UNPKG

@quarks/quarks-iam

Version:

A modern authorization server built to authenticate your users and protect your APIs

129 lines (111 loc) 3.43 kB
/** * Module dependencies */ var cwd = process.cwd() var env = process.env.NODE_ENV || 'development' var path = require('path') var bunyan = require('express-bunyan-logger') var ensureWritableDirectory = require('../lib/fs-utils').ensureWritableDirectory var oidc = require('../oidc') var FN_ARGS_SPLIT = /^[^(]*\(\s*([^)]*)\)/m /** * Returns a given function's parameter list in string form. * E.g. 'req, res, next' for a middleware function. */ function getParams (fn) { return fn.toString().match(FN_ARGS_SPLIT)[1] } /** * Adds logging to Anvil by looping through the applicable Anvil modules * and injecting any function whose parameter list matches the parameter * list of the given addLogging function into the addLogging function where * it will be executed along with the embedded log statement. * * Applicable modules have an index.js which contains the module's * functions. The module's functions are iterated through shallowly, nested * functions cannot be matched against. The functions should be named * rather than anonymous to improve the logging output. * * Currently only the oidc module is applicable. */ function addLoggingAnvil (addLogging) { function addLoggingModule (module) { for (var idx in module) { var fn = module[idx] if (getParams(fn) === addLogging.params) { // wrap function with logging module[fn.name] = addLogging(fn) } } } addLoggingModule(oidc) } /** * For each log level that has been implemented, a function has been added * below containing the desired logging statement, the original function * call (either before or after as desired). This function accepts a 'fn' * param which is a function (with matching parameter list) it will wrap. */ function addDebugLogging () { var addLogging = function (fn) { return function (req, res, next) { req.log.debug(fn.name) fn(req, res, next) } } addLogging.params = 'req, res, next' addLoggingAnvil(addLogging) } function addErrorLogging () { var addLogging = function (fn) { return function (err, req, res, next) { req.log.error(err, fn.name) fn(err, req, res, next) } } addLogging.params = 'err, req, res, next' addLoggingAnvil(addLogging) } /** * Export */ module.exports = function (options) { var logger var config = { name: 'request', streams: [], level: 'info', obfuscate: [ 'body.password' ] } if (!env.match(/test/i)) { var logsPath = path.join(cwd, 'logs') ensureWritableDirectory(logsPath) if (options && options.stdout) { config.streams.push({ stream: process.stdout }) } if (options && options.file) { config.streams.push({ path: path.join(logsPath, env + '.log') }) } if (options && options.level) { config.level = options.level } switch (config.level) { case 'fatal': break case 'error': addErrorLogging() break case 'warn': addErrorLogging() break case 'info': addErrorLogging() break case 'debug': addDebugLogging() addErrorLogging() break case 'trace': addDebugLogging() addErrorLogging() break } try { config = require(path.join(cwd, 'logger')) } catch (e) { if (e.code !== 'MODULE_NOT_FOUND') { throw e } } } logger = bunyan(config) module.exports = logger return logger }