Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit db95d80

Browse files
author
Michal Vlasák
committed
Add logger name to pretty and non-pretty loggers
1 parent 1ce5e7d commit db95d80

4 files changed

Lines changed: 77 additions & 33 deletions

File tree

src/index.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,14 @@ const maxLevelWrite: pino.WriteFn = function(this: any, data: object): void {
4949
}
5050
};
5151

52-
const defaultLogger = (options: AckeeLoggerOptions = {}): AckeeLogger => {
52+
const defaultLogger = (options: AckeeLoggerOptions & { loggerName?: string } = {}): AckeeLogger => {
5353
serializers.disablePaths(options.disableFields);
5454
serializers.enablePaths(options.enableFields);
5555

5656
const isTesting = process.env.NODE_ENV === 'test';
5757
const defaultLevel: Level = options.defaultLevel || (isTesting ? 'silent' : 'debug');
58-
const streams = initLoggerStreams(defaultLevel, options);
58+
const messageKey = options.pretty ? 'msg' : 'message'; // "message" is the best option for Google Stackdriver,
59+
const streams = initLoggerStreams(defaultLevel, Object.assign({}, options, { messageKey }));
5960

6061
if (!options.ignoredHttpMethods) {
6162
options.ignoredHttpMethods = ['OPTIONS'];
@@ -66,9 +67,9 @@ const defaultLogger = (options: AckeeLoggerOptions = {}): AckeeLogger => {
6667
Object.assign(
6768
{},
6869
{
70+
messageKey,
6971
base: {},
7072
level: defaultLevel,
71-
messageKey: options.pretty ? 'msg' : 'message', // "message" is the best option for Google Stackdriver,
7273
serializers: serializers.serializers,
7374
timestamp: false,
7475
},
@@ -93,15 +94,16 @@ const defaultLogger = (options: AckeeLoggerOptions = {}): AckeeLogger => {
9394
};
9495

9596
let rootLogger: AckeeLogger;
97+
let rootOptions: AckeeLoggerOptions;
9698

9799
const parseLoggerData = (data: string | AckeeLoggerOptions = {}) => {
98100
let moduleName: string | undefined;
99101
let options: AckeeLoggerOptions = {};
100102
if (data) {
101103
if (isString(data)) {
102-
moduleName = data as string;
104+
moduleName = data;
103105
} else if (isObject(data)) {
104-
options = data as AckeeLoggerOptions;
106+
options = data;
105107
} else {
106108
throw new TypeError(`Invalid argument of type ${typeof data}`);
107109
}
@@ -114,11 +116,12 @@ const loggerFactory = (data: string | AckeeLoggerOptions = {}): AckeeLogger => {
114116

115117
if (!rootLogger) {
116118
rootLogger = defaultLogger(options);
119+
rootOptions = options;
117120
}
118121
if (!moduleName) {
119122
return rootLogger;
120123
}
121-
return (rootLogger.child({ name: moduleName }) as any) as AckeeLogger;
124+
return defaultLogger(Object.assign({ loggerName: moduleName }, rootOptions));
122125
};
123126

124127
const factoryProxy = new Proxy(loggerFactory, {

src/stackdriver.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ class StackDriverFormatStream extends Transform {
1313
// tslint:disable-next-line:function-name
1414
public _transform(chunk: any, _encoding: string, callback: (error?: Error | undefined, data?: any) => void) {
1515
const obj = JSON.parse(chunk);
16-
if (obj.name) {
17-
obj.message = `[${obj.name}] ${obj.message}`;
18-
}
1916
obj.severity = PINO_TO_STACKDRIVER[obj.level] || 'UNKNOWN';
2017

2118
this.push(`${JSON.stringify(obj)}\n`);

src/streams.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,33 @@ import { AckeeLoggerOptions, AckeeLoggerStream } from './interfaces';
66
import { levels } from './levels';
77
import { StackDriverFormatStream } from './stackdriver';
88

9+
const isString = (x: any) => typeof x === 'string' || x instanceof String;
10+
911
const pkgJson = JSON.parse(fs.readFileSync(path.resolve(path.join(__dirname, '..', 'package.json')), 'utf8'));
1012

11-
class DefaultTransformStream extends Transform {
12-
// tslint:disable-next-line:function-name
13-
public _transform(chunk: any, _encoding: string, callback: (error?: Error | undefined, data?: any) => void) {
14-
const obj = JSON.parse(chunk);
15-
obj.pkgVersion = pkgJson.version;
13+
const getDefaultTransformStream = (options: AckeeLoggerOptions & { messageKey: string; loggerName?: string }) => {
14+
class DefaultTransformStream extends Transform {
15+
// tslint:disable-next-line:function-name
16+
public _transform(chunk: any, _encoding: string, callback: (error?: Error | undefined, data?: any) => void) {
17+
const obj = JSON.parse(chunk);
18+
obj.pkgVersion = pkgJson.version;
19+
const loggerName = options.loggerName;
20+
if (options.pretty) {
21+
obj['name\0'] = obj.name; // add null character so that it is not interpreted by pino-pretty but still visible to user unchanged
22+
delete obj.name;
23+
if (loggerName) {
24+
obj.name = loggerName;
25+
}
26+
} else if (obj[options.messageKey] && isString(obj[options.messageKey]) && loggerName) {
27+
obj[options.messageKey] = `[${loggerName}] ${obj[options.messageKey]}`;
28+
}
1629

17-
this.push(`${JSON.stringify(obj)}\n`);
18-
callback();
30+
this.push(`${JSON.stringify(obj)}\n`);
31+
callback();
32+
}
1933
}
20-
}
34+
return DefaultTransformStream;
35+
};
2136

2237
const decorateStreams = <T extends Transform>(streams: AckeeLoggerStream[], streamClass: new () => T) => {
2338
return streams.map(stream => {
@@ -31,7 +46,10 @@ const decorateStreams = <T extends Transform>(streams: AckeeLoggerStream[], stre
3146
});
3247
};
3348

34-
const initLoggerStreams = (defaultLevel: pino.LevelWithSilent, options: AckeeLoggerOptions = {}) => {
49+
const initLoggerStreams = (
50+
defaultLevel: pino.LevelWithSilent,
51+
options: AckeeLoggerOptions & { messageKey: string; loggerName?: string }
52+
) => {
3553
let streams: AckeeLoggerStream[];
3654
if (options.streams) {
3755
streams = options.streams;
@@ -54,7 +72,7 @@ const initLoggerStreams = (defaultLevel: pino.LevelWithSilent, options: AckeeLog
5472
streams = decorateStreams(streams, StackDriverFormatStream);
5573
}
5674

57-
streams = decorateStreams(streams, DefaultTransformStream);
75+
streams = decorateStreams(streams, getDefaultTransformStream(options));
5876

5977
return streams;
6078
};

src/tests/index.test.ts

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,44 @@ test('silent stream does not write', () => {
184184
expect(loggerWrites).not.toBeCalled();
185185
});
186186

187-
test('logger name is shown in non-pretty message', () =>
188-
new Promise((resolve, reject) => {
189-
const loggerName = 'database';
190-
loggerFactory({
191-
streams: [
192-
testWriteStream(resolve, json => {
193-
expect(json.name).toBe(loggerName);
194-
expect(json.message).toStartWith(`[${loggerName}] `);
195-
}),
196-
],
197-
});
198-
const logger = loggerFactory(loggerName);
187+
const exampleMessages = [
188+
{ type: 'simple', logData: 'Hello' },
189+
{ type: 'message-key', logData: { message: 'You gotta do, what you gotta do' } },
190+
{ type: 'msg-key', logData: { message: 'Mirror, mirror, on the wall' } },
191+
];
192+
193+
exampleMessages.forEach(data => {
194+
test(`logger name is shown in non-pretty ${data.type} message`, () =>
195+
new Promise((resolve, reject) => {
196+
const loggerName = 'database';
197+
loggerFactory({
198+
pretty: false,
199+
streams: [
200+
testWriteStream(resolve, json => {
201+
expect(json.message).toStartWith(`[${loggerName}] `);
202+
}),
203+
],
204+
});
205+
const logger = loggerFactory(loggerName);
199206

200-
logger.fatal('Hello');
201-
}));
207+
logger.fatal(data.logData);
208+
}));
209+
});
210+
211+
exampleMessages.forEach(data => {
212+
test(`logger name is propagated to pretty object with ${data.type} message`, () =>
213+
new Promise((resolve, reject) => {
214+
const loggerName = 'database';
215+
loggerFactory({
216+
pretty: true,
217+
streams: [
218+
testWriteStream(resolve, json => {
219+
expect(json.name).toEqual(loggerName);
220+
}),
221+
],
222+
});
223+
const logger = loggerFactory(loggerName);
224+
225+
logger.fatal(data.logData);
226+
}));
227+
});

0 commit comments

Comments
 (0)