2019-02-27 16:01:51 +08:00
|
|
|
'use strict';
|
|
|
|
|
2019-02-27 17:40:49 +08:00
|
|
|
const { stringifyForLogs } = require('../utils/logs');
|
2019-02-27 16:01:51 +08:00
|
|
|
|
2019-02-28 23:42:24 +08:00
|
|
|
const MAX_SQL_LENGTH = (global.settings.logQueries && global.settings.maxQueriesLogLength) || 1024;
|
2019-07-31 21:59:06 +08:00
|
|
|
|
|
|
|
// This is used to set a hard limit in the header size
|
|
|
|
// While Node accepts headers of up to 8192 character, but different libraries impose other limits
|
|
|
|
// This might break the JSON structure of the log
|
|
|
|
const HEADER_HARD_LIMIT = 4096;
|
|
|
|
|
2019-02-28 18:48:51 +08:00
|
|
|
const TYPES = {
|
|
|
|
QUERY: 'query',
|
|
|
|
JOB: 'job'
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = function log(sqlType = TYPES.QUERY) {
|
2019-02-27 16:01:51 +08:00
|
|
|
return function logMiddleware(req, res, next) {
|
|
|
|
const logObj = {
|
|
|
|
request: {
|
2019-07-26 22:06:53 +08:00
|
|
|
sql: prepareSQL(res.locals.params.sql, sqlType)
|
2019-02-27 16:01:51 +08:00
|
|
|
}
|
2019-02-27 18:59:04 +08:00
|
|
|
};
|
2019-02-27 16:01:51 +08:00
|
|
|
|
2019-07-31 21:59:06 +08:00
|
|
|
res.set('X-SQLAPI-Log', stringifyForLogs(logObj).substring(0, HEADER_HARD_LIMIT));
|
2019-02-27 16:01:51 +08:00
|
|
|
|
|
|
|
return next();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-02-28 18:48:51 +08:00
|
|
|
module.exports.TYPES = TYPES;
|
|
|
|
|
2019-02-28 23:42:24 +08:00
|
|
|
function prepareSQL(sql, sqlType) {
|
2019-02-27 19:51:01 +08:00
|
|
|
if (!sql || !global.settings.logQueries) {
|
2019-02-27 17:07:56 +08:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-02-28 23:42:24 +08:00
|
|
|
|
2019-02-27 17:07:56 +08:00
|
|
|
if (typeof sql === 'string') {
|
|
|
|
return {
|
2019-02-28 18:48:51 +08:00
|
|
|
type: sqlType,
|
2019-02-28 23:42:24 +08:00
|
|
|
sql: ensureMaxQueryLength(sql)
|
2019-02-27 18:59:04 +08:00
|
|
|
};
|
2019-02-27 17:07:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(sql)) {
|
2019-07-31 21:59:06 +08:00
|
|
|
const lengthPerQuery = MAX_SQL_LENGTH / sql.length;
|
2019-02-27 17:07:56 +08:00
|
|
|
return {
|
2019-02-28 18:48:51 +08:00
|
|
|
type: sqlType,
|
2019-07-31 21:59:06 +08:00
|
|
|
sql: sql.map(q => ensureMaxQueryLength(q, lengthPerQuery))
|
2019-02-27 18:59:04 +08:00
|
|
|
};
|
2019-02-27 17:07:56 +08:00
|
|
|
}
|
|
|
|
|
2019-02-28 23:42:24 +08:00
|
|
|
if (sql.query && Array.isArray(sql.query)) {
|
|
|
|
return {
|
|
|
|
type: sqlType,
|
|
|
|
sql: prepareBatchFallbackQuery(sql)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Process a Batch API fallback query controlling the queries length
|
|
|
|
* We need to create a new object avoiding original modifications
|
|
|
|
*
|
|
|
|
* @param {Object} sql
|
|
|
|
*/
|
|
|
|
function prepareBatchFallbackQuery(sql) {
|
|
|
|
const fallbackQuery = {};
|
2019-02-28 23:57:23 +08:00
|
|
|
|
2019-02-28 23:42:24 +08:00
|
|
|
if (sql.onsuccess) {
|
|
|
|
fallbackQuery.onsuccess = ensureMaxQueryLength(sql.onsuccess);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sql.onerror) {
|
|
|
|
fallbackQuery.onerror = ensureMaxQueryLength(sql.onerror);
|
|
|
|
}
|
|
|
|
|
|
|
|
fallbackQuery.query = sql.query.map(query => {
|
|
|
|
const subquery = {
|
|
|
|
query: ensureMaxQueryLength(query.query)
|
2019-02-28 23:57:23 +08:00
|
|
|
};
|
2019-02-28 23:42:24 +08:00
|
|
|
|
|
|
|
if (query.onsuccess) {
|
|
|
|
subquery.onsuccess = ensureMaxQueryLength(query.onsuccess);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (query.onerror) {
|
|
|
|
subquery.onerror = ensureMaxQueryLength(query.onerror);
|
|
|
|
}
|
|
|
|
|
|
|
|
return subquery;
|
|
|
|
});
|
|
|
|
|
|
|
|
return fallbackQuery;
|
|
|
|
}
|
|
|
|
|
2019-07-31 21:59:06 +08:00
|
|
|
function ensureMaxQueryLength(sql, length = MAX_SQL_LENGTH) {
|
|
|
|
return sql.substring(0, length);
|
2019-02-27 16:01:51 +08:00
|
|
|
}
|