databridge-logger
Version:
aggregate logs from all databridge clients
371 lines (294 loc) • 11.9 kB
JavaScript
;
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
var _koa = require('koa');
var _koa2 = _interopRequireDefault(_koa);
var _koaCors = require('koa-cors');
var _koaCors2 = _interopRequireDefault(_koaCors);
var _performanceNow = require('performance-now');
var _performanceNow2 = _interopRequireDefault(_performanceNow);
var _lodash = require('lodash');
var _coBody = require('co-body');
var _coBody2 = _interopRequireDefault(_coBody);
var _jsonschema = require('jsonschema');
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _https = require('https');
var _https2 = _interopRequireDefault(_https);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _koaSslify = require('koa-sslify');
var _koaSslify2 = _interopRequireDefault(_koaSslify);
var _constants = require('constants');
var _constants2 = _interopRequireDefault(_constants);
var _file = require('./backends/file');
var _file2 = _interopRequireDefault(_file);
var _tcp = require('./backends/tcp');
var _tcp2 = _interopRequireDefault(_tcp);
var _Logger = require('./Logger');
var _Logger2 = _interopRequireDefault(_Logger);
var _logSchema = require('./logSchema');
var _logSchema2 = _interopRequireDefault(_logSchema);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /**
* @author Guillaume Leclerc <guillaume.leclerc.work@gmail.com>
*
*/
var app = new _koa2.default();
var logfilename = process.env.DATABRIDGE_LOGFILE || './all.log';
var backends = [];
backends.push(new _file2.default(_path2.default.resolve(logfilename)));
var tcpHost = process.env.DATABRIDGE_LOGGER_TCP_HOST;
var tcpPort = process.env.DATABRIDGE_LOGGER_TCP_PORT;
if (tcpHost && tcpPort) {
backends.push(new _tcp2.default(tcpHost, tcpPort));
}
var logger = new _Logger2.default('databridge-logger', backends, 'main-logging-server');
var envKey = process.env.DATABRIDGE_KEY;
var envCertificate = process.env.DATABRIDGE_CERTIFICATE;
app.use((0, _koaCors2.default)());
logger.log('logger-prepare');
// Build ctx.log method
app.use(function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(ctx, next) {
var requestId;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
requestId = _uuid2.default.v4();
ctx.log = function (eventId, details, level) {
// eslint-disable-line no-param-reassign
var allDetails = (0, _lodash.merge)(details, {
requestId: requestId
});
logger.log(eventId, allDetails, level);
};
// Log the new request
ctx.log('new-request', {
ip: ctx.request.ip,
forwardedFor: ctx.headers['x-forwarded-for'],
length: ctx.request.length
});
_context.next = 5;
return next();
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
}));
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
}());
// Filter out non-post requests
app.use(function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(ctx, next) {
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (!(ctx.request.method === 'POST')) {
_context2.next = 5;
break;
}
_context2.next = 3;
return next();
case 3:
_context2.next = 8;
break;
case 5:
ctx.log('non-post-request', {
method: ctx.request.method,
url: ctx.request.url
}, 'warning');
ctx.response.status = 400;
ctx.response.body = '';
case 8:
case 'end':
return _context2.stop();
}
}
}, _callee2, undefined);
}));
return function (_x3, _x4) {
return _ref2.apply(this, arguments);
};
}());
// Mesure request duration
app.use(function () {
var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(ctx, next) {
var start, end;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
start = (0, _performanceNow2.default)();
_context3.next = 3;
return next();
case 3:
end = (0, _performanceNow2.default)();
ctx.log('end-request', {
requestDuration: end - start
});
case 5:
case 'end':
return _context3.stop();
}
}
}, _callee3, undefined);
}));
return function (_x5, _x6) {
return _ref3.apply(this, arguments);
};
}());
app.use(function () {
var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(ctx, next) {
var startParsing, endParsing;
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
startParsing = (0, _performanceNow2.default)();
_context4.prev = 1;
_context4.next = 4;
return _coBody2.default.json(ctx.request, { limit: '10kb' });
case 4:
ctx.body = _context4.sent;
_context4.next = 13;
break;
case 7:
_context4.prev = 7;
_context4.t0 = _context4['catch'](1);
ctx.log('invalid-json-request', {
method: ctx.request.method,
url: ctx.request.url
}, 'warning');
ctx.response.status = 400;
ctx.response.body = '';
return _context4.abrupt('return');
case 13:
endParsing = (0, _performanceNow2.default)();
ctx.log('body-parsed', {
parsingDuration: endParsing - startParsing
});
_context4.next = 17;
return next();
case 17:
case 'end':
return _context4.stop();
}
}
}, _callee4, undefined, [[1, 7]]);
}));
return function (_x7, _x8) {
return _ref4.apply(this, arguments);
};
}());
app.use(function () {
var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(ctx, next) {
var _validate, errors, valid;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
_validate = (0, _jsonschema.validate)(ctx.body, _logSchema2.default), errors = _validate.errors, valid = _validate.valid;
if (!valid) {
_context5.next = 6;
break;
}
_context5.next = 4;
return next();
case 4:
_context5.next = 9;
break;
case 6:
ctx.log('invalid-body', {
errors: errors
});
ctx.response.status = 400;
ctx.response.body = '';
case 9:
case 'end':
return _context5.stop();
}
}
}, _callee5, undefined);
}));
return function (_x9, _x10) {
return _ref5.apply(this, arguments);
};
}());
app.use(function () {
var _ref6 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6(ctx, next) {
var startStoring, messages, endStoring;
return regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
startStoring = (0, _performanceNow2.default)();
messages = ctx.body;
_context6.next = 4;
return Promise.all(backends.map(function (backend) {
return backend.store(messages);
}));
case 4:
endStoring = (0, _performanceNow2.default)();
ctx.log('logs-stored', {
storingDuration: endStoring - startStoring
});
_context6.next = 8;
return next();
case 8:
case 'end':
return _context6.stop();
}
}
}, _callee6, undefined);
}));
return function (_x11, _x12) {
return _ref6.apply(this, arguments);
};
}());
app.use(function () {
var _ref7 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(_ref8, next) {
var response = _ref8.response;
return regeneratorRuntime.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
response.status = 200;
response.body = '';
_context7.next = 4;
return next();
case 4:
case 'end':
return _context7.stop();
}
}
}, _callee7, undefined);
}));
return function (_x13, _x14) {
return _ref7.apply(this, arguments);
};
}());
var port = process.env.NODE_PORT || 3000;
logger.log('logger-start-listen', {
port: port
});
if (typeof envKey === 'undefined' || typeof envCertificate === 'undefined' || envKey === '' || envCertificate === '') {
app.listen(port);
} else {
logger.log('logger-in-https');
// Force SSL on all page
app.use((0, _koaSslify2.default)());
var privateKey = _fs2.default.readFileSync(_path2.default.resolve(envKey), 'utf8');
var certificate = _fs2.default.readFileSync(_path2.default.resolve(envCertificate), 'utf8');
var credentials = { key: privateKey,
cert: certificate,
secureOptions: _constants2.default.SSL_OP_NO_TLSv1_2
};
_https2.default.createServer(credentials, app.callback()).listen(port);
}