Skip to content

Commit 96687cb

Browse files
committed
close #89 by adding multi-value querystring support to logging
1 parent c2cfe6b commit 96687cb

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@ Logging can be enabled by setting the `logger` option to `true` when creating th
812812
| level | `string` | Minimum logging level to send logs for. See [Logging Levels](#logging-levels). | `info` |
813813
| levels | `object` | Key/value pairs of custom log levels and their priority. See [Custom Logging Levels](#custom-logging-levels). | |
814814
| messageKey | `string` | Sets the JSON property name of the log "message". | `msg` |
815+
| 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` |
815816
| nested | `boolean` | Enables/disables nesting of JSON logs for serializer data. See [Serializers](#serializers). | `false` |
816817
| timestamp | `boolean` or `function` | By default, timestamps will return the epoch time in milliseconds. A value of `false` disables log timestamps. A function that returns a value can be used to override the default format. | `true` |
817818
| sampling | `object` | Enables log sampling for periodic request tracing. See [Sampling](#sampling). | |

lib/logger.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ exports.config = (config,levels) => {
5353
let access = cfg.access === true ? true : cfg.access === 'never' ? 'never' : false // create access logs
5454
let detail = cfg.detail === true ? true : false // add req/res detail to all logs
5555

56+
let multiValue = cfg.multiValue === true ? true : false // return qs as multiValue
57+
5658
let defaults = {
5759
req: req => {
5860
return {
@@ -62,7 +64,8 @@ exports.config = (config,levels) => {
6264
device: req.clientType,
6365
country: req.clientCountry,
6466
version: req.version,
65-
qs: Object.keys(req.query).length > 0 ? req.query : undefined
67+
qs: multiValue ? (Object.keys(req.multiValueQuery).length > 0 ? req.multiValueQuery : undefined)
68+
: (Object.keys(req.query).length > 0 ? req.query : undefined)
6669
}
6770
},
6871
res: () => {

test/log.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const expect = require('chai').expect // Assertion library
44

55
// Init API instance
66
const api_default = require('../index')({ logger: true }) // default logger
7+
const api_multi = require('../index')({ logger: { multiValue: true } })
78
const api_customLevel = require('../index')({ version: 'v1.0', logger: { level: 'debug' } })
89
const api_disableLevel = require('../index')({ version: 'v1.0', logger: { level: 'none' } })
910
const api_customMsgKey = require('../index')({ version: 'v1.0', logger: { messageKey: 'customKey' } })
@@ -96,6 +97,16 @@ api_default.get('/', (req,res) => {
9697
res.send('done')
9798
})
9899

100+
api_multi.get('/', (req,res) => {
101+
req.log.trace('trace message')
102+
req.log.debug('debug message')
103+
req.log.info('info message')
104+
req.log.warn('warn message')
105+
req.log.error('error message')
106+
req.log.fatal('fatal message')
107+
res.send('done')
108+
})
109+
99110
api_default.get('/test', (req,res) => {
100111
res.send('done')
101112
})
@@ -208,7 +219,7 @@ describe('Logging Tests:', function() {
208219

209220
it('Default options (logging: true)', async function() {
210221
console.log = logger
211-
let _event = Object.assign({},event,{ path: '/', queryStringParameters: { test: true } })
222+
let _event = Object.assign({},event,{ path: '/', multiValueQueryStringParameters: { test: ['val1'] } })
212223
let result = await new Promise(r => api_default.run(_event,context,(e,res) => { r(res) }))
213224
console.log = consoleLog
214225

@@ -238,10 +249,47 @@ describe('Logging Tests:', function() {
238249
expect(_log[4]).to.have.property('ua')
239250
expect(_log[4]).to.have.property('version')
240251
expect(_log[4]).to.have.property('qs')
252+
expect(_log[4].qs.test).to.be.a('string')
241253
expect(_log[4]).to.have.property('device')
242254
expect(_log[4]).to.have.property('country')
243255
}) // end it
244256

257+
it('Multi-value support', async function() {
258+
console.log = logger
259+
let _event = Object.assign({},event,{ path: '/', multiValueQueryStringParameters: { test: ['val1'] } })
260+
let result = await new Promise(r => api_multi.run(_event,context,(e,res) => { r(res) }))
261+
console.log = consoleLog
262+
263+
expect(result).to.deep.equal({
264+
multiValueHeaders: { 'content-type': ['application/json'] },
265+
statusCode: 200,
266+
body: 'done',
267+
isBase64Encoded: false
268+
})
269+
expect(_log).to.have.length(5)
270+
expect(_log[0].level).to.equal('info')
271+
expect(_log[4].level).to.equal('access')
272+
// standard log
273+
expect(_log[0]).to.have.property('time')
274+
expect(_log[0]).to.have.property('id')
275+
expect(_log[0]).to.have.property('route')
276+
expect(_log[0]).to.have.property('msg')
277+
expect(_log[0]).to.have.property('timer')
278+
expect(_log[0]).to.have.property('remaining')
279+
expect(_log[0]).to.have.property('function')
280+
expect(_log[0]).to.have.property('memory')
281+
// access log
282+
expect(_log[4]).to.have.property('coldStart')
283+
expect(_log[4]).to.have.property('statusCode')
284+
expect(_log[4]).to.have.property('path')
285+
expect(_log[4]).to.have.property('ip')
286+
expect(_log[4]).to.have.property('ua')
287+
expect(_log[4]).to.have.property('version')
288+
expect(_log[4]).to.have.property('qs')
289+
expect(_log[4].qs.test).to.be.a('array')
290+
expect(_log[4]).to.have.property('device')
291+
expect(_log[4]).to.have.property('country')
292+
}) // end it
245293

246294
it('Default options (no logs in routes)', async function() {
247295
console.log = logger

0 commit comments

Comments
 (0)