zater-error-handler
Version:
Module for error handler zater
111 lines (98 loc) • 13.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Logger = function () {
function Logger(winston, expressWinston, slackWinston, newrelicWinston, options) {
_classCallCheck(this, Logger);
this.slackConfig = slackWinston;
this.options = options;
var loggedAsFormat = '( req.headers[\'userid\'] ? req.headers[\'userid\'] : "not_logged")';
var clientFormat = '(req.headers[\'x-forwarded-for\'] ? req.headers[\'x-forwarded-for\'] : req.ip)';
var tokenFormat = '(req.headers[\'access-token\'] ? req.headers[\'access-token\'] : "not_logged")';
var msgFormat = ' {{" ###### LOG BEGIN ###### "}}';
msgFormat += '\n {{"logged_as: " + ' + loggedAsFormat + ' }}';
msgFormat += '\n {{"client_ip: " + ' + clientFormat + ' }} ';
msgFormat += '\n {{"request_url: " + req.url}} ';
msgFormat += '\n {{"method: " + req.method}} ';
msgFormat += '\n {{"response_time: " + res.responseTime + "ms" }}';
msgFormat += '\n {{"response_message: " + res.statusMessage}} ';
msgFormat += '\n {{"status_code: " + res.statusCode}} ';
msgFormat += '\n {{"token: " + ' + tokenFormat + '}}';
msgFormat += '\n {{"request: " + JSON.stringify(req.body)}}';
msgFormat += '\n {{"node_env: " + process.env.NODE_ENV }}';
msgFormat += '\n {{"###### LOG END ###### "}}';
var optionsWinston = {
winstonInstance: winston,
meta: false,
colorize: true,
msg: msgFormat,
ignoredRoutes: ['/explorer'],
requestWhitelist: ['user', 'headers', 'method', 'httpVersion', 'url', 'query', 'ip', 'body'],
responseWhitelist: ['user', 'headers', 'method', 'httpVersion', 'url', 'query', 'ip', 'body', 'statusCode', 'responseTime'],
bodyBlacklist: ['password', 'passwordConfirm', 'newPassword', 'newPasswordConfirm', 'doc', 'image', 'file'],
statusLevels: {
success: 'info',
warn: 'warn',
error: 'error',
debug: 'debug',
slack: 'slack'
},
handleRequestOnlyOnce: true,
preferHandleErrorRequest: true
};
var errorOptions = Object.assign({}, optionsWinston, {
meta: true,
skip: function skip(err) {
if (err.name === 'UnauthorizedError') return true;
var ignoreErrors = ['TokenExpiredError'];
return ignoreErrors.indexOf(err.name) >= 0;
}
});
winston.exitOnError = false;
this.winston = winston;
this.expressWinston = expressWinston;
this.errorOptions = errorOptions;
this.optionsWinston = optionsWinston;
this.newrelicWinston = newrelicWinston;
}
_createClass(Logger, [{
key: 'logger',
value: function logger() {
this.winston.addColors({ slack: 'magenta' });
this.winston.setLevels({ error: 0, slack: 1, warn: 2, info: 3, verbose: 4, debug: 5 });
this.winston.add(this.winston.transports.Console, {
handleExceptions: true,
humanReadableUnhandledException: true,
meta: false,
json: false,
colorize: true,
timestamp: true,
level: 'debug',
name: this.options.name + new Date(),
instance: true
});
this.options.slack.name = this.options.slack.name + new Date();
this.winston.add(this.slackConfig, this.options.slack);
return this.winston;
}
}, {
key: 'middleware',
value: function middleware() {
this.winston.add(this.newrelicWinston);
return this.expressWinston.logger(this.optionsWinston);
}
}, {
key: 'errorMiddleware',
value: function errorMiddleware() {
return this.expressWinston.errorLogger(this.errorOptions);
}
}]);
return Logger;
}();
exports.default = function (winston, expressWinston, slackWinston, newrelicWinston, options) {
return new Logger(winston, expressWinston, slackWinston, newrelicWinston, options);
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Mb2dnZXIuanMiXSwibmFtZXMiOlsiTG9nZ2VyIiwid2luc3RvbiIsImV4cHJlc3NXaW5zdG9uIiwic2xhY2tXaW5zdG9uIiwibmV3cmVsaWNXaW5zdG9uIiwib3B0aW9ucyIsInNsYWNrQ29uZmlnIiwibG9nZ2VkQXNGb3JtYXQiLCJjbGllbnRGb3JtYXQiLCJ0b2tlbkZvcm1hdCIsIm1zZ0Zvcm1hdCIsIm9wdGlvbnNXaW5zdG9uIiwid2luc3Rvbkluc3RhbmNlIiwibWV0YSIsImNvbG9yaXplIiwibXNnIiwiaWdub3JlZFJvdXRlcyIsInJlcXVlc3RXaGl0ZWxpc3QiLCJyZXNwb25zZVdoaXRlbGlzdCIsImJvZHlCbGFja2xpc3QiLCJzdGF0dXNMZXZlbHMiLCJzdWNjZXNzIiwid2FybiIsImVycm9yIiwiZGVidWciLCJzbGFjayIsImhhbmRsZVJlcXVlc3RPbmx5T25jZSIsInByZWZlckhhbmRsZUVycm9yUmVxdWVzdCIsImVycm9yT3B0aW9ucyIsIk9iamVjdCIsImFzc2lnbiIsInNraXAiLCJlcnIiLCJuYW1lIiwiaWdub3JlRXJyb3JzIiwiaW5kZXhPZiIsImV4aXRPbkVycm9yIiwiYWRkQ29sb3JzIiwic2V0TGV2ZWxzIiwiaW5mbyIsInZlcmJvc2UiLCJhZGQiLCJ0cmFuc3BvcnRzIiwiQ29uc29sZSIsImhhbmRsZUV4Y2VwdGlvbnMiLCJodW1hblJlYWRhYmxlVW5oYW5kbGVkRXhjZXB0aW9uIiwianNvbiIsInRpbWVzdGFtcCIsImxldmVsIiwiRGF0ZSIsImluc3RhbmNlIiwibG9nZ2VyIiwiZXJyb3JMb2dnZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7SUFBTUEsTTtBQUNMLGlCQUFZQyxPQUFaLEVBQXFCQyxjQUFyQixFQUFxQ0MsWUFBckMsRUFBbURDLGVBQW5ELEVBQW9FQyxPQUFwRSxFQUE2RTtBQUFBOztBQUM1RSxPQUFLQyxXQUFMLEdBQW1CSCxZQUFuQjtBQUNBLE9BQUtFLE9BQUwsR0FBZUEsT0FBZjs7QUFF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SUFBSWdCLElBQUosRUFSdUI7QUFTakRDLGNBQVU7QUFUdUMsSUFBbEQ7O0FBWUEsUUFBSzdDLE9BQUwsQ0FBYW9CLEtBQWIsQ0FBbUJRLElBQW5CLEdBQTBCLEtBQUs1QixPQUFMLENBQWFvQixLQUFiLENBQW1CUSxJQUFuQixHQUEwQixJQUFJZ0IsSUFBSixFQUFwRDtBQUNBLFFBQUtoRCxPQUFMLENBQWF3QyxHQUFiLENBQWlCLEtBQUtuQyxXQUF0QixFQUFtQyxLQUFLRCxPQUFMLENBQWFvQixLQUFoRDtBQUNBLFVBQU8sS0FBS3hCLE9BQVo7QUFDQTs7OytCQUNZO0FBQ1osUUFBS0EsT0FBTCxDQUFhd0MsR0FBYixDQUFpQixLQUFLckMsZUFBdEI7QUFDQSxVQUFPLEtBQUtGLGNBQUwsQ0FBb0JpRCxNQUFwQixDQUEyQixLQUFLeEMsY0FBaEMsQ0FBUDtBQUNBOzs7b0NBQ2lCO0FBQ2pCLFVBQU8sS0FBS1QsY0FBTCxDQUFvQmtELFdBQXBCLENBQWdDLEtBQUt4QixZQUFyQyxDQUFQO0FBQ0E7Ozs7OztrQkFHYSxVQUFDM0IsT0FBRCxFQUFVQyxjQUFWLEVBQTBCQyxZQUExQixFQUF3Q0MsZUFBeEMsRUFBeURDLE9BQXpEO0FBQUEsUUFBcUUsSUFBSUwsTUFBSixDQUFXQyxPQUFYLEVBQW9CQyxjQUFwQixFQUFvQ0MsWUFBcEMsRUFBa0RDLGVBQWxELEVBQW1FQyxPQUFuRSxDQUFyRTtBQUFBLEMiLCJmaWxlIjoiTG9nZ2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgTG9nZ2VyIHtcblx0Y29uc3RydWN0b3Iod2luc3RvbiwgZXhwcmVzc1dpbnN0b24sIHNsYWNrV2luc3RvbiwgbmV3cmVsaWNXaW5zdG9uLCBvcHRpb25zKSB7XG5cdFx0dGhpcy5zbGFja0NvbmZpZyA9IHNsYWNrV2luc3Rvbjtcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG5cdFx0Y29uc3QgbG9nZ2VkQXNGb3JtYXQgPSAnKCByZXEuaGVhZGVyc1tcXCd1c2VyaWRcXCddID8gcmVxLmhlYWRlcnNbXFwndXNlcmlkXFwnXSA6IFwibm90X2xvZ2dlZFwiKSc7XG5cdFx0Y29uc3QgY2xpZW50Rm9ybWF0ID0gJyhyZXEuaGVhZGVyc1tcXCd4LWZvcndhcmRlZC1mb3JcXCddID8gcmVxLmhlYWRlcnNbXFwneC1mb3J3YXJkZWQtZm9yXFwnXSAgOiByZXEuaXApJztcblx0XHRjb25zdCB0b2tlbkZvcm1hdCA9ICcocmVxLmhlYWRlcnNbXFwnYWNjZXNzLXRva2VuXFwnXSA/IHJlcS5oZWFkZXJzW1xcJ2FjY2Vzcy10b2tlblxcJ10gOiBcIm5vdF9sb2dnZWRcIiknO1xuXHRcdGxldCBtc2dGb3JtYXQgPSBgIHt7XCIgIyMjIyMjIExPRyBCRUdJTiAjIyMjIyMgXCJ9fWA7XG5cdFx0bXNnRm9ybWF0ICs9IGBcXG4ge3tcImxvZ2dlZF9hczogXCIgKyAke2xvZ2dlZEFzRm9ybWF0fSB9fWA7XG5cdFx0bXNnRm9ybWF0ICs9IGBcXG4ge3tcImNsaWVudF9pcDogXCIgKyAke2NsaWVudEZvcm1hdH0gfX0gYDtcblx0XHRtc2dGb3JtYXQgKz0gJ1xcbiB7e1wicmVxdWVzdF91cmw6IFwiICsgcmVxLnVybH19ICc7XG5cdFx0bXNnRm9ybWF0ICs9ICdcXG4ge3tcIm1ldGhvZDogXCIgKyByZXEubWV0aG9kfX0gJztcblx0XHRtc2dGb3JtYXQgKz0gJ1xcbiB7e1wicmVzcG9uc2VfdGltZTogXCIgKyByZXMucmVzcG9uc2VUaW1lICsgXCJtc1wiIH19Jztcblx0XHRtc2dGb3JtYXQgKz0gJ1xcbiB7e1wicmVzcG9uc2VfbWVzc2FnZTogXCIgKyByZXMuc3RhdHVzTWVzc2FnZX19ICc7XG5cdFx0bXNnRm9ybWF0ICs9ICdcXG4ge3tcInN0YXR1c19jb2RlOiBcIiArIHJlcy5zdGF0dXNDb2RlfX0gJztcblx0XHRtc2dGb3JtYXQgKz0gYFxcbiB7e1widG9rZW46IFwiICsgJHt0b2tlbkZvcm1hdH19fWA7XG5cdFx0bXNnRm9ybWF0ICs9ICdcXG4ge3tcInJlcXVlc3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkocmVxLmJvZHkpfX0nO1xuXHRcdG1zZ0Zvcm1hdCArPSAnXFxuIHt7XCJub2RlX2VudjogXCIgKyBwcm9jZXNzLmVudi5OT0RFX0VOViB9fSc7XG5cdFx0bXNnRm9ybWF0ICs9IGBcXG4ge3tcIiMjIyMjIyBMT0cgRU5EICMjIyMjIyBcIn19YDtcdFx0XG5cblx0XHRjb25zdCBvcHRpb25zV2luc3RvbiA9IHtcblx0XHRcdHdpbnN0b25JbnN0YW5jZTogd2luc3Rvbixcblx0XHRcdG1ldGE6IGZhbHNlLFxuXHRcdFx0Y29sb3JpemU6IHRydWUsXG5cdFx0XHRtc2c6IG1zZ0Zvcm1hdCxcblx0XHRcdGlnbm9yZWRSb3V0ZXM6IFsnL2V4cGxvcmVyJ10sXG5cdFx0XHRyZXF1ZXN0V2hpdGVsaXN0OiBbJ3VzZXInLCAnaGVhZGVycycsICdtZXRob2QnLCAnaHR0cFZlcnNpb24nLCAndXJsJywgJ3F1ZXJ5JywgJ2lwJywgJ2JvZHknXSxcblx0XHRcdHJlc3BvbnNlV2hpdGVsaXN0OiBbJ3VzZXInLCAnaGVhZGVycycsICdtZXRob2QnLCAnaHR0cFZlcnNpb24nLCAndXJsJywgJ3F1ZXJ5JywgJ2lwJywgJ2JvZHknLCAnc3RhdHVzQ29kZScsICdyZXNwb25zZVRpbWUnXSxcblx0XHRcdGJvZHlCbGFja2xpc3Q6IFsncGFzc3dvcmQnLCAncGFzc3dvcmRDb25maXJtJywgJ25ld1Bhc3N3b3JkJywgJ25ld1Bhc3N3b3JkQ29uZmlybScsICdkb2MnLCAnaW1hZ2UnLCAnZmlsZSddLFx0XHRcdFxuXHRcdFx0c3RhdHVzTGV2ZWxzOiB7XG5cdFx0XHRcdHN1Y2Nlc3M6ICdpbmZvJyxcblx0XHRcdFx0d2FybjogJ3dhcm4nLFxuXHRcdFx0XHRlcnJvcjogJ2Vycm9yJyxcblx0XHRcdFx0ZGVidWc6ICdkZWJ1ZycsXG5cdFx0XHRcdHNsYWNrOiAnc2xhY2snXG5cdFx0XHR9LFxuXHRcdFx0aGFuZGxlUmVxdWVzdE9ubHlPbmNlOiB0cnVlLFxuXHRcdFx0cHJlZmVySGFuZGxlRXJyb3JSZXF1ZXN0OiB0cnVlLFxuXHRcdH07XG5cblx0XHRjb25zdCBlcnJvck9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zV2luc3Rvbiwge1xuXHRcdFx0bWV0YTogdHJ1ZSxcblx0XHRcdHNraXA6IChlcnIpID0+IHtcdFx0XHRcdFxuXHRcdFx0XHRpZiAoZXJyLm5hbWUgPT09ICdVbmF1dGhvcml6ZWRFcnJvcicpIHJldHVybiB0cnVlO1xuXG5cdFx0XHRcdGNvbnN0IGlnbm9yZUVycm9ycyA9IFsnVG9rZW5FeHBpcmVkRXJyb3InXTtcblx0XHRcdFx0cmV0dXJuIGlnbm9yZUVycm9ycy5pbmRleE9mKGVyci5uYW1lKSA+PSAwO1xuXHRcdFx0fSxcblx0XHR9KTtcblx0XHR3aW5zdG9uLmV4aXRPbkVycm9yID0gZmFsc2U7XG5cdFx0dGhpcy53aW5zdG9uID0gd2luc3Rvbjtcblx0XHR0aGlzLmV4cHJlc3NXaW5zdG9uID0gZXhwcmVzc1dpbnN0b247XG5cdFx0dGhpcy5lcnJvck9wdGlvbnMgPSBlcnJvck9wdGlvbnM7XG5cdFx0dGhpcy5vcHRpb25zV2luc3RvbiA9IG9wdGlvbnNXaW5zdG9uO1xuXHRcdHRoaXMubmV3cmVsaWNXaW5zdG9uID0gbmV3cmVsaWNXaW5zdG9uO1xuXHR9XG5cblx0bG9nZ2VyKCkge1xuXHRcdHRoaXMud2luc3Rvbi5hZGRDb2xvcnMoeyBzbGFjazogJ21hZ2VudGEnIH0pO1xuXHRcdHRoaXMud2luc3Rvbi5zZXRMZXZlbHMoeyBlcnJvcjogMCwgc2xhY2s6IDEsIHdhcm46IDIsIGluZm86IDMsIHZlcmJvc2U6IDQsIGRlYnVnOiA1IH0pO1xuXHRcdHRoaXMud2luc3Rvbi5hZGQodGhpcy53aW5zdG9uLnRyYW5zcG9ydHMuQ29uc29sZSwge1xuXHRcdFx0aGFuZGxlRXhjZXB0aW9uczogdHJ1ZSxcblx0XHRcdGh1bWFuUmVhZGFibGVVbmhhbmRsZWRFeGNlcHRpb246IHRydWUsXG5cdFx0XHRtZXRhOiBmYWxzZSxcblx0XHRcdGpzb246IGZhbHNlLFxuXHRcdFx0Y29sb3JpemU6IHRydWUsXG5cdFx0XHR0aW1lc3RhbXA6IHRydWUsXG5cdFx0XHRsZXZlbDogJ2RlYnVnJyxcblx0XHRcdG5hbWU6IHRoaXMub3B0aW9ucy5uYW1lICsgbmV3IERhdGUoKSxcblx0XHRcdGluc3RhbmNlOiB0cnVlXG5cdFx0fSk7XG5cblx0XHR0aGlzLm9wdGlvbnMuc2xhY2submFtZSA9IHRoaXMub3B0aW9ucy5zbGFjay5uYW1lICsgbmV3IERhdGUoKTtcblx0XHR0aGlzLndpbnN0b24uYWRkKHRoaXMuc2xhY2tDb25maWcsIHRoaXMub3B0aW9ucy5zbGFjayk7XG5cdFx0cmV0dXJuIHRoaXMud2luc3Rvbjtcblx0fVxuXHRtaWRkbGV3YXJlKCkge1xuXHRcdHRoaXMud2luc3Rvbi5hZGQodGhpcy5uZXdyZWxpY1dpbnN0b24pO1xuXHRcdHJldHVybiB0aGlzLmV4cHJlc3NXaW5zdG9uLmxvZ2dlcih0aGlzLm9wdGlvbnNXaW5zdG9uKTtcblx0fVxuXHRlcnJvck1pZGRsZXdhcmUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXhwcmVzc1dpbnN0b24uZXJyb3JMb2dnZXIodGhpcy5lcnJvck9wdGlvbnMpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0ICh3aW5zdG9uLCBleHByZXNzV2luc3Rvbiwgc2xhY2tXaW5zdG9uLCBuZXdyZWxpY1dpbnN0b24sIG9wdGlvbnMpID0+IG5ldyBMb2dnZXIod2luc3RvbiwgZXhwcmVzc1dpbnN0b24sIHNsYWNrV2luc3RvbiwgbmV3cmVsaWNXaW5zdG9uLCBvcHRpb25zKTtcbiJdfQ==