UNPKG

databridge-logger

Version:

aggregate logs from all databridge clients

371 lines (294 loc) 11.9 kB
'use strict'; 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); }