Skip to content

Commit 952abc7

Browse files
trentmhectorhdzg
andauthored
fix(winston-transport, instrumentation-winston): get the correct severityText and severityNumber with winston.format.colorize() is used (#2956)
Closes: #2952 Co-authored-by: Hector Hernandez <[email protected]>
1 parent 215c2b5 commit 952abc7

File tree

4 files changed

+94
-33
lines changed

4 files changed

+94
-33
lines changed

packages/instrumentation-winston/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010
"directory": "packages/instrumentation-winston"
1111
},
1212
"scripts": {
13-
"test": "npm run test-v1-v2 && npm run test-v3 && nyc merge .nyc_output ./coverage/coverage-final.json",
14-
"test-v1-v2": "tav winston 2.4.7 npm run test-run",
15-
"test-v3": "npm run test-run",
16-
"test-run": "nyc --no-clean mocha 'test/**/*.test.ts'",
13+
"test": "nyc mocha 'test/**/*.test.ts'",
1714
"test-all-versions": "tav",
1815
"tdd": "npm run test-run -- --watch-extensions ts --watch",
1916
"clean": "rimraf build/*",

packages/instrumentation-winston/test/winston.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ describe('WinstonInstrumentation', () => {
6161
cli,
6262
}
6363

64-
function initLogger(levelsType?: LevelsType) {
64+
/**
65+
* Set `logger` to a new Winston logger instance with the given
66+
* configuration, and setup with `writeSpy` to spy on emitted logs.
67+
*/
68+
function initLogger(levelsType?: LevelsType, formatType?: string) {
6569
const winston = require('winston');
6670

6771
let levels = winston.config.npm.levels;
@@ -71,6 +75,19 @@ describe('WinstonInstrumentation', () => {
7175
levels = winston.config.cli.levels;
7276
}
7377

78+
let format;
79+
switch (formatType) {
80+
case 'colorize':
81+
format = winston.format.colorize();
82+
break;
83+
case 'none':
84+
case undefined:
85+
format = undefined;
86+
break;
87+
default:
88+
throw new Error(`unknown formatType: "${formatType}"`);
89+
}
90+
7491
const stream = new Writable();
7592
stream._write = () => {};
7693
writeSpy = sinon.spy(stream, 'write');
@@ -80,6 +97,7 @@ describe('WinstonInstrumentation', () => {
8097
logger = winston.createLogger({
8198
level: 'debug',
8299
levels: levels,
100+
format,
83101
transports: [
84102
new winston.transports.Stream({
85103
stream,
@@ -91,6 +109,7 @@ describe('WinstonInstrumentation', () => {
91109
isWinston2 = true;
92110
logger = new winston.Logger({
93111
levels: levels,
112+
format,
94113
transports: [
95114
new winston.transports.File({
96115
stream,
@@ -236,6 +255,32 @@ describe('WinstonInstrumentation', () => {
236255
}
237256
});
238257

258+
it('emit LogRecord with correct severity* when colorize() formatter is used', () => {
259+
if (!isWinston2) {
260+
instrumentation.setConfig({
261+
disableLogSending: false,
262+
});
263+
initLogger(LevelsType.npm, 'colorize');
264+
265+
logger.log('debug', kMessage);
266+
logger.log('info', kMessage);
267+
logger.log('warn', kMessage);
268+
const logRecords = memoryLogExporter.getFinishedLogRecords();
269+
assert.strictEqual(logRecords.length, 3);
270+
assert.strictEqual(logRecords[0].severityText, 'debug');
271+
assert.strictEqual(logRecords[0].severityNumber, 5);
272+
assert.strictEqual(logRecords[0].body, kMessage);
273+
assert.strictEqual(logRecords[1].severityText, 'info');
274+
assert.strictEqual(logRecords[1].severityNumber, 9);
275+
assert.strictEqual(logRecords[1].body, kMessage);
276+
assert.strictEqual(logRecords[2].severityText, 'warn');
277+
assert.strictEqual(logRecords[2].severityNumber, 13);
278+
assert.strictEqual(logRecords[2].body, kMessage);
279+
280+
initLogger();
281+
}
282+
});
283+
239284
it('do not emit log record if @opentelemetry/winston-transport load fails', () => {
240285
const module = require('module');
241286
const originalRequire = module.prototype.require;

packages/winston-transport/src/utils.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,23 @@ function getSeverityNumber(level: string): SeverityNumber | undefined {
6060
}
6161

6262
export function emitLogRecord(
63-
record: Record<string, any>,
63+
record: Record<string | symbol, any>,
6464
logger: Logger
6565
): void {
6666
const { message, level, ...splat } = record;
6767
const attributes: LogAttributes = {};
68+
// Ensures the log level is read from a symbol property, avoiding any
69+
// accidental inclusion of ANSI color codes that may be present in the string
70+
// property.
71+
const levelSym = record[Symbol.for('level')];
6872
for (const key in splat) {
6973
if (Object.prototype.hasOwnProperty.call(splat, key)) {
7074
attributes[key] = splat[key];
7175
}
7276
}
7377
const logRecord: LogRecord = {
74-
severityNumber: getSeverityNumber(level),
75-
severityText: level,
78+
severityNumber: getSeverityNumber(levelSym),
79+
severityText: levelSym,
7680
body: message,
7781
attributes: attributes,
7882
};

packages/winston-transport/test/openTelemetryTransport.test.ts

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,18 @@ describe('OpenTelemetryTransportV3', () => {
7474
it('npm levels', () => {
7575
const callback = () => {};
7676
const transport = new OpenTelemetryTransportV3();
77-
transport.log({ message: kMessage, level: 'error' }, callback);
78-
transport.log({ message: kMessage, level: 'warn' }, callback);
79-
transport.log({ message: kMessage, level: 'info' }, callback);
80-
transport.log({ message: kMessage, level: 'http' }, callback);
81-
transport.log({ message: kMessage, level: 'verbose' }, callback);
82-
transport.log({ message: kMessage, level: 'debug' }, callback);
83-
transport.log({ message: kMessage, level: 'silly' }, callback);
77+
const sym = Symbol.for('level');
78+
for (const level of [
79+
'error',
80+
'warn',
81+
'info',
82+
'http',
83+
'verbose',
84+
'debug',
85+
'silly',
86+
]) {
87+
transport.log({ message: kMessage, level, [sym]: level }, callback);
88+
}
8489
const logRecords = memoryLogExporter.getFinishedLogRecords();
8590
assert.strictEqual(logRecords.length, 7);
8691
assert.strictEqual(logRecords[0].severityNumber, SeverityNumber.ERROR);
@@ -95,16 +100,21 @@ describe('OpenTelemetryTransportV3', () => {
95100
it('cli levels', () => {
96101
const callback = () => {};
97102
const transport = new OpenTelemetryTransportV3();
98-
transport.log({ message: kMessage, level: 'error' }, callback);
99-
transport.log({ message: kMessage, level: 'warn' }, callback);
100-
transport.log({ message: kMessage, level: 'help' }, callback);
101-
transport.log({ message: kMessage, level: 'data' }, callback);
102-
transport.log({ message: kMessage, level: 'info' }, callback);
103-
transport.log({ message: kMessage, level: 'debug' }, callback);
104-
transport.log({ message: kMessage, level: 'verbose' }, callback);
105-
transport.log({ message: kMessage, level: 'prompt' }, callback);
106-
transport.log({ message: kMessage, level: 'input' }, callback);
107-
transport.log({ message: kMessage, level: 'silly' }, callback);
103+
const sym = Symbol.for('level');
104+
for (const level of [
105+
'error',
106+
'warn',
107+
'help',
108+
'data',
109+
'info',
110+
'debug',
111+
'verbose',
112+
'prompt',
113+
'input',
114+
'silly',
115+
]) {
116+
transport.log({ message: kMessage, level, [sym]: level }, callback);
117+
}
108118
const logRecords = memoryLogExporter.getFinishedLogRecords();
109119
assert.strictEqual(logRecords.length, 10);
110120
assert.strictEqual(logRecords[0].severityNumber, SeverityNumber.ERROR);
@@ -122,14 +132,19 @@ describe('OpenTelemetryTransportV3', () => {
122132
it('syslog levels', () => {
123133
const callback = () => {};
124134
const transport = new OpenTelemetryTransportV3();
125-
transport.log({ message: kMessage, level: 'emerg' }, callback);
126-
transport.log({ message: kMessage, level: 'alert' }, callback);
127-
transport.log({ message: kMessage, level: 'crit' }, callback);
128-
transport.log({ message: kMessage, level: 'error' }, callback);
129-
transport.log({ message: kMessage, level: 'warning' }, callback);
130-
transport.log({ message: kMessage, level: 'notice' }, callback);
131-
transport.log({ message: kMessage, level: 'info' }, callback);
132-
transport.log({ message: kMessage, level: 'debug' }, callback);
135+
const sym = Symbol.for('level');
136+
for (const level of [
137+
'emerg',
138+
'alert',
139+
'crit',
140+
'error',
141+
'warning',
142+
'notice',
143+
'info',
144+
'debug',
145+
]) {
146+
transport.log({ message: kMessage, level, [sym]: level }, callback);
147+
}
133148
const logRecords = memoryLogExporter.getFinishedLogRecords();
134149
assert.strictEqual(logRecords.length, 8);
135150
assert.strictEqual(logRecords[0].severityNumber, SeverityNumber.FATAL3);

0 commit comments

Comments
 (0)