chore: rework to use the message symbol instead
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -72,7 +72,6 @@
|
||||
"fs-extra": "^11.2.0",
|
||||
"helmet": "^6.0.0",
|
||||
"jose": "^5.0.0",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"knex": "^3.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"logform": "^2.3.2",
|
||||
@@ -84,6 +83,7 @@
|
||||
"path-to-regexp": "^6.2.1",
|
||||
"selfsigned": "^2.0.0",
|
||||
"stoppable": "^1.1.0",
|
||||
"triple-beam": "^1.4.1",
|
||||
"uuid": "^9.0.0",
|
||||
"winston": "^3.2.1",
|
||||
"winston-transport": "^4.5.0"
|
||||
@@ -94,7 +94,6 @@
|
||||
"@types/compression": "^1.7.0",
|
||||
"@types/fs-extra": "^11.0.0",
|
||||
"@types/http-errors": "^2.0.0",
|
||||
"@types/json-stringify-safe": "^5.0.3",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/morgan": "^1.9.0",
|
||||
"@types/node-forge": "^1.3.0",
|
||||
|
||||
@@ -14,12 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TransformableInfo } from 'logform';
|
||||
import { format } from 'logform';
|
||||
import { WinstonLogger } from './WinstonLogger';
|
||||
|
||||
function msg(info: TransformableInfo): TransformableInfo {
|
||||
return { message: info.message, level: info.level, stack: info.stack };
|
||||
}
|
||||
import Transport from 'winston-transport';
|
||||
import { MESSAGE } from 'triple-beam';
|
||||
|
||||
describe('WinstonLogger', () => {
|
||||
it('creates a winston logger instance with default options', () => {
|
||||
@@ -33,57 +31,66 @@ describe('WinstonLogger', () => {
|
||||
expect(childLogger).toBeInstanceOf(WinstonLogger);
|
||||
});
|
||||
|
||||
it('redacter should redact and escape regex', () => {
|
||||
const redacter = WinstonLogger.redacter();
|
||||
const log = {
|
||||
level: 'error',
|
||||
message: 'hello (world)',
|
||||
stack: 'hello (world) from this file',
|
||||
};
|
||||
expect(redacter.format.transform(msg(log))).toEqual(msg(log));
|
||||
redacter.add(['hello\n']);
|
||||
expect(redacter.format.transform(msg(log))).toEqual(
|
||||
msg({
|
||||
...log,
|
||||
message: '[REDACTED] (world)',
|
||||
stack: '[REDACTED] (world) from this file',
|
||||
}),
|
||||
);
|
||||
redacter.add(['(world']);
|
||||
expect(redacter.format.transform(msg(log))).toEqual(
|
||||
msg({
|
||||
...log,
|
||||
message: '[REDACTED] [REDACTED])',
|
||||
stack: '[REDACTED] [REDACTED]) from this file',
|
||||
it('should redact and escape regex', () => {
|
||||
const mockTransport = new Transport({
|
||||
log: jest.fn(),
|
||||
logv: jest.fn(),
|
||||
});
|
||||
|
||||
const logger = WinstonLogger.create({
|
||||
format: format.json(),
|
||||
transports: [mockTransport],
|
||||
});
|
||||
|
||||
logger.addRedactions(['hello (world']);
|
||||
|
||||
logger.error('hello (world) from this file');
|
||||
|
||||
expect(mockTransport.log).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
[MESSAGE]: JSON.stringify({
|
||||
level: 'error',
|
||||
message: '[REDACTED]) from this file',
|
||||
}),
|
||||
}),
|
||||
expect.any(Function),
|
||||
);
|
||||
});
|
||||
|
||||
it('redacter should redact nested object', () => {
|
||||
const redacter = WinstonLogger.redacter();
|
||||
const log = {
|
||||
level: 'error',
|
||||
message: {
|
||||
nested: 'hello (world) from nested object',
|
||||
null: null,
|
||||
nullProto: Object.create(null, {
|
||||
foo: { value: 'hello foo', enumerable: true },
|
||||
}),
|
||||
},
|
||||
};
|
||||
it('should redact nested object', () => {
|
||||
const mockTransport = new Transport({
|
||||
log: jest.fn(),
|
||||
logv: jest.fn(),
|
||||
});
|
||||
|
||||
redacter.add(['hello']);
|
||||
expect(redacter.format.transform(msg(log))).toEqual(
|
||||
msg({
|
||||
...log,
|
||||
message: {
|
||||
const logger = WinstonLogger.create({
|
||||
format: format.json(),
|
||||
transports: [mockTransport],
|
||||
});
|
||||
|
||||
logger.addRedactions(['hello']);
|
||||
|
||||
logger.error('something went wrong', {
|
||||
null: null,
|
||||
nested: 'hello (world) from nested object',
|
||||
nullProto: Object.create(null, {
|
||||
foo: { value: 'hello foo', enumerable: true },
|
||||
}),
|
||||
});
|
||||
|
||||
expect(mockTransport.log).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
[MESSAGE]: JSON.stringify({
|
||||
level: 'error',
|
||||
message: 'something went wrong',
|
||||
nested: '[REDACTED] (world) from nested object',
|
||||
null: null,
|
||||
nullProto: {
|
||||
foo: '[REDACTED] foo',
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
expect.any(Function),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
transports,
|
||||
transport as Transport,
|
||||
} from 'winston';
|
||||
import stringify from 'json-stringify-safe';
|
||||
import { MESSAGE } from 'triple-beam';
|
||||
import { escapeRegExp } from '../lib/escapeRegExp';
|
||||
|
||||
/**
|
||||
@@ -62,8 +62,8 @@ export class WinstonLogger implements RootLoggerService {
|
||||
let logger = createLogger({
|
||||
level: process.env.LOG_LEVEL || options.level || 'info',
|
||||
format: format.combine(
|
||||
redacter.format,
|
||||
options.format ?? defaultFormatter,
|
||||
redacter.format,
|
||||
),
|
||||
transports: options.transports ?? new transports.Console(),
|
||||
});
|
||||
@@ -86,26 +86,17 @@ export class WinstonLogger implements RootLoggerService {
|
||||
|
||||
let redactionPattern: RegExp | undefined = undefined;
|
||||
|
||||
const replace = (obj: TransformableInfo) => {
|
||||
if (!redactionPattern) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
const stringifiedFields = stringify(obj);
|
||||
const redacted = JSON.parse(
|
||||
stringifiedFields.replace(redactionPattern, '[REDACTED]'),
|
||||
);
|
||||
|
||||
for (const key in redacted) {
|
||||
if (obj && Object.hasOwn(obj, key)) {
|
||||
obj[key] = redacted[key];
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
return {
|
||||
format: format(replace)(),
|
||||
format: format((obj: TransformableInfo) => {
|
||||
if (!redactionPattern || !obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
obj[MESSAGE] = obj[MESSAGE]?.replace?.(redactionPattern, '[REDACTED]');
|
||||
obj.message = obj.message.replace?.(redactionPattern, '[REDACTED]');
|
||||
|
||||
return obj;
|
||||
})(),
|
||||
add(newRedactions) {
|
||||
let added = 0;
|
||||
for (const redactionToTrim of newRedactions) {
|
||||
|
||||
Reference in New Issue
Block a user