From ec512dd10ddbfa4b1455d0894141755dd25f940c Mon Sep 17 00:00:00 2001 From: Jeremy Daly Date: Thu, 1 Aug 2019 16:18:25 -0400 Subject: [PATCH] add custom logger per #115 --- README.md | 1 + index.js | 4 ++-- lib/logger.js | 4 ++++ test/log.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ba56ea2..8ed800c 100644 --- a/README.md +++ b/README.md @@ -859,6 +859,7 @@ Logging can be enabled by setting the `logger` option to `true` when creating th | detail | `boolean` | Enables/disables adding `REQUEST` and `RESPONSE` data to all log entries. | `false` | | level | `string` | Minimum logging level to send logs for. See [Logging Levels](#logging-levels). | `info` | | levels | `object` | Key/value pairs of custom log levels and their priority. See [Custom Logging Levels](#custom-logging-levels). | | +| log | `function` | Custom function for overriding standard `console.log`. | `console.log` | | messageKey | `string` | Sets the JSON property name of the log "message". | `msg` | | multiValue | `boolean` | Enables multi-value support for querystrings. If enabled, the `qs` parameter will return all values as `array`s and will include multiple values if they exist. | `false` | | nested | `boolean` | Enables/disables nesting of JSON logs for serializer data. See [Serializers](#serializers). | `false` | diff --git a/index.js b/index.js index 97fee06..52e0e40 100644 --- a/index.js +++ b/index.js @@ -311,7 +311,7 @@ class API { // Output logs response._request._logs.forEach(log => { - console.log(JSON.stringify(this._logger.detail ? // eslint-disable-line no-console + this._logger.logger(JSON.stringify(this._logger.detail ? // eslint-disable-line no-console this._logger.format(log,response._request,response) : log)) }) @@ -321,7 +321,7 @@ class API { this._logger.log('access',undefined,response._request,response._request.context), { statusCode: res.statusCode, coldStart: response._request.coldStart, count: response._request.requestCount } ) - console.log(JSON.stringify(this._logger.format(access,response._request,response))) // eslint-disable-line no-console + this._logger.logger(JSON.stringify(this._logger.format(access,response._request,response))) // eslint-disable-line no-console } // Reset global error code diff --git a/lib/logger.js b/lib/logger.js index 344cbf9..01c9eb0 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -90,6 +90,9 @@ exports.config = (config,levels) => { custom: cfg.serializers && typeof cfg.serializers.custom === 'function' ? cfg.serializers.custom : () => {} } + // Overridable logging function + let logger = cfg.log && typeof cfg.log === 'function' ? cfg.log : (...a) => console.log(...a) + // Main logging function let log = (level,msg,req,context,custom) => { @@ -134,6 +137,7 @@ exports.config = (config,levels) => { return { level, stack, + logger, log, format, access, diff --git a/test/log.js b/test/log.js index f1588fd..c4e48e7 100644 --- a/test/log.js +++ b/test/log.js @@ -17,6 +17,9 @@ const api_noAccessLogs = require('../index')({ version: 'v1.0', logger: { access const api_nested = require('../index')({ version: 'v1.0', logger: { nested: true, access: true } }) const api_withDetail = require('../index')({ version: 'v1.0', logger: { detail: true } }) const api_showStackTrace = require('../index')({ version: 'v1.0', logger: { stack: true } }) +const api_customLogger = require('../index')({ version: 'v1.0', logger: { + log: (x) => console.log(JSON.stringify(Object.assign(JSON.parse(x),{ LOGGER: true }))) +} }) const api_customLevels = require('../index')({ version: 'v1.0', logger: { levels: { testDebug: 35, @@ -186,6 +189,11 @@ api_customSerializers.get('/', (req,res) => { res.send('done') }) +api_customLogger.get('/', (req,res) => { + req.log.info('info message','second param') + res.send('done') +}) + api_default.get('/array', (req,res) => { req.log.info('info message',['val1','val2','val3']) res.send('done') @@ -1005,4 +1013,49 @@ describe('Logging Tests:', function() { }) // end it + it('Custom Logger', async function() { + console.log = logger + let _event = Object.assign({},event,{ path: '/' }) + let result = await new Promise(r => api_customLogger.run(_event,context,(e,res) => { r(res) })) + console.log = consoleLog + + expect(result).to.deep.equal({ + multiValueHeaders: { 'content-type': ['application/json'] }, + statusCode: 200, + body: 'done', + isBase64Encoded: false + }) + + expect(_log).to.have.length(2) + expect(_log[0].level).to.equal('info') + expect(_log[1].level).to.equal('access') + // standard log + expect(_log[0]).to.have.property('LOGGER') + expect(_log[0]).to.have.property('time') + expect(_log[0]).to.have.property('id') + expect(_log[0]).to.have.property('route') + expect(_log[0]).to.have.property('msg') + expect(_log[0]).to.have.property('timer') + expect(_log[0]).to.have.property('remaining') + expect(_log[0]).to.have.property('function') + expect(_log[0]).to.have.property('memory') + expect(_log[0]).to.have.property('int') + + expect(_log[1]).to.have.property('LOGGER') + expect(_log[1]).to.have.property('time') + expect(_log[1]).to.have.property('id') + expect(_log[1]).to.have.property('route') + expect(_log[1]).to.have.property('timer') + expect(_log[1]).to.have.property('remaining') + expect(_log[1]).to.have.property('function') + expect(_log[1]).to.have.property('memory') + expect(_log[1]).to.have.property('coldStart') + expect(_log[1]).to.have.property('path') + expect(_log[1]).to.have.property('ip') + expect(_log[1]).to.have.property('ua') + expect(_log[1]).to.have.property('version') + expect(_log[1]).to.have.property('device') + expect(_log[1]).to.have.property('country') + }) // end it + })