Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): Optionally suppress warning about logger being overwritten #3366

Merged
Merged
6 changes: 6 additions & 0 deletions api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## Unreleased

### Features

* Optionally suppress warning about logger being overwritten ([#3366](https://www.github.com/open-telemetry/opentelemetry-js-api/pull/3366))

## [1.2.0](https://www.github.com/open-telemetry/opentelemetry-js-api/compare/v1.1.0...v1.2.0) (2022-08-09)

### Features
Expand Down
76 changes: 46 additions & 30 deletions api/src/api/diag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ import {

const API_NAME = 'diag';

interface LoggerOptions {
logLevel?: DiagLogLevel;
suppressOverrideMessage?: boolean;
}

/**
* Singleton object which represents the entry point to the OpenTelemetry internal
* diagnostic API
Expand Down Expand Up @@ -65,35 +70,6 @@ export class DiagAPI implements DiagLogger {

// DiagAPI specific functions

self.setLogger = (
logger: DiagLogger,
logLevel: DiagLogLevel = DiagLogLevel.INFO
) => {
if (logger === self) {
// There isn't much we can do here.
// Logging to the console might break the user application.
// Try to log to self. If a logger was previously registered it will receive the log.
const err = new Error(
'Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation'
);
self.error(err.stack ?? err.message);
return false;
}

const oldLogger = getGlobal('diag');
const newLogger = createLogLevelDiagLogger(logLevel, logger);
// There already is an logger registered. We'll let it know before overwriting it.
if (oldLogger) {
const stack = new Error().stack ?? '<failed to generate stacktrace>';
oldLogger.warn(`Current logger will be overwritten from ${stack}`);
newLogger.warn(
`Current logger will overwrite one already registered from ${stack}`
);
}

return registerGlobal('diag', newLogger, self, true);
};

self.disable = () => {
unregisterGlobal(API_NAME, self);
};
Expand All @@ -117,7 +93,47 @@ export class DiagAPI implements DiagLogger {
* @param logLevel - [Optional] The DiagLogLevel used to filter logs sent to the logger. If not provided it will default to INFO.
* @returns true if the logger was successfully registered, else false
*/
public setLogger!: (logger: DiagLogger, logLevel?: DiagLogLevel) => boolean;
public setLogger(logger: DiagLogger, logLevel?: DiagLogLevel): boolean;
dyladan marked this conversation as resolved.
Show resolved Hide resolved
/**
* Set the global DiagLogger and DiagLogLevel.
* If a global diag logger is already set, this will override it.
*
* @param logger - [Optional] The DiagLogger instance to set as the default logger.
* @param options - [Optional] And object which can contain `logLevel: DiagLogLevel` used to filter logs sent to the logger. If not provided it will default to INFO. The object may also contain `suppressOverrideMessage: boolean` which will suppress the warning normally logged when a logger is already registered.
* @returns true if the logger was successfully registered, else false
*/
public setLogger(logger: DiagLogger, options?: LoggerOptions): boolean;
public setLogger(logger: DiagLogger, optionsOrLogLevel: DiagLogLevel | LoggerOptions = { logLevel: DiagLogLevel.INFO }) {
if (logger === this) {
// There isn't much we can do here.
// Logging to the console might break the user application.
// Try to log to self. If a logger was previously registered it will receive the log.
const err = new Error(
'Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation'
);
this.error(err.stack ?? err.message);
return false;
}

if (typeof optionsOrLogLevel === 'number') {
optionsOrLogLevel = {
logLevel: optionsOrLogLevel,
}
}

const oldLogger = getGlobal('diag');
const newLogger = createLogLevelDiagLogger(optionsOrLogLevel.logLevel ?? DiagLogLevel.INFO, logger);
// There already is an logger registered. We'll let it know before overwriting it.
if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) {
const stack = new Error().stack ?? '<failed to generate stacktrace>';
oldLogger.warn(`Current logger will be overwritten from ${stack}`);
newLogger.warn(
`Current logger will overwrite one already registered from ${stack}`
);
}

return registerGlobal('diag', newLogger, this, true);
}
/**
*
*/
Expand Down