Skip to content

Commit 4dc812e

Browse files
hectorhdzgtrentm
andauthored
feat(instrumentation-bunyan): Allow log level to be configured for log sending (#1919)
* Allow log level to be configured for auto instrumentation and BunyanStream * Addressing comments * Update * Update plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts Co-authored-by: Trent Mick <[email protected]> * Add test coverage --------- Co-authored-by: Trent Mick <[email protected]>
1 parent 9d19ca4 commit 4dc812e

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

plugins/node/opentelemetry-instrumentation-bunyan/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ Log injection can be disabled with the `disableLogCorrelation: true` option.
8787
| Option | Type | Description |
8888
| ----------------------- | ----------------- | ----------- |
8989
| `disableLogSending` | `boolean` | Whether to disable [log sending](#log-sending). Default `false`. |
90+
| `logSeverity` | `SeverityNumber` | Control severity level for [log sending](#log-sending). Default `SeverityNumber.UNSPECIFIED`, it will use Bunnyan Logger's current level when unspecified. |
9091
| `disableLogCorrelation` | `boolean` | Whether to disable [log correlation](#log-correlation). Default `false`. |
9192
| `logHook` | `LogHookFunction` | An option hook to inject additional context to a log record after trace-context has been added. This requires `disableLogCorrelation` to be false. |
9293

plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { BunyanInstrumentationConfig } from './types';
2525
import { VERSION } from './version';
2626
import { OpenTelemetryBunyanStream } from './OpenTelemetryBunyanStream';
2727
import type * as BunyanLogger from 'bunyan';
28+
import { SeverityNumber } from '@opentelemetry/api-logs';
2829

2930
const DEFAULT_CONFIG: BunyanInstrumentationConfig = {
3031
disableLogSending: false,
@@ -157,10 +158,15 @@ export class BunyanInstrumentation extends InstrumentationBase<
157158
return;
158159
}
159160
this._diag.debug('Adding OpenTelemetryBunyanStream to logger');
161+
let streamLevel = logger.level();
162+
if (config.logSeverity) {
163+
const bunyanLevel = bunyanLevelFromSeverity(config.logSeverity);
164+
streamLevel = bunyanLevel || streamLevel;
165+
}
160166
logger.addStream({
161167
type: 'raw',
162168
stream: new OpenTelemetryBunyanStream(),
163-
level: logger.level(),
169+
level: streamLevel,
164170
});
165171
}
166172

@@ -182,3 +188,20 @@ export class BunyanInstrumentation extends InstrumentationBase<
182188
);
183189
}
184190
}
191+
192+
function bunyanLevelFromSeverity(severity: SeverityNumber): string | undefined {
193+
if (severity >= SeverityNumber.FATAL) {
194+
return 'fatal';
195+
} else if (severity >= SeverityNumber.ERROR) {
196+
return 'error';
197+
} else if (severity >= SeverityNumber.WARN) {
198+
return 'warn';
199+
} else if (severity >= SeverityNumber.INFO) {
200+
return 'info';
201+
} else if (severity >= SeverityNumber.DEBUG) {
202+
return 'debug';
203+
} else if (severity >= SeverityNumber.TRACE) {
204+
return 'trace';
205+
}
206+
return;
207+
}

plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import { Span } from '@opentelemetry/api';
18+
import { SeverityNumber } from '@opentelemetry/api-logs';
1819
import { InstrumentationConfig } from '@opentelemetry/instrumentation';
1920

2021
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -28,6 +29,11 @@ export interface BunyanInstrumentationConfig extends InstrumentationConfig {
2829
*/
2930
disableLogSending?: boolean;
3031

32+
/**
33+
* Control Log sending severity level, logs will be sent for specified severity and higher.
34+
*/
35+
logSeverity?: SeverityNumber;
36+
3137
/**
3238
* Whether to disable the injection trace-context fields, and possibly other
3339
* fields from `logHook()`, into log records for log correlation.

plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,92 @@ describe('BunyanInstrumentation', () => {
319319
assert.strictEqual(rec.body, 'hi');
320320
assert.strictEqual(rec.attributes.aProperty, 'bar');
321321
});
322+
323+
it('log record error level', () => {
324+
instrumentation.setConfig({ logSeverity: SeverityNumber.FATAL });
325+
// Setting `logSeverity` only has an impact on Loggers created
326+
// *after* it is set. So we cannot test with the `log` created in
327+
// `beforeEach()` above.
328+
log = Logger.createLogger({ name: 'test-logger-name', stream });
329+
log.error('error log');
330+
log.fatal('fatal log');
331+
const logRecords = memExporter.getFinishedLogRecords();
332+
// Only one log record match configured severity
333+
assert.strictEqual(logRecords.length, 1);
334+
assert.strictEqual(logRecords[0].body, 'fatal log');
335+
});
336+
337+
it('log record error level', () => {
338+
instrumentation.setConfig({ logSeverity: SeverityNumber.ERROR });
339+
// Setting `logSeverity` only has an impact on Loggers created
340+
// *after* it is set. So we cannot test with the `log` created in
341+
// `beforeEach()` above.
342+
log = Logger.createLogger({ name: 'test-logger-name', stream });
343+
log.warn('warn log');
344+
log.error('error log');
345+
const logRecords = memExporter.getFinishedLogRecords();
346+
// Only one log record match configured severity
347+
assert.strictEqual(logRecords.length, 1);
348+
assert.strictEqual(logRecords[0].body, 'error log');
349+
});
350+
351+
it('log record warn level', () => {
352+
instrumentation.setConfig({ logSeverity: SeverityNumber.WARN });
353+
// Setting `logSeverity` only has an impact on Loggers created
354+
// *after* it is set. So we cannot test with the `log` created in
355+
// `beforeEach()` above.
356+
log = Logger.createLogger({ name: 'test-logger-name', stream });
357+
log.info('info log');
358+
log.warn('warn log');
359+
const logRecords = memExporter.getFinishedLogRecords();
360+
// Only one log record match configured severity
361+
assert.strictEqual(logRecords.length, 1);
362+
assert.strictEqual(logRecords[0].body, 'warn log');
363+
});
364+
365+
it('log record info level', () => {
366+
instrumentation.setConfig({ logSeverity: SeverityNumber.INFO });
367+
// Setting `logSeverity` only has an impact on Loggers created
368+
// *after* it is set. So we cannot test with the `log` created in
369+
// `beforeEach()` above.
370+
log = Logger.createLogger({ name: 'test-logger-name', stream });
371+
log.debug('debug log');
372+
log.info('info log');
373+
const logRecords = memExporter.getFinishedLogRecords();
374+
// Only one log record match configured severity
375+
assert.strictEqual(logRecords.length, 1);
376+
assert.strictEqual(logRecords[0].body, 'info log');
377+
});
378+
379+
it('log record debug level', () => {
380+
instrumentation.setConfig({ logSeverity: SeverityNumber.DEBUG });
381+
log = Logger.createLogger({ name: 'test-logger-name', stream });
382+
log.info('info log');
383+
log.debug('debug log');
384+
// Just the log.info() writes to `stream`.
385+
sinon.assert.calledOnce(writeSpy);
386+
// Both log.info() and log.debug() should be written to the OTel Logs SDK.
387+
const logRecords = memExporter.getFinishedLogRecords();
388+
assert.strictEqual(logRecords.length, 2);
389+
assert.strictEqual(logRecords[0].body, 'info log');
390+
assert.strictEqual(logRecords[1].body, 'debug log');
391+
});
392+
393+
it('log record trace level', () => {
394+
instrumentation.setConfig({ logSeverity: SeverityNumber.TRACE });
395+
log = Logger.createLogger({ name: 'test-logger-name', stream });
396+
log.info('info log');
397+
log.debug('debug log');
398+
log.debug('trace log');
399+
// Just the log.info() writes to `stream`.
400+
sinon.assert.calledOnce(writeSpy);
401+
// Both log.info() and log.debug() should be written to the OTel Logs SDK.
402+
const logRecords = memExporter.getFinishedLogRecords();
403+
assert.strictEqual(logRecords.length, 3);
404+
assert.strictEqual(logRecords[0].body, 'info log');
405+
assert.strictEqual(logRecords[1].body, 'debug log');
406+
assert.strictEqual(logRecords[2].body, 'trace log');
407+
});
322408
});
323409

324410
describe('disabled instrumentation', () => {

0 commit comments

Comments
 (0)