8c91b549e70ea91c01d40c6ed5ccb91d0691e798
4 const assert
= require('assert');
5 const sinon
= require('sinon'); // eslint-disable-line node/no-unpublished-require
6 const Logger
= require('../../lib/logger');
7 const http
= require('http');
9 describe('Logger', function () {
10 let config
, logger
, scope
, message
;
12 beforeEach(function () {
14 nodeId: '3c100e84-9a7f-11ec-9b4e-0025905f714a',
17 logger
= new Logger(config
);
18 Object
.keys(Logger
.nullLogger
).forEach((level
) => sinon
.stub(logger
.backend
, level
));
22 this.afterEach(function () {
26 it('logs a message', function () {
27 logger
.info(scope
, message
, { baz: 'quux' }, { foo: 1 }, 'more other');
28 assert(logger
.backend
.info
.called
);
29 assert(logger
.backend
.info
.args
[0][0].includes(message
));
32 it('stubs missing levels', function () {
33 logger
= new Logger(config
);
34 assert
.strictEqual(typeof logger
.info
, 'function');
37 it('logs BigInts', function () {
38 logger
.info(scope
, message
, { aBigInteger: BigInt(2) });
39 assert(logger
.backend
.info
.called
);
40 assert(logger
.backend
.info
.args
[0][0].includes('"2"'));
43 it('logs Errors', function () {
44 logger
.error(scope
, message
, { e: new Error('an error') });
45 assert(logger
.backend
.error
.called
);
46 assert(logger
.backend
.error
.args
[0][0].includes('an error'));
49 it('covers config settings', function () {
50 config
.logger
.ignoreBelowLevel
= 'info';
51 logger
= new Logger(config
);
52 logger
.debug(scope
, message
, {});
53 assert(logger
.backend
.debug
.notCalled
);
56 it('covers config error', function () {
57 config
.logger
.ignoreBelowLevel
= 'not a level';
59 logger
= new Logger(config
);
60 assert
.fail('expected RangeError here');
62 assert(e
instanceof RangeError
);
66 it('covers empty fields', function () {
68 assert(logger
.backend
.info
.called
);
69 assert(logger
.backend
.info
.args
[0][0].includes('[unknown]'));
72 it('sanitizes', function () {
73 logger
.dataSanitizers
.push((data
, sanitize
= true) => {
75 const credentialLength
= data
&& data
.ctx
&& data
.ctx
.parsedBody
&& data
.ctx
.parsedBody
.credential
&& data
.ctx
.parsedBody
.credential
.length
;
76 if (credentialLength
) {
79 if (unclean
&& sanitize
) {
80 data
.ctx
.parsedBody
.credential
= '*'.repeat(credentialLength
);
84 logger
.info(scope
, message
, {
91 assert(logger
.backend
.info
.called
);
92 assert(logger
.backend
.info
.args
[0][0].includes('******'));
95 it('logs http client requests', function () {
96 const incomingMessage
= new http
.IncomingMessage();
97 incomingMessage
.method
= 'GET';
98 incomingMessage
.url
= new URL('http://example.com/');
99 logger
.info(scope
, message
, { incomingMessage
});
100 assert(logger
.backend
.info
.called
);
101 assert(logger
.backend
.info
.args
[0][0].includes('GET'));
102 assert(logger
.backend
.info
.args
[0][0].includes('http://example.com/'));
105 it('logs http client requests with scrubbed auth', function () {
106 const incomingMessage
= Object
.create(http
.IncomingMessage
.prototype);
107 incomingMessage
.headers
= {
108 authorization: 'Basic eW8=',
110 logger
.info(scope
, message
, { incomingMessage
});
111 assert(logger
.backend
.info
.called
);
112 assert(logger
.backend
.info
.args
[0][0].includes('****'));
115 it('logs http server responses', function () {
116 const serverResponse
= Object
.create(http
.ServerResponse
.prototype);
117 logger
.info(scope
, message
, { serverResponse
});
118 assert(logger
.backend
.info
.args
[0][0].includes('"statusCode":200'));
121 it('follows expected level ordering', function () {
122 const levels
= Object
.keys(Logger
.nullLogger
);
123 const expected
= ['error', 'warn', 'info', 'log', 'debug'];
124 assert
.deepStrictEqual(levels
, expected
);