From 59f11f37171cf075f80f320df06e5fdceb0c2d48 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Fri, 22 Sep 2023 14:01:52 -0700 Subject: [PATCH 01/30] feat(instrumentation-bunyan): add log sending to Logs Bridge API This extends the Bunyan instrumentation to automatically add a Bunyan stream to created loggers that will send log records to the Logs Bridge API: https://opentelemetry.io/docs/specs/otel/logs/bridge-api/ Now that the instrumentation supports separate "injection" of fields and "bridging" of log records functionality, this also adds two boolean options to disable those independently: `enableInjection` and `enableLogsBridge`. This also updates the instrumentation to work with ES module usage. Closes: #1559 --- .../README.md | 70 +++-- .../examples/README.md | 80 ++++++ .../examples/app.js | 32 +++ .../examples/app.mjs | 33 +++ .../examples/package.json | 25 ++ .../examples/telemetry.js | 45 ++++ .../package.json | 5 +- .../src/OpenTelemetryBunyanStream.ts | 147 ++++++++++ .../src/instrumentation.ts | 113 ++++++-- .../src/types.ts | 19 ++ .../test/bunyan.test.ts | 254 ++++++++++++++++-- 11 files changed, 747 insertions(+), 76 deletions(-) create mode 100644 plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md create mode 100644 plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js create mode 100644 plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs create mode 100644 plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json create mode 100644 plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js create mode 100644 plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/README.md index 4feb985aa1..1529493896 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/README.md @@ -3,7 +3,7 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] -This module provides automatic instrumentation for the injection of trace context to [`bunyan`](https://www.npmjs.com/package/bunyan), which may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle. +This module provides automatic instrumentation of the [`bunyan`](https://www.npmjs.com/package/bunyan) module to inject trace-context into Bunyan log records and to bridge Bunyan logging to the OpenTelemetry Logging SDK. It may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle. If total installation size is not constrained, it is recommended to use the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle with [@opentelemetry/sdk-node](`https://www.npmjs.com/package/@opentelemetry/sdk-node`) for the most seamless instrumentation experience. @@ -15,46 +15,74 @@ Compatible with OpenTelemetry JS API and SDK `1.0+`. npm install --save @opentelemetry/instrumentation-bunyan ``` -### Supported Versions +## Supported Versions - `^1.0.0` ## Usage ```js -const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); +const { NodeSDK, tracing, logs, api } = require('@opentelemetry/sdk-node'); const { BunyanInstrumentation } = require('@opentelemetry/instrumentation-bunyan'); -const { registerInstrumentations } = require('@opentelemetry/instrumentation'); - -const provider = new NodeTracerProvider(); -provider.register(); - -registerInstrumentations({ +const sdk = new NodeSDK({ + spanProcessor: new tracing.SimpleSpanProcessor(new tracing.ConsoleSpanExporter()), + logRecordProcessor: new logs.SimpleLogRecordProcessor(new logs.ConsoleLogRecordExporter()), instrumentations: [ new BunyanInstrumentation({ - // Optional hook to insert additional context to bunyan records. - // Called after trace context is added to the record. - logHook: (span, record) => { - record['resource.service.name'] = provider.resource.attributes['service.name']; - }, + // See below for Bunyan instrumentation options. }), - // other instrumentations - ], -}); + ] +}) + +const log = bunyan.createLogger({name: 'example'}); + +log.info('hi'); +// 1. Log records will be sent to the SDK-registered log record processor, if any. +// This is called "bridging". -bunyan.createLogger({ name: 'example' }).info('foo'); -// {"name":"example","msg":"foo","trace_id":"e21c7a95fff34e04f77c7bd518779621","span_id":"b7589a981fde09f4","trace_flags":"01", ...} +const tracer = api.getTracer('example'); +tracer.startActiveSpan('manual-span', span => { + log.info('in a span'); + // 2. Fields identifying the current span will be injected into log records: + // {"name":"example",...,"msg":"in a span","trace_id":"d61b4e4af1032e0aae279d12f3ab0159","span_id":"d140da862204f2a2","trace_flags":"01"} +}) ``` -### Fields added to bunyan records +### Logs Bridge + +Creation of a Bunyan Logger will automatically add a [Bunyan stream](https://github.com/trentm/node-bunyan#streams) that sends log records to the OpenTelemetry Logs Bridge API. The OpenTelemetry SDK can be configured to handle those records -- for example, sending them on to an OpenTelemetry collector for log archiving and processing. The example above shows a minimal configuration that emits OpenTelemetry log records to the console for debugging. + +If the OpenTelemetry SDK is not configured with a Logger provider, then this added stream will be a no-op. + +The logs bridge can be disabled with the `enableLogsBridge: false` option. -For the current active span, the following will be added to the bunyan record: +### Log injection + +Bunyan logger calls in the context of a tracing span will have fields indentifying +the span ([spec](https://opentelemetry.io/docs/specs/otel/compatibility/logging_trace_context/)): - `trace_id` - `span_id` - `trace_flags` +After adding these fields, the optional `logHook` is called to allow injecting additional fields. For example: + +```js + logHook: (span, record) => { + record['resource.service.name'] = provider.resource.attributes['service.name']; + } +``` + When no span context is active or the span context is invalid, injection is skipped. +Log injection can be disabled with the `enableInjection: false` option. + +### Bunyan instrumentation options + +| Option | Type | Description | +| ------------------ | ----------------- | ----------- | +| `enableLogsBridge` | `boolean` | Whether [logs bridging](#logs-bridge) is enabled. Default `true`. | +| `enableInjection` | `boolean` | Whether [log injection](#log-injection) is enabled. Default `true`. | +| `logHook` | `LogHookFunction` | An option hook to inject additional context to a log record after span context has been added. This requires `enableInjection` to be true. | ## Useful links diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md new file mode 100644 index 0000000000..242770109b --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md @@ -0,0 +1,80 @@ +This is a small example app, "app.js", that shows using the +[Bunyan](https://github.com/trentm/node-bunyan) logger with OpenTelemetry. See +[the OpenTelemetry Bunyan instrumentation README](../) for full details. + +# Usage + +``` +npm install +node -r ./telemetry.js app.js +``` + +# Overview + +"telemetry.js" sets up the OpenTelemetry SDK to write OTel tracing spans and +log records to the *console* for simplicity. In a real setup you would +configure exporters to send to remote observability apps for viewing and +analysis. + +An example run looks like this: + +``` +$ node -r ./telemetry.js app.js +{"name":"myapp","hostname":"amachine.local","pid":93017,"level":20,"msg":"hi","time":"2023-09-27T23:24:06.074Z","v":0} +{ + timestamp: 1695857046074000, + traceId: undefined, + spanId: undefined, + traceFlags: undefined, + severityText: 'debug', + severityNumber: 5, + body: 'hi', + attributes: { name: 'myapp', hostname: 'amachine.local', pid: 93017 } +} +{"name":"myapp","hostname":"amachine.local","pid":93017,"level":30,"msg":"this record will have trace_id et al fields for the current span","time":"2023-09-27T23:24:06.079Z","v":0,"trace_id":"af5ce23816c4feabb713ee1dc84ef4d3","span_id":"5f50e181ec7bc621","trace_flags":"01"} +{ + timestamp: 1695857046079000, + traceId: 'af5ce23816c4feabb713ee1dc84ef4d3', + spanId: '5f50e181ec7bc621', + traceFlags: 1, + severityText: 'info', + severityNumber: 9, + body: 'this record will have trace_id et al fields for the current span', + attributes: { + name: 'myapp', + hostname: 'amachine.local', + pid: 93017, + trace_id: 'af5ce23816c4feabb713ee1dc84ef4d3', + span_id: '5f50e181ec7bc621', + trace_flags: '01' + } +} +{ + traceId: 'af5ce23816c4feabb713ee1dc84ef4d3', + parentId: undefined, + traceState: undefined, + name: 'manual-span', + id: '5f50e181ec7bc621', + kind: 0, + timestamp: 1695857046079000, + duration: 1407.196, + attributes: {}, + status: { code: 0 }, + events: [], + links: [] +} +``` + +There are two separate Bunyan instrumentation functionalities. The first is +that Bunyan log records emitted in the context of a tracing span will include +`trace_id` and `span_id` fields that can be used for correlating with collect +tracing data. Line 3 shows an example of this. + +The second is that a [Bunyan +stream](https://github.com/trentm/node-bunyan#streams) is automatically added +to created Loggers that will send every log record to the OpenTelemetry Logs +Bridge API. This means that if the OpenTelemetry SDK has been configured with +a Logger Provider, it will receive them. (If the OpenTelemetry SDK is not +configured for this, then the added Bunyan stream will be a no-op.) Lines 2 +and 4 show a dumped OpenTelemetry Log Record. + diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js new file mode 100644 index 0000000000..98bcad9fc6 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// A small example that shows using OpenTelemetry's instrumentation of +// Bunyan loggers. Usage: +// node --require ./telemetry.js app.js + +const otel = require('@opentelemetry/api'); +const bunyan = require('bunyan'); + +const log = bunyan.createLogger({name: 'myapp', level: 'debug'}); + +log.debug('hi'); + +const tracer = otel.trace.getTracer('example'); +tracer.startActiveSpan('manual-span', span => { + log.info('this record will have trace_id et al fields for the current span'); + span.end(); +}); diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs new file mode 100644 index 0000000000..a4dbc339a1 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// The equivalent of "app.js", but showing usage with ESM code. +// Usage: +// node --require ./telemetry.js --experimental-loader ../node_modules/@opentelemetry/instrumentation/hook.mjs app.js + +import { trace } from '@opentelemetry/api'; +import bunyan from 'bunyan'; + +const log = bunyan.createLogger({name: 'myapp', level: 'debug'}); + +log.debug('hi'); + +const tracer = trace.getTracer('example'); +tracer.startActiveSpan('manual-span', span => { + log.info('this record will have trace_id et al fields for the current span'); + span.end(); +}); + diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json b/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json new file mode 100644 index 0000000000..d7947e0ee1 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json @@ -0,0 +1,25 @@ +{ + "name": "bunyan-example", + "private": true, + "version": "0.43.0", + "description": "Example of Bunyan integration with OpenTelemetry", + "scripts": { + "start": "node -r ./telemetry.js app.js" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/open-telemetry/opentelemetry-js.git" + }, + "engines": { + "node": ">=14" + }, + "author": "OpenTelemetry Authors", + "license": "Apache-2.0", + "// @opentelemetry/instrumentation-bunyan": "TODO: change to a ver when there is a next release", + "dependencies": { + "@opentelemetry/api": "^1.6.0", + "@opentelemetry/instrumentation-bunyan": "../", + "@opentelemetry/sdk-node": "^0.43.0", + "bunyan": "^1.8.15" + } +} diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js b/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js new file mode 100644 index 0000000000..7f196869c8 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Setup telemetry for tracing and Bunyan logging. +// +// This writes OTel spans and log records to the console for simplicity. In a +// real setup you would configure exporters to send to remote observability apps +// for viewing and analysis. + +const { NodeSDK, tracing, logs, api } = require('@opentelemetry/sdk-node'); +// api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG); + +const { BunyanInstrumentation } = require('@opentelemetry/instrumentation-bunyan'); + +const sdk = new NodeSDK({ + serviceName: 'bunyan-example', + spanProcessor: new tracing.SimpleSpanProcessor(new tracing.ConsoleSpanExporter()), + logRecordProcessor: new logs.SimpleLogRecordProcessor(new logs.ConsoleLogRecordExporter()), + instrumentations: [ + new BunyanInstrumentation(), + ] +}) +process.on("SIGTERM", () => { + sdk + .shutdown() + .then( + () => {}, + (err) => console.log("warning: error shutting down OTel SDK", err) + ) + .finally(() => process.exit(0)); +}); +sdk.start(); diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/package.json b/plugins/node/opentelemetry-instrumentation-bunyan/package.json index 9286eccdfb..d5e04be6ac 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/package.json +++ b/plugins/node/opentelemetry-instrumentation-bunyan/package.json @@ -48,9 +48,11 @@ }, "devDependencies": { "@opentelemetry/api": "^1.3.0", - "@opentelemetry/context-async-hooks": "^1.8.0", + "@opentelemetry/resources": "^1.17.0", + "@opentelemetry/sdk-logs": "^0.43.0", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", + "@opentelemetry/semantic-conventions": "^1.17.0", "@types/mocha": "7.0.2", "@types/node": "18.6.5", "@types/sinon": "10.0.16", @@ -64,6 +66,7 @@ "typescript": "4.4.4" }, "dependencies": { + "@opentelemetry/api-logs": "^0.43.0", "@opentelemetry/instrumentation": "^0.43.0", "@types/bunyan": "1.8.9" }, diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts new file mode 100644 index 0000000000..7d402bf3bf --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -0,0 +1,147 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { logs, SeverityNumber, Logger } from '@opentelemetry/api-logs'; +import type { LoggerOptions } from '@opentelemetry/api-logs'; +import type * as BunyanLogger from 'bunyan'; +import { VERSION } from './version'; + +const DEFAULT_INSTRUMENTATION_SCOPE_NAME = 'io.opentelemetry.contrib.bunyan'; +const DEFAULT_INSTRUMENTATION_SCOPE_VERSION = VERSION; + +// This block is a copy (modulo code style and TypeScript types) of the Bunyan +// code that defines log level value and names. These values won't ever change +// in bunyan@1. This file is part of *instrumenting* Bunyan, so we want to +// avoid a dependency on the library. +const TRACE = 10; +const DEBUG = 20; +const INFO = 30; +const WARN = 40; +const ERROR = 50; +const FATAL = 60; +const levelFromName: { [name in BunyanLogger.LogLevelString]: number } = { + trace: TRACE, + debug: DEBUG, + info: INFO, + warn: WARN, + error: ERROR, + fatal: FATAL, +}; +const nameFromLevel: { [level: number]: string } = {}; +Object.keys(levelFromName).forEach(function (name) { + nameFromLevel[levelFromName[name as BunyanLogger.LogLevelString]] = name; +}); + +const OTEL_SEV_NUM_FROM_BUNYAN_LEVEL: { [level: number]: number } = { + [TRACE]: SeverityNumber.TRACE, + [DEBUG]: SeverityNumber.DEBUG, + [INFO]: SeverityNumber.INFO, + [WARN]: SeverityNumber.WARN, + [ERROR]: SeverityNumber.ERROR, + [FATAL]: SeverityNumber.FATAL, +}; + +const EXTRA_SEV_NUMS = [ + SeverityNumber.TRACE2, + SeverityNumber.TRACE3, + SeverityNumber.TRACE4, + SeverityNumber.DEBUG2, + SeverityNumber.DEBUG3, + SeverityNumber.DEBUG4, + SeverityNumber.INFO2, + SeverityNumber.INFO3, + SeverityNumber.INFO4, + SeverityNumber.WARN2, + SeverityNumber.WARN3, + SeverityNumber.WARN4, + SeverityNumber.ERROR2, + SeverityNumber.ERROR3, + SeverityNumber.ERROR4, + SeverityNumber.FATAL2, + SeverityNumber.FATAL3, + SeverityNumber.FATAL4, +]; + +function severityNumberFromBunyanLevel(lvl: number) { + // Fast common case: one of the known levels + const sev = OTEL_SEV_NUM_FROM_BUNYAN_LEVEL[lvl]; + if (sev !== undefined) { + return sev; + } + + // Otherwise, scale the Bunyan level range -- 10 (TRACE) to 70 (FATAL+10) + // -- onto the extra OTel severity numbers (TRACE2, TRACE3, ..., FATAL4). + // Values below bunyan.TRACE map to SeverityNumber.TRACE2, which is a bit + // weird. + return EXTRA_SEV_NUMS[ + Math.min( + EXTRA_SEV_NUMS.length - 1, + Math.max(0, Math.floor(((lvl - 10) / (70 - 10)) * EXTRA_SEV_NUMS.length)) + ) + ]; +} + +/** + * A Bunyan stream for sending log records to the OpenTelemetry Logs Bridge API. + */ +export class OpenTelemetryBunyanStream { + private _otelLogger: Logger; + + constructor(name?: string, version?: string, options?: LoggerOptions) { + this._otelLogger = logs.getLogger( + name || DEFAULT_INSTRUMENTATION_SCOPE_NAME, + version || DEFAULT_INSTRUMENTATION_SCOPE_VERSION, + options + ); + } + + /** + * Convert from https://github.com/trentm/node-bunyan#log-record-fields + * to https://opentelemetry.io/docs/specs/otel/logs/data-model/ + * + * Dev Notes: + * - We drop the Bunyan 'v' field. It is meant to indicate the format + * of the Bunyan log record. FWIW, it has always been `0`. + * - Some Bunyan fields would naturally map to Resource attributes: + * hostname -> host.name + * name -> service.name + * pid -> process.pid + * However, AFAIK there isn't a way to influence the LoggerProvider's + * `resource` from here. + * - Strip the `trace_id` et al fields that may have been added by the + * the _emit wrapper. + */ + write(rec: Record) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { time, level, msg, v, trace_id, span_id, trace_flags, ...fields } = + rec; + let timestamp = undefined; + if (typeof time.getTime === 'function') { + timestamp = time.getTime(); // ms + } else { + fields.time = time; // Expose non-Date "time" field on attributes. + } + const otelRec = { + timestamp, + observedTimestamp: timestamp, + severityNumber: severityNumberFromBunyanLevel(level), + severityText: nameFromLevel[level], + body: msg, + attributes: fields, + }; + this._otelLogger.emit(otelRec); + } +} diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts index a673a364bd..003ff223a7 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts @@ -14,28 +14,32 @@ * limitations under the License. */ -import { - context, - diag, - trace, - isSpanContextValid, - Span, -} from '@opentelemetry/api'; +import { inherits } from 'util'; +import { context, trace, isSpanContextValid, Span } from '@opentelemetry/api'; import { InstrumentationBase, InstrumentationNodeModuleDefinition, - isWrapped, safeExecuteInTheMiddle, } from '@opentelemetry/instrumentation'; import { BunyanInstrumentationConfig } from './types'; import { VERSION } from './version'; +import { OpenTelemetryBunyanStream } from './OpenTelemetryBunyanStream'; import type * as BunyanLogger from 'bunyan'; +const DEFAULT_CONFIG: BunyanInstrumentationConfig = { + enableLogsBridge: true, + enableInjection: true, +}; + export class BunyanInstrumentation extends InstrumentationBase< typeof BunyanLogger > { constructor(config: BunyanInstrumentationConfig = {}) { - super('@opentelemetry/instrumentation-bunyan', VERSION, config); + super( + '@opentelemetry/instrumentation-bunyan', + VERSION, + Object.assign({}, DEFAULT_CONFIG, config) + ); } protected init() { @@ -43,25 +47,55 @@ export class BunyanInstrumentation extends InstrumentationBase< new InstrumentationNodeModuleDefinition( 'bunyan', ['<2.0'], - logger => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const proto = logger.prototype as any; - if (isWrapped(proto['_emit'])) { - this._unwrap(proto, '_emit'); - } + (module: any, moduleVersion) => { + this._diag.debug(`Applying patch for bunyan@${moduleVersion}`); + const instrumentation = this; + const Logger = + module[Symbol.toStringTag] === 'Module' + ? module.default // ESM + : module; // CommonJS this._wrap( - proto, + Logger.prototype, '_emit', // eslint-disable-next-line @typescript-eslint/no-explicit-any this._getPatchedEmit() as any ); - return logger; - }, - logger => { - if (logger === undefined) return; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this._unwrap(logger.prototype as any, '_emit'); + + function LoggerTraced(this: any, ...args: unknown[]) { + let inst; + let retval = undefined; + if (this instanceof LoggerTraced) { + // called with `new Logger()` + inst = this; + Logger.call(this, ...args); + } else { + // called without `new` + inst = Logger.call(null, ...args); + retval = inst; + } + // If `_childOptions` is defined, this is a `Logger#child(...)` + // call. We must not add an OTel stream again. + if (args[1] /* _childOptions */ === undefined) { + instrumentation._addStream(inst); + } + return retval; + } + // Must use the deprecated `inherits` to support this style: + // const log = require('bunyan')({name: 'foo'}); + // i.e. calling the constructor function without `new`. + inherits(LoggerTraced, Logger); + + const patchedExports = Object.assign(LoggerTraced, Logger); + + this._wrap( + patchedExports, + 'createLogger', + // eslint-disable-next-line @typescript-eslint/no-explicit-any + this._getPatchedCreateLogger() as any + ); + + return patchedExports; } ), ]; @@ -72,21 +106,24 @@ export class BunyanInstrumentation extends InstrumentationBase< } override setConfig(config: BunyanInstrumentationConfig) { - this._config = config; + this._config = Object.assign({}, DEFAULT_CONFIG, config); } private _getPatchedEmit() { return (original: (...args: unknown[]) => void) => { const instrumentation = this; return function patchedEmit(this: BunyanLogger, ...args: unknown[]) { - const span = trace.getSpan(context.active()); + const config = instrumentation.getConfig(); + if (!instrumentation.isEnabled() || !config.enableInjection) { + return original.apply(this, args); + } + const span = trace.getSpan(context.active()); if (!span) { return original.apply(this, args); } const spanContext = span.spanContext(); - if (!isSpanContextValid(spanContext)) { return original.apply(this, args); } @@ -103,6 +140,30 @@ export class BunyanInstrumentation extends InstrumentationBase< }; } + private _getPatchedCreateLogger() { + return (original: (...args: unknown[]) => void) => { + const instrumentation = this; + return function patchedCreateLogger(...args: unknown[]) { + const logger = original(...args); + instrumentation._addStream(logger); + return logger; + }; + }; + } + + private _addStream(logger: any) { + const config: BunyanInstrumentationConfig = this._config; + if (!this.isEnabled() || !config.enableLogsBridge) { + return; + } + this._diag.debug('Adding OpenTelemetryBunyanStream to logger'); + logger.addStream({ + type: 'raw', + stream: new OpenTelemetryBunyanStream(), + level: logger.level(), + }); + } + private _callHook(span: Span, record: Record) { const hook = this.getConfig().logHook; @@ -114,7 +175,7 @@ export class BunyanInstrumentation extends InstrumentationBase< () => hook(span, record), err => { if (err) { - diag.error('bunyan instrumentation: error calling logHook', err); + this._diag.error('error calling logHook', err); } }, true diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts index 1e1559b463..f6315f8737 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts @@ -21,5 +21,24 @@ import { InstrumentationConfig } from '@opentelemetry/instrumentation'; export type LogHookFunction = (span: Span, record: Record) => void; export interface BunyanInstrumentationConfig extends InstrumentationConfig { + /** + * Whether to enable the automatic sending of log records to the OpenTelemetry + * Logs Bridge API. + * @default true + */ + enableLogsBridge?: boolean; + + /** + * Whether to enable the injection of data such as trace-context fields into + * log output. + * @default true + */ + enableInjection?: boolean; + + /** + * A function that allows injecting additional fields in log records. It is + * called, as `logHook(span, record)`, for each log record emitted in a valid + * span context. It requires `enableInjection` to be true. + */ logHook?: LogHookFunction; } diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index e82b912638..1c3ade7b57 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -19,47 +19,74 @@ import { SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; import { context, INVALID_SPAN_CONTEXT, trace } from '@opentelemetry/api'; +import { logs, SeverityNumber } from '@opentelemetry/api-logs'; +import { + LoggerProvider, + SimpleLogRecordProcessor, + InMemoryLogRecordExporter, +} from '@opentelemetry/sdk-logs'; import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { isWrapped } from '@opentelemetry/instrumentation'; -import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; +import { Resource } from '@opentelemetry/resources'; +import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import * as assert from 'assert'; -import * as Logger from 'bunyan'; +import * as os from 'os'; import * as sinon from 'sinon'; import { Writable } from 'stream'; import { BunyanInstrumentation } from '../src'; +import { VERSION } from '../src/version'; + +import type * as BunyanLogger from 'bunyan'; + +// import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'; +// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); + +const tracerProvider = new NodeTracerProvider(); +tracerProvider.register(); +tracerProvider.addSpanProcessor( + new SimpleSpanProcessor(new InMemorySpanExporter()) +); +const tracer = tracerProvider.getTracer('default'); -const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider(); -const tracer = provider.getTracer('default'); -provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter)); -context.setGlobalContextManager(new AsyncHooksContextManager()); +const resource = new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: 'test-instrumentation-bunyan', +}); +const loggerProvider = new LoggerProvider({ resource }); +const memExporter = new InMemoryLogRecordExporter(); +loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(memExporter)); +logs.setGlobalLoggerProvider(loggerProvider); + +const instrumentation = new BunyanInstrumentation(); +const Logger = require('bunyan'); describe('BunyanInstrumentation', () => { - let logger: Logger; - let stream; + let log: BunyanLogger; + let stream: Writable; let writeSpy: sinon.SinonSpy; - let instrumentation: BunyanInstrumentation; - before(() => { - instrumentation = new BunyanInstrumentation(); - require('bunyan'); + it('is instrumented', () => { assert.ok(isWrapped((Logger.prototype as any)['_emit'])); }); describe('enabled instrumentation', () => { beforeEach(() => { - instrumentation.setConfig({ enabled: true }); + instrumentation.setConfig({}); // reset to defaults + memExporter.getFinishedLogRecords().length = 0; // clear stream = new Writable(); stream._write = () => {}; writeSpy = sinon.spy(stream, 'write'); - logger = Logger.createLogger({ name: 'test', stream }); + log = Logger.createLogger({ + name: 'test-logger-name', + level: 'debug', + stream, + }); }); it('injects span context to records', () => { const span = tracer.startSpan('abc'); context.with(trace.setSpan(context.active(), span), () => { const { traceId, spanId, traceFlags } = span.spanContext(); - logger.info('foo'); + log.info('foo'); sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); assert.strictEqual(record['trace_id'], traceId); @@ -73,16 +100,15 @@ describe('BunyanInstrumentation', () => { }); }); - it('calls the users log hook', () => { + it('calls the logHook', () => { const span = tracer.startSpan('abc'); instrumentation.setConfig({ - enabled: true, logHook: (_span, record) => { record['resource.service.name'] = 'test-service'; }, }); context.with(trace.setSpan(context.active(), span), () => { - logger.info('foo'); + log.info('foo'); sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); assert.strictEqual(record['resource.service.name'], 'test-service'); @@ -90,7 +116,7 @@ describe('BunyanInstrumentation', () => { }); it('does not inject span context if no span is active', () => { - logger.info('foo'); + log.info('foo'); assert.strictEqual(trace.getSpan(context.active()), undefined); sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); @@ -103,7 +129,7 @@ describe('BunyanInstrumentation', () => { it('does not inject span context if span context is invalid', () => { const span = trace.wrapSpanContext(INVALID_SPAN_CONTEXT); context.with(trace.setSpan(context.active(), span), () => { - logger.info('foo'); + log.info('foo'); sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); assert.strictEqual(record['trace_id'], undefined); @@ -113,17 +139,16 @@ describe('BunyanInstrumentation', () => { }); }); - it('does not propagate exceptions from user hooks', () => { + it('does not propagate exceptions from logHook', () => { const span = tracer.startSpan('abc'); instrumentation.setConfig({ - enabled: true, logHook: () => { throw new Error('Oops'); }, }); context.with(trace.setSpan(context.active(), span), () => { const { traceId, spanId } = span.spanContext(); - logger.info('foo'); + log.info('foo'); sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); assert.strictEqual(record['trace_id'], traceId); @@ -131,6 +156,172 @@ describe('BunyanInstrumentation', () => { assert.strictEqual('foo', record['msg']); }); }); + + it('does not inject or call logHook if enableInjection=false', () => { + instrumentation.setConfig({ + enableInjection: false, + logHook: (_span, record) => { + record['resource.service.name'] = 'test-service'; + }, + }); + tracer.startActiveSpan('abc', span => { + log.info('foo'); + sinon.assert.calledOnce(writeSpy); + const record = JSON.parse(writeSpy.firstCall.args[0].toString()); + assert.strictEqual('foo', record['msg']); + assert.strictEqual(record['trace_id'], undefined); + assert.strictEqual(record['span_id'], undefined); + assert.strictEqual(record['trace_flags'], undefined); + assert.strictEqual(record['resource.service.name'], undefined); + assert.strictEqual( + memExporter.getFinishedLogRecords().length, + 1, + 'Logs Bridge still works' + ); + span.end(); + }); + }); + + it('emits log records to Logs Bridge API', () => { + const logRecords = memExporter.getFinishedLogRecords(); + + // levels + log.trace('at trace level'); + log.debug('at debug level'); + log.info('at info level'); + log.warn('at warn level'); + log.error('at error level'); + log.fatal('at fatal level'); + assert.strictEqual(logRecords.length, 5); + assert.strictEqual(logRecords[0].severityNumber, SeverityNumber.DEBUG); + assert.strictEqual(logRecords[0].severityText, 'debug'); + assert.strictEqual(logRecords[1].severityNumber, SeverityNumber.INFO); + assert.strictEqual(logRecords[1].severityText, 'info'); + assert.strictEqual(logRecords[2].severityNumber, SeverityNumber.WARN); + assert.strictEqual(logRecords[2].severityText, 'warn'); + assert.strictEqual(logRecords[3].severityNumber, SeverityNumber.ERROR); + assert.strictEqual(logRecords[3].severityText, 'error'); + assert.strictEqual(logRecords[4].severityNumber, SeverityNumber.FATAL); + assert.strictEqual(logRecords[4].severityText, 'fatal'); + + // attributes, resource, instrumentationScope, etc. + log.info({ foo: 'bar' }, 'a message'); + const rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.body, 'a message'); + assert.deepStrictEqual(rec.attributes, { + name: 'test-logger-name', + hostname: os.hostname(), + pid: process.pid, + foo: 'bar', + }); + assert.strictEqual( + rec.resource.attributes['service.name'], + 'test-instrumentation-bunyan' + ); + assert.strictEqual( + rec.instrumentationScope.name, + 'io.opentelemetry.contrib.bunyan' + ); + assert.strictEqual(rec.instrumentationScope.version, VERSION); + assert.strictEqual(rec.spanContext, undefined); + + // spanContext + tracer.startActiveSpan('abc', span => { + const { traceId, spanId, traceFlags } = span.spanContext(); + log.info('in active span'); + const rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.spanContext?.traceId, traceId); + assert.strictEqual(rec.spanContext?.spanId, spanId); + assert.strictEqual(rec.spanContext?.traceFlags, traceFlags); + + // This rec should *NOT* have the `trace_id` et al attributes. + assert.strictEqual(rec.attributes.trace_id, undefined); + assert.strictEqual(rec.attributes.span_id, undefined); + assert.strictEqual(rec.attributes.trace_flags, undefined); + + span.end(); + }); + }); + + it('handles log record edge cases', () => { + let rec; + const logRecords = memExporter.getFinishedLogRecords(); + + // A non-Date "time" Bunyan field. + log.info({ time: 'miller' }, 'hi'); + rec = logRecords[logRecords.length - 1]; + assert.deepEqual( + rec.hrTime.map(n => typeof n), + ['number', 'number'] + ); + assert.strictEqual(rec.attributes.time, 'miller'); + + // An atypical Bunyan level number. + log.info({ level: 42 }, 'just above Bunyan WARN==40'); + rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.severityNumber, SeverityNumber.WARN2); + assert.strictEqual(rec.severityText, undefined); + + log.info({ level: 200 }, 'far above Bunyan FATAL==60'); + rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.severityNumber, SeverityNumber.FATAL4); + assert.strictEqual(rec.severityText, undefined); + }); + + it('does not emit to the Logs Bridge API if enableLogsBridge=false', () => { + instrumentation.setConfig({ enableLogsBridge: false }); + + // Changing `enableLogsBridge` only has an impact on Loggers created + // *after* it is set. So we cannot test with the `log` created in + // `beforeEach()` above. + log = Logger.createLogger({ name: 'test-logger-name', stream }); + + tracer.startActiveSpan('abc', span => { + const { traceId, spanId } = span.spanContext(); + log.info('foo'); + assert.strictEqual(memExporter.getFinishedLogRecords().length, 0); + + // Test log injection still works. + sinon.assert.calledOnce(writeSpy); + const record = JSON.parse(writeSpy.firstCall.args[0].toString()); + assert.strictEqual('foo', record['msg']); + assert.strictEqual(record['trace_id'], traceId); + assert.strictEqual(record['span_id'], spanId); + span.end(); + }); + }); + + it('emits to the Logs Bridge API with `new Logger(...)`', () => { + log = new Logger({ name: 'test-logger-name', stream }); + log.info('foo'); + + const logRecords = memExporter.getFinishedLogRecords(); + assert.strictEqual(logRecords.length, 1); + let rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.body, 'foo'); + + const child = log.child({ aProperty: 'bar' }); + child.info('hi'); + rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.body, 'hi'); + assert.strictEqual(rec.attributes.aProperty, 'bar'); + }); + + it('emits to the Logs Bridge API with `Logger(...)`', () => { + log = Logger({ name: 'test-logger-name', stream }); + log.info('foo'); + + const logRecords = memExporter.getFinishedLogRecords(); + assert.strictEqual(logRecords.length, 1); + let rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.body, 'foo'); + + const child = log.child({ aProperty: 'bar' }); + child.info('hi'); + rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.body, 'hi'); + assert.strictEqual(rec.attributes.aProperty, 'bar'); + }); }); describe('disabled instrumentation', () => { @@ -146,13 +337,14 @@ describe('BunyanInstrumentation', () => { stream = new Writable(); stream._write = () => {}; writeSpy = sinon.spy(stream, 'write'); - logger = Logger.createLogger({ name: 'test', stream }); + log = Logger.createLogger({ name: 'test', stream }); + memExporter.getFinishedLogRecords().length = 0; // clear }); it('does not inject span context', () => { const span = tracer.startSpan('abc'); context.with(trace.setSpan(context.active(), span), () => { - logger.info('foo'); + log.info('foo'); sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); assert.strictEqual(record['trace_id'], undefined); @@ -166,17 +358,23 @@ describe('BunyanInstrumentation', () => { it('does not call log hook', () => { const span = tracer.startSpan('abc'); instrumentation.setConfig({ - enabled: false, logHook: (_span, record) => { record['resource.service.name'] = 'test-service'; }, }); context.with(trace.setSpan(context.active(), span), () => { - logger.info('foo'); + log.info('foo'); sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); assert.strictEqual(record['resource.service.name'], undefined); }); }); + + it('does not emit to the Logs Bridge API', () => { + tracer.startActiveSpan('abc', span => { + log.info('foo'); + assert.strictEqual(memExporter.getFinishedLogRecords().length, 0); + }); + }); }); }); From 03c1c16c8749fd85e93c2639ff8a69a31a89c0f7 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Tue, 3 Oct 2023 11:09:40 -0700 Subject: [PATCH 02/30] markdown lint fixes --- .../opentelemetry-instrumentation-bunyan/examples/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md index 242770109b..a10ec1d747 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md @@ -4,7 +4,7 @@ This is a small example app, "app.js", that shows using the # Usage -``` +```bash npm install node -r ./telemetry.js app.js ``` @@ -18,7 +18,7 @@ analysis. An example run looks like this: -``` +```bash $ node -r ./telemetry.js app.js {"name":"myapp","hostname":"amachine.local","pid":93017,"level":20,"msg":"hi","time":"2023-09-27T23:24:06.074Z","v":0} { From 3fbfc0c1393a689e6cd34cb1edde44c7cd8cea81 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Tue, 3 Oct 2023 11:10:50 -0700 Subject: [PATCH 03/30] markdown lint fixes --- .../node/opentelemetry-instrumentation-bunyan/examples/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md index a10ec1d747..1e04258154 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md @@ -77,4 +77,3 @@ Bridge API. This means that if the OpenTelemetry SDK has been configured with a Logger Provider, it will receive them. (If the OpenTelemetry SDK is not configured for this, then the added Bunyan stream will be a no-op.) Lines 2 and 4 show a dumped OpenTelemetry Log Record. - From d5a92d18ba6a6a6af619bb9dcb38c085f832a75a Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Sun, 15 Oct 2023 12:03:40 -0700 Subject: [PATCH 04/30] catch up with recent core-deps update --- plugins/node/opentelemetry-instrumentation-bunyan/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/package.json b/plugins/node/opentelemetry-instrumentation-bunyan/package.json index 391a9be164..0d0dff3244 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/package.json +++ b/plugins/node/opentelemetry-instrumentation-bunyan/package.json @@ -49,7 +49,7 @@ "devDependencies": { "@opentelemetry/api": "^1.3.0", "@opentelemetry/resources": "^1.17.0", - "@opentelemetry/sdk-logs": "^0.43.0", + "@opentelemetry/sdk-logs": "^0.44.0", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", "@opentelemetry/semantic-conventions": "^1.17.0", From 5b9aecb9ab2b2296db54e1d71597f1f675328fe7 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Sun, 15 Oct 2023 12:04:02 -0700 Subject: [PATCH 05/30] some type tweaks suggested by David --- .../src/OpenTelemetryBunyanStream.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index 7d402bf3bf..1d33cfdd4c 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -16,7 +16,7 @@ import { logs, SeverityNumber, Logger } from '@opentelemetry/api-logs'; import type { LoggerOptions } from '@opentelemetry/api-logs'; -import type * as BunyanLogger from 'bunyan'; +import type { LogLevelString } from 'bunyan'; import { VERSION } from './version'; const DEFAULT_INSTRUMENTATION_SCOPE_NAME = 'io.opentelemetry.contrib.bunyan'; @@ -32,7 +32,7 @@ const INFO = 30; const WARN = 40; const ERROR = 50; const FATAL = 60; -const levelFromName: { [name in BunyanLogger.LogLevelString]: number } = { +const levelFromName: Record = { trace: TRACE, debug: DEBUG, info: INFO, @@ -42,7 +42,7 @@ const levelFromName: { [name in BunyanLogger.LogLevelString]: number } = { }; const nameFromLevel: { [level: number]: string } = {}; Object.keys(levelFromName).forEach(function (name) { - nameFromLevel[levelFromName[name as BunyanLogger.LogLevelString]] = name; + nameFromLevel[levelFromName[name as LogLevelString]] = name; }); const OTEL_SEV_NUM_FROM_BUNYAN_LEVEL: { [level: number]: number } = { From e3ed22c296d880dff1411244e434145caffc3539 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 14:03:02 -0800 Subject: [PATCH 06/30] more specific type Co-authored-by: Amir Blum --- .../src/OpenTelemetryBunyanStream.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index 1d33cfdd4c..293e6746ec 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -45,7 +45,7 @@ Object.keys(levelFromName).forEach(function (name) { nameFromLevel[levelFromName[name as LogLevelString]] = name; }); -const OTEL_SEV_NUM_FROM_BUNYAN_LEVEL: { [level: number]: number } = { +const OTEL_SEV_NUM_FROM_BUNYAN_LEVEL: { [level: number]: SeverityNumber } = { [TRACE]: SeverityNumber.TRACE, [DEBUG]: SeverityNumber.DEBUG, [INFO]: SeverityNumber.INFO, From bd507e2467c5e0cd37c7ffa202022235f669c380 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 14:35:22 -0800 Subject: [PATCH 07/30] use more self-explanatory code for mapping Bunyan level to OTel severity, from blumamir --- .../src/OpenTelemetryBunyanStream.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index 293e6746ec..9cb42b6ec1 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -84,14 +84,14 @@ function severityNumberFromBunyanLevel(lvl: number) { // Otherwise, scale the Bunyan level range -- 10 (TRACE) to 70 (FATAL+10) // -- onto the extra OTel severity numbers (TRACE2, TRACE3, ..., FATAL4). - // Values below bunyan.TRACE map to SeverityNumber.TRACE2, which is a bit - // weird. - return EXTRA_SEV_NUMS[ - Math.min( - EXTRA_SEV_NUMS.length - 1, - Math.max(0, Math.floor(((lvl - 10) / (70 - 10)) * EXTRA_SEV_NUMS.length)) - ) - ]; + // Values below bunyan.TRACE map to SeverityNumber.TRACE2, which may be + // considered a bit weird, but it means the unnumbered levels are always + // just for exactly values. + const relativeLevelWeight = (lvl - 10) / (70 - 10); + const otelSevIdx = Math.floor(relativeLevelWeight * EXTRA_SEV_NUMS.length); + const cappedOTelIdx = Math.min(EXTRA_SEV_NUMS.length - 1, Math.max(0, otelSevIdx)); + const otelSevValue = EXTRA_SEV_NUMS[cappedOTelIdx]; + return otelSevValue; } /** From 45f2b1d66567cea3b4dbb9f6a0ca154e960c8bf2 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 15:11:44 -0800 Subject: [PATCH 08/30] export OpenTelemetryBunyanStream for direct usage in Bunyan loggers without the instrumentation --- .../src/OpenTelemetryBunyanStream.ts | 5 +- .../src/index.ts | 1 + .../test/bunyan.test.ts | 83 ++++++++++++++++++- 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index 9cb42b6ec1..892ce3c123 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -89,7 +89,10 @@ function severityNumberFromBunyanLevel(lvl: number) { // just for exactly values. const relativeLevelWeight = (lvl - 10) / (70 - 10); const otelSevIdx = Math.floor(relativeLevelWeight * EXTRA_SEV_NUMS.length); - const cappedOTelIdx = Math.min(EXTRA_SEV_NUMS.length - 1, Math.max(0, otelSevIdx)); + const cappedOTelIdx = Math.min( + EXTRA_SEV_NUMS.length - 1, + Math.max(0, otelSevIdx) + ); const otelSevValue = EXTRA_SEV_NUMS[cappedOTelIdx]; return otelSevValue; } diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/index.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/index.ts index c26f998cff..2418a3b930 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/index.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/index.ts @@ -16,3 +16,4 @@ export * from './instrumentation'; export * from './types'; +export * from './OpenTelemetryBunyanStream'; diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index 1c3ade7b57..d809b300c0 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -33,7 +33,7 @@ import * as assert from 'assert'; import * as os from 'os'; import * as sinon from 'sinon'; import { Writable } from 'stream'; -import { BunyanInstrumentation } from '../src'; +import { BunyanInstrumentation, OpenTelemetryBunyanStream } from '../src'; import { VERSION } from '../src/version'; import type * as BunyanLogger from 'bunyan'; @@ -378,3 +378,84 @@ describe('BunyanInstrumentation', () => { }); }); }); + +describe('OpenTelemetryBunyanStream', () => { + before(() => { + instrumentation.disable(); + }); + + beforeEach(() => { + memExporter.getFinishedLogRecords().length = 0; // clear + }); + + it('can be used directly with createLogger', () => { + const log = Logger.createLogger({ + name: 'test-logger-name', + streams: [ + { + type: 'raw', + stream: new OpenTelemetryBunyanStream(), + level: 'debug', + }, + ], + }); + + // levels + log.trace('at trace level'); + log.debug('at debug level'); + log.info('at info level'); + log.warn('at warn level'); + log.error('at error level'); + log.fatal('at fatal level'); + const logRecords = memExporter.getFinishedLogRecords(); + assert.strictEqual(logRecords.length, 5); + assert.strictEqual(logRecords[0].severityNumber, SeverityNumber.DEBUG); + assert.strictEqual(logRecords[0].severityText, 'debug'); + assert.strictEqual(logRecords[1].severityNumber, SeverityNumber.INFO); + assert.strictEqual(logRecords[1].severityText, 'info'); + assert.strictEqual(logRecords[2].severityNumber, SeverityNumber.WARN); + assert.strictEqual(logRecords[2].severityText, 'warn'); + assert.strictEqual(logRecords[3].severityNumber, SeverityNumber.ERROR); + assert.strictEqual(logRecords[3].severityText, 'error'); + assert.strictEqual(logRecords[4].severityNumber, SeverityNumber.FATAL); + assert.strictEqual(logRecords[4].severityText, 'fatal'); + + // attributes, resource, instrumentationScope, etc. + log.info({ foo: 'bar' }, 'a message'); + const rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.body, 'a message'); + assert.deepStrictEqual(rec.attributes, { + name: 'test-logger-name', + hostname: os.hostname(), + pid: process.pid, + foo: 'bar', + }); + assert.strictEqual( + rec.resource.attributes['service.name'], + 'test-instrumentation-bunyan' + ); + assert.strictEqual( + rec.instrumentationScope.name, + 'io.opentelemetry.contrib.bunyan' + ); + assert.strictEqual(rec.instrumentationScope.version, VERSION); + assert.strictEqual(rec.spanContext, undefined); + + // spanContext + tracer.startActiveSpan('abc', span => { + const { traceId, spanId, traceFlags } = span.spanContext(); + log.info('in active span'); + const rec = logRecords[logRecords.length - 1]; + assert.strictEqual(rec.spanContext?.traceId, traceId); + assert.strictEqual(rec.spanContext?.spanId, spanId); + assert.strictEqual(rec.spanContext?.traceFlags, traceFlags); + + // This rec should *NOT* have the `trace_id` et al attributes. + assert.strictEqual(rec.attributes.trace_id, undefined); + assert.strictEqual(rec.attributes.span_id, undefined); + assert.strictEqual(rec.attributes.trace_flags, undefined); + + span.end(); + }); + }); +}); From 7d1532fbb32c67acdbdb9cfd1ffd7506938c6163 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 15:16:30 -0800 Subject: [PATCH 09/30] .apply over .call suggestion --- .../src/instrumentation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts index 003ff223a7..0a1084c7c8 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts @@ -68,10 +68,10 @@ export class BunyanInstrumentation extends InstrumentationBase< if (this instanceof LoggerTraced) { // called with `new Logger()` inst = this; - Logger.call(this, ...args); + Logger.apply(this, args); } else { // called without `new` - inst = Logger.call(null, ...args); + inst = Logger.apply(null, args); retval = inst; } // If `_childOptions` is defined, this is a `Logger#child(...)` From ed9ddafd182b7ef613a494696f2fa0437ac402ee Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 15:17:25 -0800 Subject: [PATCH 10/30] consistency suggestion --- .../opentelemetry-instrumentation-bunyan/src/instrumentation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts index 0a1084c7c8..9ed55d20e6 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts @@ -152,7 +152,7 @@ export class BunyanInstrumentation extends InstrumentationBase< } private _addStream(logger: any) { - const config: BunyanInstrumentationConfig = this._config; + const config: BunyanInstrumentationConfig = this.getConfig(); if (!this.isEnabled() || !config.enableLogsBridge) { return; } From 0f77516dac08e0ffc201ad5d90c4591559eea967 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 15:21:53 -0800 Subject: [PATCH 11/30] suggestion to use the longer (perhaps clearer) logger var name --- plugins/node/opentelemetry-instrumentation-bunyan/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/README.md index 1529493896..f8b797517e 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/README.md @@ -34,15 +34,15 @@ const sdk = new NodeSDK({ ] }) -const log = bunyan.createLogger({name: 'example'}); +const logger = bunyan.createLogger({name: 'example'}); -log.info('hi'); +logger.info('hi'); // 1. Log records will be sent to the SDK-registered log record processor, if any. // This is called "bridging". const tracer = api.getTracer('example'); tracer.startActiveSpan('manual-span', span => { - log.info('in a span'); + logger.info('in a span'); // 2. Fields identifying the current span will be injected into log records: // {"name":"example",...,"msg":"in a span","trace_id":"d61b4e4af1032e0aae279d12f3ab0159","span_id":"d140da862204f2a2","trace_flags":"01"} }) From 4c94dbac52856cdf40f8659f9b2ab70dfa71533d Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 15:50:16 -0800 Subject: [PATCH 12/30] switch to false-by-default config vars to avoid surprises with undefined values See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#boolean-value Suggestion from blumamir. --- .../README.md | 16 ++++++++-------- .../src/instrumentation.ts | 8 ++++---- .../src/types.ts | 16 ++++++++-------- .../test/bunyan.test.ts | 10 +++++----- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/README.md index f8b797517e..db4ab101f1 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/README.md @@ -17,7 +17,7 @@ npm install --save @opentelemetry/instrumentation-bunyan ## Supported Versions -- `^1.0.0` +- `bunyan@^1.0.0` ## Usage @@ -54,7 +54,7 @@ Creation of a Bunyan Logger will automatically add a [Bunyan stream](https://git If the OpenTelemetry SDK is not configured with a Logger provider, then this added stream will be a no-op. -The logs bridge can be disabled with the `enableLogsBridge: false` option. +The logs bridge can be disabled with the `disableLogsBridge: true` option. ### Log injection @@ -74,15 +74,15 @@ After adding these fields, the optional `logHook` is called to allow injecting a ``` When no span context is active or the span context is invalid, injection is skipped. -Log injection can be disabled with the `enableInjection: false` option. +Log injection can be disabled with the `disableInjection: true` option. ### Bunyan instrumentation options -| Option | Type | Description | -| ------------------ | ----------------- | ----------- | -| `enableLogsBridge` | `boolean` | Whether [logs bridging](#logs-bridge) is enabled. Default `true`. | -| `enableInjection` | `boolean` | Whether [log injection](#log-injection) is enabled. Default `true`. | -| `logHook` | `LogHookFunction` | An option hook to inject additional context to a log record after span context has been added. This requires `enableInjection` to be true. | +| Option | Type | Description | +| ------------------- | ----------------- | ----------- | +| `disableLogsBridge` | `boolean` | Whether to disable [logs bridging](#logs-bridge). Default `false`. | +| `disableInjection` | `boolean` | Whether to disable [log injection](#log-injection). Default `false`. | +| `logHook` | `LogHookFunction` | An option hook to inject additional context to a log record after span context has been added. This requires `disableInjection` to be false. | ## Useful links diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts index 9ed55d20e6..5a3e96073c 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts @@ -27,8 +27,8 @@ import { OpenTelemetryBunyanStream } from './OpenTelemetryBunyanStream'; import type * as BunyanLogger from 'bunyan'; const DEFAULT_CONFIG: BunyanInstrumentationConfig = { - enableLogsBridge: true, - enableInjection: true, + disableLogsBridge: false, + disableInjection: false, }; export class BunyanInstrumentation extends InstrumentationBase< @@ -114,7 +114,7 @@ export class BunyanInstrumentation extends InstrumentationBase< const instrumentation = this; return function patchedEmit(this: BunyanLogger, ...args: unknown[]) { const config = instrumentation.getConfig(); - if (!instrumentation.isEnabled() || !config.enableInjection) { + if (!instrumentation.isEnabled() || config.disableInjection) { return original.apply(this, args); } @@ -153,7 +153,7 @@ export class BunyanInstrumentation extends InstrumentationBase< private _addStream(logger: any) { const config: BunyanInstrumentationConfig = this.getConfig(); - if (!this.isEnabled() || !config.enableLogsBridge) { + if (!this.isEnabled() || config.disableLogsBridge) { return; } this._diag.debug('Adding OpenTelemetryBunyanStream to logger'); diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts index f6315f8737..7189177c55 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts @@ -22,23 +22,23 @@ export type LogHookFunction = (span: Span, record: Record) => void; export interface BunyanInstrumentationConfig extends InstrumentationConfig { /** - * Whether to enable the automatic sending of log records to the OpenTelemetry - * Logs Bridge API. - * @default true + * Whether to disable the automatic sending of log records to the + * OpenTelemetry Logs Bridge API. + * @default false */ - enableLogsBridge?: boolean; + disableLogsBridge?: boolean; /** - * Whether to enable the injection of data such as trace-context fields into + * Whether to disable the injection of data such as trace-context fields into * log output. - * @default true + * @default false */ - enableInjection?: boolean; + disableInjection?: boolean; /** * A function that allows injecting additional fields in log records. It is * called, as `logHook(span, record)`, for each log record emitted in a valid - * span context. It requires `enableInjection` to be true. + * span context. It requires `disableInjection` to be false. */ logHook?: LogHookFunction; } diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index d809b300c0..461d662d23 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -157,9 +157,9 @@ describe('BunyanInstrumentation', () => { }); }); - it('does not inject or call logHook if enableInjection=false', () => { + it('does not inject or call logHook if disableInjection=true', () => { instrumentation.setConfig({ - enableInjection: false, + disableInjection: true, logHook: (_span, record) => { record['resource.service.name'] = 'test-service'; }, @@ -268,10 +268,10 @@ describe('BunyanInstrumentation', () => { assert.strictEqual(rec.severityText, undefined); }); - it('does not emit to the Logs Bridge API if enableLogsBridge=false', () => { - instrumentation.setConfig({ enableLogsBridge: false }); + it('does not emit to the Logs Bridge API if disableLogsBridge=true', () => { + instrumentation.setConfig({ disableLogsBridge: true }); - // Changing `enableLogsBridge` only has an impact on Loggers created + // Changing `disableLogsBridge` only has an impact on Loggers created // *after* it is set. So we cannot test with the `log` created in // `beforeEach()` above. log = Logger.createLogger({ name: 'test-logger-name', stream }); From 21e3a55fa24efcf90169dd4fa1fd872b5a9cc3a5 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 15:57:11 -0800 Subject: [PATCH 13/30] document using OpenTelemetryBunyanStream without the instrumentation --- .../README.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/README.md index db4ab101f1..e91c19b7dc 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/README.md @@ -84,6 +84,33 @@ Log injection can be disabled with the `disableInjection: true` option. | `disableInjection` | `boolean` | Whether to disable [log injection](#log-injection). Default `false`. | | `logHook` | `LogHookFunction` | An option hook to inject additional context to a log record after span context has been added. This requires `disableInjection` to be false. | +### Using OpenTelemetryBunyanStream without instrumentation + +This package exports the Bunyan stream class that is used to bridge to the +OpenTelemetry Logs Bridge API. It can be used directly when configuring a +Bunyan logger if one is not using the `BunyanInstrumentation` for whatever +reason. For example: + +```js +const { OpenTelemetryBunyanStream } = require('@opentelemetry/instrumentation-bunyan'); +const bunyan = require('bunyan'); + +// You must register an OpenTelemetry LoggerProvider, otherwise log records will +// be sent to a no-op implementation. "examples/telemetry.js" shows one way +// to configure one. +// ... + +const logger = bunyan.createLogger({ + name: 'my-logger', + streams: [ + { + type: 'raw', + stream: new OpenTelemetryBunyanStream() + } + ], +}); +``` + ## Useful links - For more information on OpenTelemetry, visit: From 44d20bde237805f5c7870ceaec335b5ee0e3e05b Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 8 Nov 2023 16:19:07 -0800 Subject: [PATCH 14/30] fix https://eslint.org/docs/latest/rules/prefer-spread lint error --- .../opentelemetry-instrumentation-bunyan/src/instrumentation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts index 5a3e96073c..8fd0d5bc04 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts @@ -71,7 +71,7 @@ export class BunyanInstrumentation extends InstrumentationBase< Logger.apply(this, args); } else { // called without `new` - inst = Logger.apply(null, args); + inst = Logger(...args); retval = inst; } // If `_childOptions` is defined, this is a `Logger#child(...)` From 751f95a27e8003e206e756d39d841289b65cb25b Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 08:12:59 -0800 Subject: [PATCH 15/30] drop options to OpenTelemetryBunyanStream constructor because YAGNI --- .../src/OpenTelemetryBunyanStream.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index 892ce3c123..bf49ae9131 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -15,7 +15,6 @@ */ import { logs, SeverityNumber, Logger } from '@opentelemetry/api-logs'; -import type { LoggerOptions } from '@opentelemetry/api-logs'; import type { LogLevelString } from 'bunyan'; import { VERSION } from './version'; @@ -103,11 +102,10 @@ function severityNumberFromBunyanLevel(lvl: number) { export class OpenTelemetryBunyanStream { private _otelLogger: Logger; - constructor(name?: string, version?: string, options?: LoggerOptions) { + constructor() { this._otelLogger = logs.getLogger( - name || DEFAULT_INSTRUMENTATION_SCOPE_NAME, - version || DEFAULT_INSTRUMENTATION_SCOPE_VERSION, - options + DEFAULT_INSTRUMENTATION_SCOPE_NAME, + DEFAULT_INSTRUMENTATION_SCOPE_VERSION ); } From 2f0a89a6c1fc825c81293dfe2b8c6f72ec389df8 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 08:49:59 -0800 Subject: [PATCH 16/30] temporarily drop CI caching to test theory on unit-test (18) CI failure --- .github/workflows/unit-test.yml | 39 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 2e82c88a96..72e96e664a 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -123,25 +123,26 @@ jobs: node-version: ${{ matrix.node }} - name: Set MySQL variables run: mysql --user=root --password=${MYSQL_ROOT_PASSWORD} --host=${MYSQL_HOST} --port=${MYSQL_PORT} -e "SET GLOBAL log_output='TABLE'; SET GLOBAL general_log = 1;" mysql - - name: Cache Dependencies - uses: actions/cache@v3 - with: - path: | - node_modules - package-lock.json - detectors/node/*/node_modules - detectors/node/*/package-lock.json - metapackages/*/node_modules - metapackages/*/package-lock.json - packages/*/node_modules - packages/*/package-lock.json - plugins/node/*/node_modules - plugins/node/*/package-lock.json - plugins/web/*/node_modules - plugins/web/*/package-lock.json - propagators/*/node_modules - propagators/*/package-lock.json - key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('package.json', 'detectors/node/*/package.json', 'metapackages/*/package.json', 'packages/*/package.json', 'plugins/node/*/package.json', 'plugins/web/*/package.json', 'propagators/*/package.json') }} + # XXX test https://github.com/open-telemetry/opentelemetry-js-contrib/pull/1713#issuecomment-1802982371 theory for unit-test (18) failure + # - name: Cache Dependencies + # uses: actions/cache@v3 + # with: + # path: | + # node_modules + # package-lock.json + # detectors/node/*/node_modules + # detectors/node/*/package-lock.json + # metapackages/*/node_modules + # metapackages/*/package-lock.json + # packages/*/node_modules + # packages/*/package-lock.json + # plugins/node/*/node_modules + # plugins/node/*/package-lock.json + # plugins/web/*/node_modules + # plugins/web/*/package-lock.json + # propagators/*/node_modules + # propagators/*/package-lock.json + # key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('package.json', 'detectors/node/*/package.json', 'metapackages/*/package.json', 'packages/*/package.json', 'plugins/node/*/package.json', 'plugins/web/*/package.json', 'propagators/*/package.json') }} - name: Legacy Peer Dependencies for npm 7 if: matrix.node == '16' run: npm config set legacy-peer-deps=true From c283178c054abe418cc6a6dea35940d1dc1d0480 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 11:02:47 -0800 Subject: [PATCH 17/30] more CI debugging: restore cache, add some 'npm ls -a' to look into NoopContextManager being used --- .github/workflows/unit-test.yml | 44 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 72e96e664a..9546a2062c 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -123,26 +123,25 @@ jobs: node-version: ${{ matrix.node }} - name: Set MySQL variables run: mysql --user=root --password=${MYSQL_ROOT_PASSWORD} --host=${MYSQL_HOST} --port=${MYSQL_PORT} -e "SET GLOBAL log_output='TABLE'; SET GLOBAL general_log = 1;" mysql - # XXX test https://github.com/open-telemetry/opentelemetry-js-contrib/pull/1713#issuecomment-1802982371 theory for unit-test (18) failure - # - name: Cache Dependencies - # uses: actions/cache@v3 - # with: - # path: | - # node_modules - # package-lock.json - # detectors/node/*/node_modules - # detectors/node/*/package-lock.json - # metapackages/*/node_modules - # metapackages/*/package-lock.json - # packages/*/node_modules - # packages/*/package-lock.json - # plugins/node/*/node_modules - # plugins/node/*/package-lock.json - # plugins/web/*/node_modules - # plugins/web/*/package-lock.json - # propagators/*/node_modules - # propagators/*/package-lock.json - # key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('package.json', 'detectors/node/*/package.json', 'metapackages/*/package.json', 'packages/*/package.json', 'plugins/node/*/package.json', 'plugins/web/*/package.json', 'propagators/*/package.json') }} + - name: Cache Dependencies + uses: actions/cache@v3 + with: + path: | + node_modules + package-lock.json + detectors/node/*/node_modules + detectors/node/*/package-lock.json + metapackages/*/node_modules + metapackages/*/package-lock.json + packages/*/node_modules + packages/*/package-lock.json + plugins/node/*/node_modules + plugins/node/*/package-lock.json + plugins/web/*/node_modules + plugins/web/*/package-lock.json + propagators/*/node_modules + propagators/*/package-lock.json + key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('package.json', 'detectors/node/*/package.json', 'metapackages/*/package.json', 'packages/*/package.json', 'plugins/node/*/package.json', 'plugins/web/*/package.json', 'propagators/*/package.json') }} - name: Legacy Peer Dependencies for npm 7 if: matrix.node == '16' run: npm config set legacy-peer-deps=true @@ -150,6 +149,11 @@ jobs: run: npm install --ignore-scripts - name: Bootstrap Dependencies run: npx lerna bootstrap --no-ci --hoist --nohoist='zone.js' --nohoist='mocha' --nohoist='ts-mocha' + + # XXX Some debugging of the unit-test (18) failure + - run: npm ls -a + - run: npx lerna exec --scope @opentelemetry/instrumentation-bunyan -- npm ls -a + - name: Unit tests (Full) if: matrix.code-coverage run: npm run test -- ${{ matrix.lerna-extra-args }} From 3638f7212b901b235c3445e78334bc433e9e1671 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 12:12:50 -0800 Subject: [PATCH 18/30] elide Bunyan 'pid' and 'hostname' fields in OTel log record attributes Because they are redundant with 'process.pid' and 'host.name' resource attributes. Add some docs on how to use resource detectors to the example, because the HostDetector is not on by default in the NodeSDK. --- .../README.md | 3 +- .../examples/README.md | 56 +++++++++++++++---- .../examples/app.js | 2 +- .../examples/app.mjs | 2 +- .../examples/package.json | 5 +- .../examples/telemetry.js | 13 ++++- .../package.json | 2 +- .../src/OpenTelemetryBunyanStream.ts | 30 +++++++--- 8 files changed, 88 insertions(+), 25 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/README.md index e91c19b7dc..a273e053a6 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/README.md @@ -34,13 +34,14 @@ const sdk = new NodeSDK({ ] }) +const bunyan = require('bunyan'); const logger = bunyan.createLogger({name: 'example'}); logger.info('hi'); // 1. Log records will be sent to the SDK-registered log record processor, if any. // This is called "bridging". -const tracer = api.getTracer('example'); +const tracer = api.trace.getTracer('example'); tracer.startActiveSpan('manual-span', span => { logger.info('in a span'); // 2. Fields identifying the current span will be injected into log records: diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md index 1e04258154..8e93a16fa2 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md @@ -29,7 +29,7 @@ $ node -r ./telemetry.js app.js severityText: 'debug', severityNumber: 5, body: 'hi', - attributes: { name: 'myapp', hostname: 'amachine.local', pid: 93017 } + attributes: { name: 'myapp', foo: 'bar' } } {"name":"myapp","hostname":"amachine.local","pid":93017,"level":30,"msg":"this record will have trace_id et al fields for the current span","time":"2023-09-27T23:24:06.079Z","v":0,"trace_id":"af5ce23816c4feabb713ee1dc84ef4d3","span_id":"5f50e181ec7bc621","trace_flags":"01"} { @@ -42,8 +42,6 @@ $ node -r ./telemetry.js app.js body: 'this record will have trace_id et al fields for the current span', attributes: { name: 'myapp', - hostname: 'amachine.local', - pid: 93017, trace_id: 'af5ce23816c4feabb713ee1dc84ef4d3', span_id: '5f50e181ec7bc621', trace_flags: '01' @@ -65,15 +63,53 @@ $ node -r ./telemetry.js app.js } ``` -There are two separate Bunyan instrumentation functionalities. The first is -that Bunyan log records emitted in the context of a tracing span will include -`trace_id` and `span_id` fields that can be used for correlating with collect -tracing data. Line 3 shows an example of this. +There are two separate Bunyan instrumentation functionalities. The first, called +"log injection", is that Bunyan log records emitted in the context of a tracing +span will include `trace_id` and `span_id` fields that can be used for +correlating with collected tracing data. -The second is that a [Bunyan +The second, called "logs bridging", is that a [Bunyan stream](https://github.com/trentm/node-bunyan#streams) is automatically added to created Loggers that will send every log record to the OpenTelemetry Logs Bridge API. This means that if the OpenTelemetry SDK has been configured with a Logger Provider, it will receive them. (If the OpenTelemetry SDK is not -configured for this, then the added Bunyan stream will be a no-op.) Lines 2 -and 4 show a dumped OpenTelemetry Log Record. +configured for this, then the added Bunyan stream will be a no-op.) + + +# Resource attributes + +One thing the `ConsoleLogRecordExporter` output above does not show is some +additional data that is included in exported log records: resource attributes. + +Every OpenTelemetry LoggerProvider has a "resource". The OpenTelemetry SDK +provides configurable "resource detectors" that collect data that is then +included with log records. This can include "host.name" (provided by the +`HostDetector`) and "process.pid" (provided by the `ProcessDetector`) -- which +is why this instrumentation does **not** include the Bunyan "hostname" and "pid" +fields in the log record attributes. + +When configured with the `HostDetector` and `ProcessDetector` (as shown in +"telemetry.js") the log records above also include resource attributes such +as the following: + +```js +{ + 'process.pid': 93017, + 'process.executable.name': 'node', + 'process.executable.path': '/Users/trentm/.nvm/versions/node/v18.18.2/bin/node', + 'process.command_args': [ + '/Users/trentm/.nvm/versions/node/v18.18.2/bin/node', + '-r', + './telemetry.js', + '/Users/trentm/src/opentelemetry-js-contrib/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js' + ], + 'process.runtime.version': '18.18.2', + 'process.runtime.name': 'nodejs', + 'process.runtime.description': 'Node.js', + 'process.command': '/Users/trentm/src/opentelemetry-js-contrib/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js', + 'process.owner': 'trentm' + 'host.name': 'amachine.local', + 'host.arch': 'amd64', + 'host.id': '...' +} +``` diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js index 98bcad9fc6..05214a8073 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.js @@ -23,7 +23,7 @@ const bunyan = require('bunyan'); const log = bunyan.createLogger({name: 'myapp', level: 'debug'}); -log.debug('hi'); +log.debug({foo: 'bar'}, 'hi'); const tracer = otel.trace.getTracer('example'); tracer.startActiveSpan('manual-span', span => { diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs index a4dbc339a1..c20d5ff05b 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/app.mjs @@ -23,7 +23,7 @@ import bunyan from 'bunyan'; const log = bunyan.createLogger({name: 'myapp', level: 'debug'}); -log.debug('hi'); +log.debug({foo: 'bar'}, 'hi'); const tracer = trace.getTracer('example'); tracer.startActiveSpan('manual-span', span => { diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json b/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json index d7947e0ee1..812c6a2242 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json @@ -1,7 +1,7 @@ { "name": "bunyan-example", "private": true, - "version": "0.43.0", + "version": "0.45.1", "description": "Example of Bunyan integration with OpenTelemetry", "scripts": { "start": "node -r ./telemetry.js app.js" @@ -19,7 +19,8 @@ "dependencies": { "@opentelemetry/api": "^1.6.0", "@opentelemetry/instrumentation-bunyan": "../", - "@opentelemetry/sdk-node": "^0.43.0", + "@opentelemetry/resources": "^1.17.0", + "@opentelemetry/sdk-node": "^0.44.0", "bunyan": "^1.8.15" } } diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js b/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js index 7f196869c8..7765944c70 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js @@ -21,12 +21,23 @@ // for viewing and analysis. const { NodeSDK, tracing, logs, api } = require('@opentelemetry/sdk-node'); -// api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG); +const { envDetectorSync, hostDetectorSync, processDetectorSync } = require('@opentelemetry/resources'); +api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG); const { BunyanInstrumentation } = require('@opentelemetry/instrumentation-bunyan'); const sdk = new NodeSDK({ serviceName: 'bunyan-example', + resourceDetectors: [ + envDetectorSync, + // ProcessDetector adds `process.pid` (among other resource attributes), + // which replaces the usual Bunyan `pid` field. + processDetectorSync, + // The HostDetector adds `host.name` and `host.arch` fields. `host.name` + // replaces the usual Bunyan `hostname` field. HostDetector is *not* a + // default detector of the `NodeSDK`. + hostDetectorSync + ], spanProcessor: new tracing.SimpleSpanProcessor(new tracing.ConsoleSpanExporter()), logRecordProcessor: new logs.SimpleLogRecordProcessor(new logs.ConsoleLogRecordExporter()), instrumentations: [ diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/package.json b/plugins/node/opentelemetry-instrumentation-bunyan/package.json index 33749b8295..5c0e0c6aa1 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/package.json +++ b/plugins/node/opentelemetry-instrumentation-bunyan/package.json @@ -52,7 +52,7 @@ "@opentelemetry/sdk-logs": "^0.44.0", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", - "@opentelemetry/semantic-conventions": "^1.17.0", + "@opentelemetry/semantic-conventions": "^1.0.0", "@types/mocha": "7.0.2", "@types/node": "18.6.5", "@types/sinon": "10.0.18", diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index bf49ae9131..fb105fb34f 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -116,19 +116,33 @@ export class OpenTelemetryBunyanStream { * Dev Notes: * - We drop the Bunyan 'v' field. It is meant to indicate the format * of the Bunyan log record. FWIW, it has always been `0`. - * - Some Bunyan fields would naturally map to Resource attributes: - * hostname -> host.name - * name -> service.name - * pid -> process.pid - * However, AFAIK there isn't a way to influence the LoggerProvider's - * `resource` from here. + * - The standard Bunyan `hostname` and `pid` fields are removed because they + * are redundant with the OpenTelemetry `host.name` and `process.pid` + * Resource attributes, respectively. This code cannot change the + * LoggerProvider's `resource`, so getting the OpenTelemetry equivalents + * depends on the user using relevant OpenTelemetry resource detectors. + * "examples/telemetry.js" shows using HostDetector and ProcessDetector for + * this. + * - The Bunyan `name` field *could* naturally map to OpenTelemetry's + * `service.name` resource attribute. However, that is debatable, as some + * users might use `name` more like a log4j logger name. * - Strip the `trace_id` et al fields that may have been added by the * the _emit wrapper. */ write(rec: Record) { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { time, level, msg, v, trace_id, span_id, trace_flags, ...fields } = - rec; + const { + time, + level, + msg, + v, + hostname, + pid, + trace_id, + span_id, + trace_flags, + ...fields + } = rec; let timestamp = undefined; if (typeof time.getTime === 'function') { timestamp = time.getTime(); // ms From 303b6abaa8329db3058c830ec07cd1ba9d626472 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 12:13:43 -0800 Subject: [PATCH 19/30] update test for having elided 'pid' and 'hostname' fields --- .../opentelemetry-instrumentation-bunyan/test/bunyan.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index 461d662d23..72aa8c9b9f 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -210,8 +210,6 @@ describe('BunyanInstrumentation', () => { assert.strictEqual(rec.body, 'a message'); assert.deepStrictEqual(rec.attributes, { name: 'test-logger-name', - hostname: os.hostname(), - pid: process.pid, foo: 'bar', }); assert.strictEqual( @@ -426,8 +424,6 @@ describe('OpenTelemetryBunyanStream', () => { assert.strictEqual(rec.body, 'a message'); assert.deepStrictEqual(rec.attributes, { name: 'test-logger-name', - hostname: os.hostname(), - pid: process.pid, foo: 'bar', }); assert.strictEqual( From 018118ea1cab068c06fe7f1225e2aaacd0c80e2d Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 12:15:52 -0800 Subject: [PATCH 20/30] CI debugging: ignore the 'npm ls -a' exit status, they shouldn't break the build --- .github/workflows/unit-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 9546a2062c..60f03ff1d2 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -151,8 +151,8 @@ jobs: run: npx lerna bootstrap --no-ci --hoist --nohoist='zone.js' --nohoist='mocha' --nohoist='ts-mocha' # XXX Some debugging of the unit-test (18) failure - - run: npm ls -a - - run: npx lerna exec --scope @opentelemetry/instrumentation-bunyan -- npm ls -a + - run: npm ls -a || true + - run: npx lerna exec --scope @opentelemetry/instrumentation-bunyan -- npm ls -a || true - name: Unit tests (Full) if: matrix.code-coverage From 284e4d62038b3168a4a13fc82c988ab8c25b26f7 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 12:39:27 -0800 Subject: [PATCH 21/30] fix lint and compile errors --- .../node/opentelemetry-instrumentation-bunyan/examples/README.md | 1 - .../opentelemetry-instrumentation-bunyan/test/bunyan.test.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md index 8e93a16fa2..49338b7e39 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md @@ -75,7 +75,6 @@ Bridge API. This means that if the OpenTelemetry SDK has been configured with a Logger Provider, it will receive them. (If the OpenTelemetry SDK is not configured for this, then the added Bunyan stream will be a no-op.) - # Resource attributes One thing the `ConsoleLogRecordExporter` output above does not show is some diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index 72aa8c9b9f..42fb7d06fc 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -30,7 +30,6 @@ import { isWrapped } from '@opentelemetry/instrumentation'; import { Resource } from '@opentelemetry/resources'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import * as assert from 'assert'; -import * as os from 'os'; import * as sinon from 'sinon'; import { Writable } from 'stream'; import { BunyanInstrumentation, OpenTelemetryBunyanStream } from '../src'; From 7fc08424d8cb4b3d33ffcbfb4d6ca7b8950b9f43 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 9 Nov 2023 19:26:56 -0800 Subject: [PATCH 22/30] CI debugging: turn on diag DEBUG to test a theory --- .../opentelemetry-instrumentation-bunyan/test/bunyan.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index 42fb7d06fc..c0e116c164 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -37,8 +37,9 @@ import { VERSION } from '../src/version'; import type * as BunyanLogger from 'bunyan'; -// import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'; -// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); +// XXX +import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'; +diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); const tracerProvider = new NodeTracerProvider(); tracerProvider.register(); From 54d247769a4e568672252ae84b782a3b71a0c11f Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Fri, 10 Nov 2023 16:52:35 -0800 Subject: [PATCH 23/30] turn off diag in this example --- .../opentelemetry-instrumentation-bunyan/examples/telemetry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js b/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js index 7765944c70..20f84ee7d1 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/telemetry.js @@ -22,7 +22,7 @@ const { NodeSDK, tracing, logs, api } = require('@opentelemetry/sdk-node'); const { envDetectorSync, hostDetectorSync, processDetectorSync } = require('@opentelemetry/resources'); -api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG); +// api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG); const { BunyanInstrumentation } = require('@opentelemetry/instrumentation-bunyan'); From 6de5de18079d25d80fee353b2ced66f13b14f3c2 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Fri, 10 Nov 2023 16:53:29 -0800 Subject: [PATCH 24/30] undo CI debugging changes --- .github/workflows/unit-test.yml | 5 ----- .../opentelemetry-instrumentation-bunyan/test/bunyan.test.ts | 5 ++--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 60f03ff1d2..2e82c88a96 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -149,11 +149,6 @@ jobs: run: npm install --ignore-scripts - name: Bootstrap Dependencies run: npx lerna bootstrap --no-ci --hoist --nohoist='zone.js' --nohoist='mocha' --nohoist='ts-mocha' - - # XXX Some debugging of the unit-test (18) failure - - run: npm ls -a || true - - run: npx lerna exec --scope @opentelemetry/instrumentation-bunyan -- npm ls -a || true - - name: Unit tests (Full) if: matrix.code-coverage run: npm run test -- ${{ matrix.lerna-extra-args }} diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index c0e116c164..42fb7d06fc 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -37,9 +37,8 @@ import { VERSION } from '../src/version'; import type * as BunyanLogger from 'bunyan'; -// XXX -import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'; -diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); +// import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'; +// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); const tracerProvider = new NodeTracerProvider(); tracerProvider.register(); From f3c4d03dbc69c2c524d0e98a6816ba44739e701f Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Tue, 21 Nov 2023 07:00:32 -0800 Subject: [PATCH 25/30] update deps to current releases and sync package-lock.json --- package-lock.json | 92 +++++++++++-------- .../examples/package.json | 6 +- .../package.json | 4 +- 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/package-lock.json b/package-lock.json index 63901e9215..0c01a7cc17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12012,7 +12012,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "devOptional": true }, "node_modules/base": { "version": "0.11.2", @@ -12332,7 +12332,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "devOptional": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -12561,7 +12561,6 @@ "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", - "dev": true, "engines": [ "node >=0.10.0" ], @@ -12575,6 +12574,10 @@ "safe-json-stringify": "~1" } }, + "node_modules/bunyan-example": { + "resolved": "plugins/node/opentelemetry-instrumentation-bunyan/examples", + "link": true + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -13490,7 +13493,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "devOptional": true }, "node_modules/concat-stream": { "version": "2.0.0", @@ -14518,7 +14521,6 @@ "version": "0.8.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "dev": true, "hasInstallScript": true, "optional": true, "dependencies": { @@ -18251,7 +18253,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, + "devOptional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -22651,7 +22653,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "devOptional": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -23494,7 +23496,6 @@ "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", - "dev": true, "optional": true, "engines": { "node": "*" @@ -23865,7 +23866,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", - "dev": true, "optional": true, "dependencies": { "mkdirp": "~0.5.1", @@ -23880,7 +23880,6 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", - "dev": true, "optional": true, "dependencies": { "inflight": "^1.0.4", @@ -23897,7 +23896,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "optional": true, "dependencies": { "minimist": "^1.2.6" @@ -23910,7 +23908,6 @@ "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", - "dev": true, "optional": true, "dependencies": { "glob": "^6.0.1" @@ -24069,7 +24066,7 @@ "version": "2.18.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", - "dev": true + "devOptional": true }, "node_modules/nanomatch": { "version": "1.2.13", @@ -24160,7 +24157,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", - "dev": true, "optional": true, "bin": { "ncp": "bin/ncp" @@ -25868,7 +25864,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, + "devOptional": true, "dependencies": { "wrappy": "1" } @@ -26747,7 +26743,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -28848,7 +28844,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", - "dev": true, "optional": true }, "node_modules/safe-regex": { @@ -33787,7 +33782,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "devOptional": true }, "node_modules/write-file-atomic": { "version": "4.0.1", @@ -35146,14 +35141,17 @@ "version": "0.33.0", "license": "Apache-2.0", "dependencies": { + "@opentelemetry/api-logs": "^0.45.1", "@opentelemetry/instrumentation": "^0.45.1", "@types/bunyan": "1.8.9" }, "devDependencies": { "@opentelemetry/api": "^1.3.0", - "@opentelemetry/context-async-hooks": "^1.8.0", + "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/sdk-logs": "^0.45.1", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", + "@opentelemetry/semantic-conventions": "^1.0.0", "@types/mocha": "7.0.2", "@types/node": "18.6.5", "@types/sinon": "10.0.18", @@ -35173,6 +35171,20 @@ "@opentelemetry/api": "^1.3.0" } }, + "plugins/node/opentelemetry-instrumentation-bunyan/examples": { + "version": "0.45.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0", + "@opentelemetry/instrumentation-bunyan": "../", + "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/sdk-node": "^0.45.1", + "bunyan": "^1.8.15" + }, + "engines": { + "node": ">=14" + } + }, "plugins/node/opentelemetry-instrumentation-bunyan/node_modules/@types/mocha": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", @@ -44108,10 +44120,13 @@ "version": "file:plugins/node/opentelemetry-instrumentation-bunyan", "requires": { "@opentelemetry/api": "^1.3.0", - "@opentelemetry/context-async-hooks": "^1.8.0", + "@opentelemetry/api-logs": "^0.45.1", "@opentelemetry/instrumentation": "^0.45.1", + "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/sdk-logs": "^0.45.1", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", + "@opentelemetry/semantic-conventions": "^1.0.0", "@types/bunyan": "1.8.9", "@types/mocha": "7.0.2", "@types/node": "18.6.5", @@ -49038,7 +49053,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "devOptional": true }, "base": { "version": "0.11.2", @@ -49308,7 +49323,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "devOptional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -49504,7 +49519,6 @@ "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", - "dev": true, "requires": { "dtrace-provider": "~0.8", "moment": "^2.19.3", @@ -49512,6 +49526,16 @@ "safe-json-stringify": "~1" } }, + "bunyan-example": { + "version": "file:plugins/node/opentelemetry-instrumentation-bunyan/examples", + "requires": { + "@opentelemetry/api": "^1.3.0", + "@opentelemetry/instrumentation-bunyan": "../", + "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/sdk-node": "^0.45.1", + "bunyan": "^1.8.15" + } + }, "busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -50204,7 +50228,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "devOptional": true }, "concat-stream": { "version": "2.0.0", @@ -51030,7 +51054,6 @@ "version": "0.8.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "dev": true, "optional": true, "requires": { "nan": "^2.14.0" @@ -54068,7 +54091,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, + "devOptional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -57565,7 +57588,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, + "devOptional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -58253,7 +58276,6 @@ "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", - "dev": true, "optional": true }, "mongodb": { @@ -58550,7 +58572,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", - "dev": true, "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -58562,7 +58583,6 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", - "dev": true, "optional": true, "requires": { "inflight": "^1.0.4", @@ -58576,7 +58596,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "optional": true, "requires": { "minimist": "^1.2.6" @@ -58586,7 +58605,6 @@ "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", - "dev": true, "optional": true, "requires": { "glob": "^6.0.1" @@ -58755,7 +58773,7 @@ "version": "2.18.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", - "dev": true + "devOptional": true }, "nanomatch": { "version": "1.2.13", @@ -58833,7 +58851,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", - "dev": true, "optional": true }, "negotiator": { @@ -60206,7 +60223,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, + "devOptional": true, "requires": { "wrappy": "1" } @@ -60878,7 +60895,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "devOptional": true }, "path-key": { "version": "3.1.1", @@ -62497,7 +62514,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", - "dev": true, "optional": true }, "safe-regex": { @@ -66430,7 +66446,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "devOptional": true }, "write-file-atomic": { "version": "4.0.1", diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json b/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json index 812c6a2242..ccd208cd8c 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/package.json @@ -17,10 +17,10 @@ "license": "Apache-2.0", "// @opentelemetry/instrumentation-bunyan": "TODO: change to a ver when there is a next release", "dependencies": { - "@opentelemetry/api": "^1.6.0", + "@opentelemetry/api": "^1.3.0", "@opentelemetry/instrumentation-bunyan": "../", - "@opentelemetry/resources": "^1.17.0", - "@opentelemetry/sdk-node": "^0.44.0", + "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/sdk-node": "^0.45.1", "bunyan": "^1.8.15" } } diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/package.json b/plugins/node/opentelemetry-instrumentation-bunyan/package.json index 3da5bce0c6..52a2ed161a 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/package.json +++ b/plugins/node/opentelemetry-instrumentation-bunyan/package.json @@ -45,8 +45,8 @@ }, "devDependencies": { "@opentelemetry/api": "^1.3.0", - "@opentelemetry/resources": "^1.17.0", - "@opentelemetry/sdk-logs": "^0.44.0", + "@opentelemetry/resources": "^1.8.0", + "@opentelemetry/sdk-logs": "^0.45.1", "@opentelemetry/sdk-trace-base": "^1.8.0", "@opentelemetry/sdk-trace-node": "^1.8.0", "@opentelemetry/semantic-conventions": "^1.0.0", From c740b767e2bb3ef3950d1e97b39f2034294dff05 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 22 Nov 2023 12:33:12 -0800 Subject: [PATCH 26/30] disableInjection -> disableLogCorrelation --- .../README.md | 26 +++++++++++-------- .../examples/README.md | 4 +-- .../src/instrumentation.ts | 4 +-- .../src/types.ts | 8 +++--- .../test/bunyan.test.ts | 6 ++--- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/README.md index a273e053a6..6c34e1f3c5 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/README.md @@ -3,7 +3,7 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] -This module provides automatic instrumentation of the [`bunyan`](https://www.npmjs.com/package/bunyan) module to inject trace-context into Bunyan log records and to bridge Bunyan logging to the OpenTelemetry Logging SDK. It may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle. +This module provides automatic instrumentation of the [`bunyan`](https://www.npmjs.com/package/bunyan) module to inject trace-context into Bunyan log records (Log correlation) and to bridge Bunyan logging to the OpenTelemetry Logging SDK. It may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle. If total installation size is not constrained, it is recommended to use the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle with [@opentelemetry/sdk-node](`https://www.npmjs.com/package/@opentelemetry/sdk-node`) for the most seamless instrumentation experience. @@ -44,8 +44,9 @@ logger.info('hi'); const tracer = api.trace.getTracer('example'); tracer.startActiveSpan('manual-span', span => { logger.info('in a span'); - // 2. Fields identifying the current span will be injected into log records: + // 2. Fields identifying the current span will be added to log records: // {"name":"example",...,"msg":"in a span","trace_id":"d61b4e4af1032e0aae279d12f3ab0159","span_id":"d140da862204f2a2","trace_flags":"01"} + // This is called "log correlation". }) ``` @@ -57,10 +58,13 @@ If the OpenTelemetry SDK is not configured with a Logger provider, then this add The logs bridge can be disabled with the `disableLogsBridge: true` option. -### Log injection +### Log correlation -Bunyan logger calls in the context of a tracing span will have fields indentifying -the span ([spec](https://opentelemetry.io/docs/specs/otel/compatibility/logging_trace_context/)): +Bunyan logger calls in the context of a tracing span will have fields +indentifying the span added to the log record. This allows +[correlating](https://opentelemetry.io/docs/specs/otel/logs/#log-correlation) +log records with tracing data. The added fields are +([spec](https://opentelemetry.io/docs/specs/otel/compatibility/logging_trace_context/)): - `trace_id` - `span_id` @@ -75,15 +79,15 @@ After adding these fields, the optional `logHook` is called to allow injecting a ``` When no span context is active or the span context is invalid, injection is skipped. -Log injection can be disabled with the `disableInjection: true` option. +Log injection can be disabled with the `disableLogCorrelation: true` option. ### Bunyan instrumentation options -| Option | Type | Description | -| ------------------- | ----------------- | ----------- | -| `disableLogsBridge` | `boolean` | Whether to disable [logs bridging](#logs-bridge). Default `false`. | -| `disableInjection` | `boolean` | Whether to disable [log injection](#log-injection). Default `false`. | -| `logHook` | `LogHookFunction` | An option hook to inject additional context to a log record after span context has been added. This requires `disableInjection` to be false. | +| Option | Type | Description | +| ----------------------- | ----------------- | ----------- | +| `disableLogsBridge` | `boolean` | Whether to disable [logs bridging](#logs-bridge). Default `false`. | +| `disableLogCorrelation` | `boolean` | Whether to disable [log correlation](#log-correlation). Default `false`. | +| `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. | ### Using OpenTelemetryBunyanStream without instrumentation diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md index 49338b7e39..7ccd066d18 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md @@ -63,8 +63,8 @@ $ node -r ./telemetry.js app.js } ``` -There are two separate Bunyan instrumentation functionalities. The first, called -"log injection", is that Bunyan log records emitted in the context of a tracing +There are two separate Bunyan instrumentation features. The first, called +"log correlation", is that Bunyan log records emitted in the context of a tracing span will include `trace_id` and `span_id` fields that can be used for correlating with collected tracing data. diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts index 8fd0d5bc04..ca060df7de 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts @@ -28,7 +28,7 @@ import type * as BunyanLogger from 'bunyan'; const DEFAULT_CONFIG: BunyanInstrumentationConfig = { disableLogsBridge: false, - disableInjection: false, + disableLogCorrelation: false, }; export class BunyanInstrumentation extends InstrumentationBase< @@ -114,7 +114,7 @@ export class BunyanInstrumentation extends InstrumentationBase< const instrumentation = this; return function patchedEmit(this: BunyanLogger, ...args: unknown[]) { const config = instrumentation.getConfig(); - if (!instrumentation.isEnabled() || config.disableInjection) { + if (!instrumentation.isEnabled() || config.disableLogCorrelation) { return original.apply(this, args); } diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts index 7189177c55..8e5a9df03a 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts @@ -29,16 +29,16 @@ export interface BunyanInstrumentationConfig extends InstrumentationConfig { disableLogsBridge?: boolean; /** - * Whether to disable the injection of data such as trace-context fields into - * log output. + * Whether to disable the injection trace-context fields, and possibly other + * fields from `logHook()`, into log records for log correlation. * @default false */ - disableInjection?: boolean; + disableLogCorrelation?: boolean; /** * A function that allows injecting additional fields in log records. It is * called, as `logHook(span, record)`, for each log record emitted in a valid - * span context. It requires `disableInjection` to be false. + * span context. It requires `disableLogCorrelation` to be false. */ logHook?: LogHookFunction; } diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index 42fb7d06fc..290b47af8e 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -156,9 +156,9 @@ describe('BunyanInstrumentation', () => { }); }); - it('does not inject or call logHook if disableInjection=true', () => { + it('does not inject or call logHook if disableLogCorrelation=true', () => { instrumentation.setConfig({ - disableInjection: true, + disableLogCorrelation: true, logHook: (_span, record) => { record['resource.service.name'] = 'test-service'; }, @@ -278,7 +278,7 @@ describe('BunyanInstrumentation', () => { log.info('foo'); assert.strictEqual(memExporter.getFinishedLogRecords().length, 0); - // Test log injection still works. + // Test log correlation still works. sinon.assert.calledOnce(writeSpy); const record = JSON.parse(writeSpy.firstCall.args[0].toString()); assert.strictEqual('foo', record['msg']); From f850a63c064175f395fe3790bd3d5818d726b200 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 22 Nov 2023 16:36:43 -0800 Subject: [PATCH 27/30] disableLogsBridge -> disableLogSending Avoid using 'bridge' terminology at suggestion from specs that the Bridge API is an internal detail. --- .../README.md | 20 +++++++++---------- .../examples/README.md | 12 +++++------ .../src/OpenTelemetryBunyanStream.ts | 15 +++++++------- .../src/instrumentation.ts | 4 ++-- .../src/types.ts | 4 ++-- .../test/bunyan.test.ts | 16 +++++++-------- 6 files changed, 35 insertions(+), 36 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/README.md index 6c34e1f3c5..c12b489658 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/README.md @@ -3,7 +3,7 @@ [![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image] -This module provides automatic instrumentation of the [`bunyan`](https://www.npmjs.com/package/bunyan) module to inject trace-context into Bunyan log records (Log correlation) and to bridge Bunyan logging to the OpenTelemetry Logging SDK. It may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle. +This module provides automatic instrumentation of the [`bunyan`](https://www.npmjs.com/package/bunyan) module to inject trace-context into Bunyan log records (log correlation) and to send Bunyan logging to the OpenTelemetry Logging SDK (log sending). It may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle. If total installation size is not constrained, it is recommended to use the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle with [@opentelemetry/sdk-node](`https://www.npmjs.com/package/@opentelemetry/sdk-node`) for the most seamless instrumentation experience. @@ -39,7 +39,7 @@ const logger = bunyan.createLogger({name: 'example'}); logger.info('hi'); // 1. Log records will be sent to the SDK-registered log record processor, if any. -// This is called "bridging". +// This is called "log sending". const tracer = api.trace.getTracer('example'); tracer.startActiveSpan('manual-span', span => { @@ -50,13 +50,13 @@ tracer.startActiveSpan('manual-span', span => { }) ``` -### Logs Bridge +### Log sending -Creation of a Bunyan Logger will automatically add a [Bunyan stream](https://github.com/trentm/node-bunyan#streams) that sends log records to the OpenTelemetry Logs Bridge API. The OpenTelemetry SDK can be configured to handle those records -- for example, sending them on to an OpenTelemetry collector for log archiving and processing. The example above shows a minimal configuration that emits OpenTelemetry log records to the console for debugging. +Creation of a Bunyan Logger will automatically add a [Bunyan stream](https://github.com/trentm/node-bunyan#streams) that sends log records to the OpenTelemetry Logs SDK. The OpenTelemetry SDK can be configured to handle those records -- for example, sending them on to an OpenTelemetry collector for log archiving and processing. The example above shows a minimal configuration that emits OpenTelemetry log records to the console for debugging. If the OpenTelemetry SDK is not configured with a Logger provider, then this added stream will be a no-op. -The logs bridge can be disabled with the `disableLogsBridge: true` option. +Log sending can be disabled with the `disableLogSending: true` option. ### Log correlation @@ -85,16 +85,16 @@ Log injection can be disabled with the `disableLogCorrelation: true` option. | Option | Type | Description | | ----------------------- | ----------------- | ----------- | -| `disableLogsBridge` | `boolean` | Whether to disable [logs bridging](#logs-bridge). Default `false`. | +| `disableLogSending` | `boolean` | Whether to disable [log sending](#log-sending). Default `false`. | | `disableLogCorrelation` | `boolean` | Whether to disable [log correlation](#log-correlation). Default `false`. | | `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. | ### Using OpenTelemetryBunyanStream without instrumentation -This package exports the Bunyan stream class that is used to bridge to the -OpenTelemetry Logs Bridge API. It can be used directly when configuring a -Bunyan logger if one is not using the `BunyanInstrumentation` for whatever -reason. For example: +This package exports the Bunyan stream class that is used to send records to the +OpenTelemetry Logs SDK. It can be used directly when configuring a Bunyan logger +if one is not using the `BunyanInstrumentation` for whatever reason. For +example: ```js const { OpenTelemetryBunyanStream } = require('@opentelemetry/instrumentation-bunyan'); diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md index 7ccd066d18..89041f4bb1 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md +++ b/plugins/node/opentelemetry-instrumentation-bunyan/examples/README.md @@ -63,17 +63,17 @@ $ node -r ./telemetry.js app.js } ``` -There are two separate Bunyan instrumentation features. The first, called -"log correlation", is that Bunyan log records emitted in the context of a tracing +There are two separate Bunyan instrumentation features. The first, called "log +correlation", is that Bunyan log records emitted in the context of a tracing span will include `trace_id` and `span_id` fields that can be used for correlating with collected tracing data. -The second, called "logs bridging", is that a [Bunyan +The second, called "log sending", is that a [Bunyan stream](https://github.com/trentm/node-bunyan#streams) is automatically added to created Loggers that will send every log record to the OpenTelemetry Logs -Bridge API. This means that if the OpenTelemetry SDK has been configured with -a Logger Provider, it will receive them. (If the OpenTelemetry SDK is not -configured for this, then the added Bunyan stream will be a no-op.) +SDK. This means that if the OpenTelemetry SDK has been configured with a Logger +Provider, it will receive them. (If the OpenTelemetry SDK is not configured for +this, then the added Bunyan stream will be a no-op.) # Resource attributes diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index fb105fb34f..559db71008 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -97,7 +97,7 @@ function severityNumberFromBunyanLevel(lvl: number) { } /** - * A Bunyan stream for sending log records to the OpenTelemetry Logs Bridge API. + * A Bunyan stream for sending log records to the OpenTelemetry Logs SDK. */ export class OpenTelemetryBunyanStream { private _otelLogger: Logger; @@ -130,17 +130,16 @@ export class OpenTelemetryBunyanStream { * the _emit wrapper. */ write(rec: Record) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars const { time, level, msg, - v, - hostname, - pid, - trace_id, - span_id, - trace_flags, + v, // eslint-disable-line @typescript-eslint/no-unused-vars + hostname, // eslint-disable-line @typescript-eslint/no-unused-vars + pid, // eslint-disable-line @typescript-eslint/no-unused-vars + trace_id, // eslint-disable-line @typescript-eslint/no-unused-vars + span_id, // eslint-disable-line @typescript-eslint/no-unused-vars + trace_flags, // eslint-disable-line @typescript-eslint/no-unused-vars ...fields } = rec; let timestamp = undefined; diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts index ca060df7de..c78e27b50b 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/instrumentation.ts @@ -27,7 +27,7 @@ import { OpenTelemetryBunyanStream } from './OpenTelemetryBunyanStream'; import type * as BunyanLogger from 'bunyan'; const DEFAULT_CONFIG: BunyanInstrumentationConfig = { - disableLogsBridge: false, + disableLogSending: false, disableLogCorrelation: false, }; @@ -153,7 +153,7 @@ export class BunyanInstrumentation extends InstrumentationBase< private _addStream(logger: any) { const config: BunyanInstrumentationConfig = this.getConfig(); - if (!this.isEnabled() || config.disableLogsBridge) { + if (!this.isEnabled() || config.disableLogSending) { return; } this._diag.debug('Adding OpenTelemetryBunyanStream to logger'); diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts index 8e5a9df03a..7a2f5f686b 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/types.ts @@ -23,10 +23,10 @@ export type LogHookFunction = (span: Span, record: Record) => void; export interface BunyanInstrumentationConfig extends InstrumentationConfig { /** * Whether to disable the automatic sending of log records to the - * OpenTelemetry Logs Bridge API. + * OpenTelemetry Logs SDK. * @default false */ - disableLogsBridge?: boolean; + disableLogSending?: boolean; /** * Whether to disable the injection trace-context fields, and possibly other diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index 290b47af8e..0479e10189 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -175,13 +175,13 @@ describe('BunyanInstrumentation', () => { assert.strictEqual( memExporter.getFinishedLogRecords().length, 1, - 'Logs Bridge still works' + 'Log sending still works' ); span.end(); }); }); - it('emits log records to Logs Bridge API', () => { + it('emits log records to Logs SDK', () => { const logRecords = memExporter.getFinishedLogRecords(); // levels @@ -265,10 +265,10 @@ describe('BunyanInstrumentation', () => { assert.strictEqual(rec.severityText, undefined); }); - it('does not emit to the Logs Bridge API if disableLogsBridge=true', () => { - instrumentation.setConfig({ disableLogsBridge: true }); + it('does not emit to the Logs SDK if disableLogSending=true', () => { + instrumentation.setConfig({ disableLogSending: true }); - // Changing `disableLogsBridge` only has an impact on Loggers created + // Changing `disableLogSending` only has an impact on Loggers created // *after* it is set. So we cannot test with the `log` created in // `beforeEach()` above. log = Logger.createLogger({ name: 'test-logger-name', stream }); @@ -288,7 +288,7 @@ describe('BunyanInstrumentation', () => { }); }); - it('emits to the Logs Bridge API with `new Logger(...)`', () => { + it('emits to the Logs SDK with `new Logger(...)`', () => { log = new Logger({ name: 'test-logger-name', stream }); log.info('foo'); @@ -304,7 +304,7 @@ describe('BunyanInstrumentation', () => { assert.strictEqual(rec.attributes.aProperty, 'bar'); }); - it('emits to the Logs Bridge API with `Logger(...)`', () => { + it('emits to the Logs SDK with `Logger(...)`', () => { log = Logger({ name: 'test-logger-name', stream }); log.info('foo'); @@ -367,7 +367,7 @@ describe('BunyanInstrumentation', () => { }); }); - it('does not emit to the Logs Bridge API', () => { + it('does not emit to the Logs SDK', () => { tracer.startActiveSpan('abc', span => { log.info('foo'); assert.strictEqual(memExporter.getFinishedLogRecords().length, 0); From 39b8507c79a38aa6432e8186e30697c60d49ba4a Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 27 Nov 2023 10:23:58 -0800 Subject: [PATCH 28/30] correct the default instrumentation scope name (as discussed earlier) --- .../src/OpenTelemetryBunyanStream.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index 559db71008..e88b16fabd 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -18,7 +18,7 @@ import { logs, SeverityNumber, Logger } from '@opentelemetry/api-logs'; import type { LogLevelString } from 'bunyan'; import { VERSION } from './version'; -const DEFAULT_INSTRUMENTATION_SCOPE_NAME = 'io.opentelemetry.contrib.bunyan'; +const DEFAULT_INSTRUMENTATION_SCOPE_NAME = '@opentelemetry/instrumentation-bunyan'; const DEFAULT_INSTRUMENTATION_SCOPE_VERSION = VERSION; // This block is a copy (modulo code style and TypeScript types) of the Bunyan From a149912d069464329e11748341a3632809bad5e7 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 27 Nov 2023 10:25:56 -0800 Subject: [PATCH 29/30] tests: fix test for intrumentationScope.name change in previous commit --- .../opentelemetry-instrumentation-bunyan/test/bunyan.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts index 0479e10189..5ca3744d3d 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/test/bunyan.test.ts @@ -217,7 +217,7 @@ describe('BunyanInstrumentation', () => { ); assert.strictEqual( rec.instrumentationScope.name, - 'io.opentelemetry.contrib.bunyan' + '@opentelemetry/instrumentation-bunyan' ); assert.strictEqual(rec.instrumentationScope.version, VERSION); assert.strictEqual(rec.spanContext, undefined); @@ -431,7 +431,7 @@ describe('OpenTelemetryBunyanStream', () => { ); assert.strictEqual( rec.instrumentationScope.name, - 'io.opentelemetry.contrib.bunyan' + '@opentelemetry/instrumentation-bunyan' ); assert.strictEqual(rec.instrumentationScope.version, VERSION); assert.strictEqual(rec.spanContext, undefined); From ca1803425d9f9f8e4dd9877659475129fbead72e Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 27 Nov 2023 10:26:46 -0800 Subject: [PATCH 30/30] fix lint --- .../src/OpenTelemetryBunyanStream.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts index e88b16fabd..8b3d1c8977 100644 --- a/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts +++ b/plugins/node/opentelemetry-instrumentation-bunyan/src/OpenTelemetryBunyanStream.ts @@ -18,7 +18,8 @@ import { logs, SeverityNumber, Logger } from '@opentelemetry/api-logs'; import type { LogLevelString } from 'bunyan'; import { VERSION } from './version'; -const DEFAULT_INSTRUMENTATION_SCOPE_NAME = '@opentelemetry/instrumentation-bunyan'; +const DEFAULT_INSTRUMENTATION_SCOPE_NAME = + '@opentelemetry/instrumentation-bunyan'; const DEFAULT_INSTRUMENTATION_SCOPE_VERSION = VERSION; // This block is a copy (modulo code style and TypeScript types) of the Bunyan