diff --git a/README.md b/README.md index b339391..4eec14f 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ Pass these options to the HoneycombWebSDK: | traceExporters | optional | SpanExporter[] | | Array of [span exporters](https://opentelemetry.io/docs/languages/js/exporters) | optional | | webVitalsInstrumentationConfig|optional|WebVitalsInstrumentationConfig| `{ enabled: true }` | See [WebVitalsInstrumentationConfig](####WebVitalsInstrumentationConfig). | | globalErrorsInstrumentationConfig |optional| GlobalErrorsInstrumentationConfig| `{ enabled: true }` | See [GlobalErrorsInstrumentationConfig](####GlobalErrorsInstrumentationConfig). +| logLevel | optional | DiagLogLevel | DiagLogLevel.DEBUG | Controls the verbosity of logs printed to the console. | `*` Note: the `apiKey` field is required because this SDK really wants to help you send data directly to Honeycomb. diff --git a/packages/honeycomb-opentelemetry-web/src/console-trace-link-exporter.ts b/packages/honeycomb-opentelemetry-web/src/console-trace-link-exporter.ts index aff15a6..160c587 100644 --- a/packages/honeycomb-opentelemetry-web/src/console-trace-link-exporter.ts +++ b/packages/honeycomb-opentelemetry-web/src/console-trace-link-exporter.ts @@ -10,6 +10,7 @@ import { FAILED_AUTH_FOR_LOCAL_VISUALIZATIONS, MISSING_FIELDS_FOR_LOCAL_VISUALIZATIONS, } from './validate-options'; +import { DiagLogLevel } from '@opentelemetry/api'; /** * Builds and returns a {@link SpanExporter} that logs Honeycomb URLs for completed traces @@ -22,7 +23,11 @@ export function configureConsoleTraceLinkExporter( options?: HoneycombOptions, ): SpanExporter { const apiKey = getTracesApiKey(options); - return new ConsoleTraceLinkExporter(options?.serviceName, apiKey); + return new ConsoleTraceLinkExporter( + options?.serviceName, + apiKey, + options?.logLevel, + ); } /** @@ -32,10 +37,17 @@ export function configureConsoleTraceLinkExporter( */ class ConsoleTraceLinkExporter implements SpanExporter { private _traceUrl = ''; + private _logLevel: DiagLogLevel = DiagLogLevel.DEBUG; + + constructor(serviceName?: string, apikey?: string, logLevel?: DiagLogLevel) { + if (logLevel) { + this._logLevel = logLevel; + } - constructor(serviceName?: string, apikey?: string) { if (!serviceName || !apikey) { - console.debug(MISSING_FIELDS_FOR_LOCAL_VISUALIZATIONS); + if (this._logLevel >= DiagLogLevel.DEBUG) { + console.debug(MISSING_FIELDS_FOR_LOCAL_VISUALIZATIONS); + } return; } @@ -65,7 +77,9 @@ class ConsoleTraceLinkExporter implements SpanExporter { } }) .catch(() => { - console.log(FAILED_AUTH_FOR_LOCAL_VISUALIZATIONS); + if (this._logLevel >= DiagLogLevel.INFO) { + console.log(FAILED_AUTH_FOR_LOCAL_VISUALIZATIONS); + } }); } @@ -76,7 +90,7 @@ class ConsoleTraceLinkExporter implements SpanExporter { if (this._traceUrl) { spans.forEach((span) => { // only log root spans (ones without a parent span) - if (!span.parentSpanId) { + if (!span.parentSpanId && this._logLevel >= DiagLogLevel.INFO) { console.log( createHoneycombSDKLogMessage( `Honeycomb link: ${this._traceUrl}=${span.spanContext().traceId}`, diff --git a/packages/honeycomb-opentelemetry-web/src/types.ts b/packages/honeycomb-opentelemetry-web/src/types.ts index df6677c..f58dbb9 100644 --- a/packages/honeycomb-opentelemetry-web/src/types.ts +++ b/packages/honeycomb-opentelemetry-web/src/types.ts @@ -16,7 +16,7 @@ * limitations under the License. */ -import type { ContextManager } from '@opentelemetry/api'; +import type { ContextManager, DiagLogLevel } from '@opentelemetry/api'; import { TextMapPropagator } from '@opentelemetry/api'; import { Instrumentation } from '@opentelemetry/instrumentation'; import { @@ -102,7 +102,7 @@ export interface HoneycombOptions extends Partial { */ sampleRate?: number; - /** The debug flag enables additional logging that us useful when debugging your application. Do not use in production. + /** The debug flag enables additional logging that is useful when debugging your application. Do not use in production. * Defaults to 'false'. */ debug?: boolean; @@ -141,6 +141,12 @@ export interface HoneycombOptions extends Partial { /** Config options for web vitals instrumentation. Enabled by default. */ webVitalsInstrumentationConfig?: WebVitalsInstrumentationConfig; globalErrorsInstrumentationConfig?: GlobalErrorsInstrumentationConfig; + + /** + * Controls the verbosity of logs. Utilizes OpenTelemetry's `DiagLogLevel` enum. Defaults to 'DEBUG'. + * Current options include 'NONE', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'VERBOSE', and 'ALL'. + */ + logLevel?: DiagLogLevel; } /* Configure which fields to include in the `entry_page` resource attributes. By default, diff --git a/packages/honeycomb-opentelemetry-web/src/validate-options.ts b/packages/honeycomb-opentelemetry-web/src/validate-options.ts index c5a3aac..a8be45f 100644 --- a/packages/honeycomb-opentelemetry-web/src/validate-options.ts +++ b/packages/honeycomb-opentelemetry-web/src/validate-options.ts @@ -1,3 +1,4 @@ +import { DiagLogLevel } from '@opentelemetry/api'; import { HoneycombOptions } from './types'; import { createHoneycombSDKLogMessage, @@ -33,32 +34,48 @@ export const FAILED_AUTH_FOR_LOCAL_VISUALIZATIONS = ); export const validateOptionsWarnings = (options?: HoneycombOptions) => { + const logLevel: DiagLogLevel = options?.logLevel + ? options.logLevel + : DiagLogLevel.DEBUG; + if (options?.skipOptionsValidation) { - console.debug(SKIPPING_OPTIONS_VALIDATION_MSG); + if (logLevel >= DiagLogLevel.DEBUG) { + console.debug(SKIPPING_OPTIONS_VALIDATION_MSG); + } return; } // warn if api key is missing - if (!options?.apiKey) { + if (!options?.apiKey && logLevel >= DiagLogLevel.WARN) { console.warn(MISSING_API_KEY_ERROR); } // warn if service name is missing - if (!options?.serviceName) { + if (!options?.serviceName && logLevel >= DiagLogLevel.WARN) { console.warn(MISSING_SERVICE_NAME_ERROR); } // warn if dataset is set while using an environment-aware key - if (options?.apiKey && !isClassic(options?.apiKey) && options?.dataset) { + if ( + options?.apiKey && + !isClassic(options?.apiKey) && + options?.dataset && + logLevel >= DiagLogLevel.WARN + ) { console.warn(IGNORED_DATASET_ERROR); } // warn if dataset is missing if using classic key - if (options?.apiKey && isClassic(options?.apiKey) && !options?.dataset) { + if ( + options?.apiKey && + isClassic(options?.apiKey) && + !options?.dataset && + logLevel >= DiagLogLevel.WARN + ) { console.warn(MISSING_DATASET_ERROR); } // warn if custom sampler provided - if (options?.sampler) { + if (options?.sampler && logLevel >= DiagLogLevel.DEBUG) { console.debug(SAMPLER_OVERRIDE_WARNING); } diff --git a/packages/honeycomb-opentelemetry-web/test/validate-options.test.ts b/packages/honeycomb-opentelemetry-web/test/validate-options.test.ts index ab0599b..8cc7284 100644 --- a/packages/honeycomb-opentelemetry-web/test/validate-options.test.ts +++ b/packages/honeycomb-opentelemetry-web/test/validate-options.test.ts @@ -1,3 +1,4 @@ +import { DiagLogLevel } from '@opentelemetry/api'; import { HoneycombWebSDK } from '../src/honeycomb-otel-sdk'; import { IGNORED_DATASET_ERROR, @@ -42,7 +43,27 @@ describe('console warnings', () => { SKIPPING_OPTIONS_VALIDATION_MSG, ); }); + + it('should not show any warnings or debug logs if log level is lower than DEBUG level', () => { + new HoneycombWebSDK({ + skipOptionsValidation: true, + logLevel: DiagLogLevel.INFO, + }); + expect(debugSpy).not.toHaveBeenCalled(); + }); + + it("should show debug logs if log level is 'DEBUG'", () => { + new HoneycombWebSDK({ + skipOptionsValidation: true, + logLevel: DiagLogLevel.DEBUG, + }); + expect(debugSpy).toHaveBeenNthCalledWith( + 1, + SKIPPING_OPTIONS_VALIDATION_MSG, + ); + }); }); + describe('when skipOptionsValidation is false', () => { it('should show the API key missing warning', () => { new HoneycombWebSDK({ @@ -83,5 +104,13 @@ describe('console warnings', () => { expect(debugSpy).toHaveBeenLastCalledWith(SAMPLER_OVERRIDE_WARNING); }); + + it("should not show any warnings if log level is lower than 'WARN'", () => { + new HoneycombWebSDK({ + logLevel: DiagLogLevel.ERROR, + }); + + expect(warningSpy).not.toHaveBeenCalled(); + }); }); });