diff --git a/index.js b/index.js index 04b87f2..c973663 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,8 @@ const defaults = { requiredTags: ['handler'], excludeStatus: [], includeId: false, - tags: ['detailed-response'] + tags: ['detailed-response'], + verbose: false }; const contains = (arr1, arr2) => arr1.some(item => arr2.includes(item)); @@ -65,13 +66,14 @@ const register = (server, options) => { if (request.route.settings.plugins['hapi-log-response'] && request.route.settings.plugins['hapi-log-response'].enabled === false) { return; } - if (event.error && event.error.output) { + if (options.verbose || (event.error && event.error.output)) { // ignore if required tags were specified, but none of them match any of the event tags: const tagArray = Array.isArray(event.tags) ? event.tags : Object.keys(event.tags); - if (options.requiredTags.length > 0 && !contains(options.requiredTags, tagArray)) { + if (!options.verbose && options.requiredTags.length > 0 && !contains(options.requiredTags, tagArray)) { return; } - const statusCode = event.error.output.statusCode; + // the only request events that have no error are unauthorized: + const statusCode = event.error ? event.error.output.statusCode : 401; // skip 404's, they are covered by the response handler: if (statusCode === 404) { return; @@ -95,6 +97,10 @@ const register = (server, options) => { output: event.error.output }; } + // in verbose mode we might want to log the original tags: + if (options.verbose) { + data.eventTags = eventTags; + } server.log(tags, data); } }); diff --git a/test/test.response.js b/test/test.response.js index 044ffb8..45f5c2d 100644 --- a/test/test.response.js +++ b/test/test.response.js @@ -513,3 +513,41 @@ test('options.requiredTags just logs everything if set to empty', async (t) => { await server.stop(); t.end(); }); + +test('options.verbose logs all request events', async (t) => { + const server = new Hapi.Server({ + debug: { + request: ['error'] + }, + port: 8080 + }); + await server.register([ + { plugin: require('../'), + options: { + verbose: true + } + } + ]); + server.route({ + method: 'GET', + path: '/error', + handler(request, h) { + // simulate a 'no authentication scheme' event + request.auth.isAuthenticated = false; + request.auth.credentials = null; + request.error = boom.unauthorized(); + request._log(['auth', 'unauthenticated']); + return h.response('not authenticated').code(401); + } + }); + server.events.on('log', async (event, tags) => { + t.ok(tags['user-error']); + t.ok(event.data.eventTags.auth, 'verbose mode includes original tags'); + t.ok(event.data.eventTags.unauthenticated, 'verbose mode includes original tags'); + await server.stop(); + t.end(); + }); + await server.start(); + await server.inject({ url: '/error' }); + await wait(1000); +});