Skip to content

Commit 28640ee

Browse files
committed
fix: wrap the Reliability Kit logger
We have been losing information from the OpenTelemetry internal logs because they log multiple messages in a row which pino/reliability kit does not support. We don't support this because we want to maintain consistency with n-logger. To fix this, we need to wrap the Reliability Kit logger and extract any extra logged information into a new property. I've gone with `details`. Testing this locally, it's not common to get any info but it's important when we do get it - it helped me debug the issue with loading Pino ahead of instrumentation.
1 parent 7daaa7b commit 28640ee

File tree

2 files changed

+82
-17
lines changed

2 files changed

+82
-17
lines changed

packages/opentelemetry/lib/index.js

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,18 @@ function setupOpenTelemetry({
4444
});
4545
}
4646

47-
// Use a Reliability Kit logger for logging. The DiagLogLevel
48-
// does nothing here – Reliability Kit's log level (set through
49-
// the LOG_LEVEL environment variable) takes over. We set the
50-
// OpenTelemetry log level to the maximum value that we want
51-
// Reliability Kit to consider logging
52-
opentelemetry.api.diag.setLogger(
53-
// @ts-ignore this complains because DiagLogger accepts a type
54-
// of unknown whereas our logger is stricter. This is fine though,
55-
// if something unknown is logged then we do our best with it.
56-
// It's easier to ignore this error than fix it.
57-
logger.createChildLogger({ event: 'OTEL_INTERNALS' }),
58-
opentelemetry.api.DiagLogLevel.INFO
59-
);
47+
// We need to create a new logger for OpenTelemetry internals
48+
// because the function signature is different and OpenTelemetry
49+
// logs mutliple strings. With pino this means we lose data
50+
const log = logger.createChildLogger({ event: 'OTEL_INTERNALS' });
51+
const opentelemetryLogger = {
52+
error: (...args) => log.error(args[0], { details: args.slice(1) }),
53+
info: (...args) => log.info(args[0], { details: args.slice(1) }),
54+
warn: (...args) => log.warn(args[0], { details: args.slice(1) }),
55+
debug: () => {},
56+
verbose: () => {}
57+
};
58+
opentelemetry.api.diag.setLogger(opentelemetryLogger);
6059

6160
// Set up and start OpenTelemetry
6261
instances = {

packages/opentelemetry/test/unit/lib/index.spec.js

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ describe('@dotcom-reliability-kit/opentelemetry', () => {
2424
let createTracingConfig;
2525
let HostMetrics;
2626
let logger;
27+
let mockChildLogger;
2728
let NodeSDK;
2829
let opentelemetry;
2930

@@ -46,7 +47,14 @@ describe('@dotcom-reliability-kit/opentelemetry', () => {
4647
NodeSDK = require('@opentelemetry/sdk-node').NodeSDK;
4748
logger = require('@dotcom-reliability-kit/logger');
4849

49-
logger.createChildLogger.mockReturnValue('mock child logger');
50+
mockChildLogger = {
51+
debug: jest.fn(),
52+
error: jest.fn(),
53+
info: jest.fn(),
54+
verbose: jest.fn(),
55+
warn: jest.fn()
56+
};
57+
logger.createChildLogger.mockReturnValue(mockChildLogger);
5058
api.DiagLogLevel.INFO = 'mock info log level';
5159

5260
opentelemetry = require('../../../lib/index');
@@ -69,18 +77,76 @@ describe('@dotcom-reliability-kit/opentelemetry', () => {
6977
});
7078
});
7179

72-
it('sets up OpenTelemetry to log via Reliability Kit logger', () => {
80+
it('sets up OpenTelemetry to log via a custom logger', () => {
7381
expect(logger.createChildLogger).toHaveBeenCalledTimes(1);
7482
expect(logger.createChildLogger).toHaveBeenCalledWith({
7583
event: 'OTEL_INTERNALS'
7684
});
7785
expect(api.diag.setLogger).toHaveBeenCalledTimes(1);
86+
expect(api.diag.setLogger).not.toHaveBeenCalledWith(mockChildLogger);
7887
expect(api.diag.setLogger).toHaveBeenCalledWith(
79-
'mock child logger',
80-
'mock info log level'
88+
expect.objectContaining({
89+
debug: expect.any(Function),
90+
error: expect.any(Function),
91+
info: expect.any(Function),
92+
verbose: expect.any(Function),
93+
warn: expect.any(Function)
94+
})
8195
);
8296
});
8397

98+
describe('custom logger', () => {
99+
let customLogger;
100+
101+
beforeEach(() => {
102+
customLogger = api.diag.setLogger.mock.calls[0][0];
103+
});
104+
105+
describe('.debug()', () => {
106+
it('does nothing', () => {
107+
customLogger.debug('mock message 1', 'mock message 2');
108+
expect(mockChildLogger.debug).toHaveBeenCalledTimes(0);
109+
});
110+
});
111+
112+
describe('.error()', () => {
113+
it('logs an error via the Reliability Kit child logger', () => {
114+
customLogger.error('mock message 1', 'mock message 2');
115+
expect(mockChildLogger.error).toHaveBeenCalledTimes(1);
116+
expect(mockChildLogger.error).toHaveBeenCalledWith('mock message 1', {
117+
details: ['mock message 2']
118+
});
119+
});
120+
});
121+
122+
describe('.info()', () => {
123+
it('logs info via the Reliability Kit child logger', () => {
124+
customLogger.info('mock message 1', 'mock message 2');
125+
expect(mockChildLogger.info).toHaveBeenCalledTimes(1);
126+
expect(mockChildLogger.info).toHaveBeenCalledWith('mock message 1', {
127+
details: ['mock message 2']
128+
});
129+
});
130+
});
131+
132+
describe('.verbose()', () => {
133+
it('does nothing', () => {
134+
customLogger.verbose('mock message 1', 'mock message 2');
135+
expect(mockChildLogger.verbose).toHaveBeenCalledTimes(0);
136+
});
137+
});
138+
139+
describe('.warn()', () => {
140+
it('logs an warning via the Reliability Kit child logger', () => {
141+
customLogger.warn('mock message 1', 'mock message 2');
142+
expect(mockChildLogger.warn).toHaveBeenCalledTimes(1);
143+
expect(mockChildLogger.warn).toHaveBeenCalledWith('mock message 1', {
144+
details: ['mock message 2']
145+
});
146+
});
147+
});
148+
});
149+
84150
it('configures the OpenTelemetry instrumentations', () => {
85151
expect(createInstrumentationConfig).toHaveBeenCalledTimes(1);
86152
expect(createInstrumentationConfig).toHaveBeenCalledWith();

0 commit comments

Comments
 (0)