CartoDB-SQL-API/lib/api/middlewares/log.js

101 lines
2.5 KiB
JavaScript
Raw Normal View History

2019-02-27 16:01:51 +08:00
'use strict';
const { stringifyForLogs } = require('../../utils/logs');
2019-02-27 16:01:51 +08:00
const MAX_SQL_LENGTH = (global.settings.logQueries && global.settings.maxQueriesLogLength) || 1024;
2019-07-31 22:07:45 +08:00
// This is used to set a hard limit to the header size
// While Node accepts headers of up to 8192 character, different libraries impose other limits
// This might break the JSON structure of the log, but avoids responses being dropped by varnish
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: {
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
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;
function prepareSQL(sql, sqlType) {
2019-02-27 19:51:01 +08:00
if (!sql || !global.settings.logQueries) {
return null;
}
if (typeof sql === 'string') {
return {
2019-02-28 18:48:51 +08:00
type: sqlType,
sql: ensureMaxQueryLength(sql)
2019-02-27 18:59:04 +08:00
};
}
if (Array.isArray(sql)) {
const lengthPerQuery = MAX_SQL_LENGTH / sql.length;
return {
2019-02-28 18:48:51 +08:00
type: sqlType,
sql: sql.map(q => ensureMaxQueryLength(q, lengthPerQuery))
2019-02-27 18:59:04 +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
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
};
if (query.onsuccess) {
subquery.onsuccess = ensureMaxQueryLength(query.onsuccess);
}
if (query.onerror) {
subquery.onerror = ensureMaxQueryLength(query.onerror);
}
return subquery;
});
return fallbackQuery;
}
function ensureMaxQueryLength(sql, length = MAX_SQL_LENGTH) {
return sql.substring(0, length);
2019-02-27 16:01:51 +08:00
}