diff --git a/.eslintrc.js b/.eslintrc.js index 507822e8..e1e62430 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -32,6 +32,7 @@ module.exports = { "@typescript-eslint/no-inferrable-types": ["error", { ignoreProperties: true }], "arrow-parens": ["error", "as-needed"], "prettier/prettier": ["error", { "singleQuote": true, "arrowParens": "avoid" }], + "prefer-spread": "off", "node/no-deprecated-api": ["warn"], "header/header": [2, "block", [{ pattern: / \* Copyright The OpenTelemetry Authors[\r\n]+ \*[\r\n]+ \* Licensed under the Apache License, Version 2\.0 \(the \"License\"\);[\r\n]+ \* you may not use this file except in compliance with the License\.[\r\n]+ \* You may obtain a copy of the License at[\r\n]+ \*[\r\n]+ \* https:\/\/www\.apache\.org\/licenses\/LICENSE-2\.0[\r\n]+ \*[\r\n]+ \* Unless required by applicable law or agreed to in writing, software[\r\n]+ \* distributed under the License is distributed on an \"AS IS\" BASIS,[\r\n]+ \* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\.[\r\n]+ \* See the License for the specific language governing permissions and[\r\n]+ \* limitations under the License\./gm, diff --git a/package.json b/package.json index 4bd6ac87..d0e1500a 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p .", "compile": "tsc --build", "docs-test": "linkinator docs/out --silent --skip david-dm.org", - "docs": "typedoc --tsconfig tsconfig.docs.json", + "docs": "typedoc", "lint:fix": "eslint src test --ext .ts --fix", "lint": "eslint src test --ext .ts", "test:browser": "nyc karma start --single-run", diff --git a/src/api/diag.ts b/src/api/diag.ts index 58a5cdd1..b32b6b25 100644 --- a/src/api/diag.ts +++ b/src/api/diag.ts @@ -14,13 +14,9 @@ * limitations under the License. */ -import { - DiagLogger, - DiagLogFunction, - createNoopDiagLogger, - diagLoggerFunctions, -} from '../diag/logger'; -import { DiagLogLevel, createLogLevelDiagLogger } from '../diag/logLevel'; +import { createLogLevelDiagLogger } from '../diag/internal/logLevelLogger'; +import { createNoopDiagLogger } from '../diag/internal/noopLogger'; +import { DiagLogFunction, DiagLogger, DiagLogLevel } from '../diag/types'; import { API_BACKWARDS_COMPATIBILITY_VERSION, GLOBAL_DIAG_LOGGER_API_KEY, @@ -28,15 +24,14 @@ import { _global, } from './global-utils'; +function nop() {} + /** Internal simple Noop Diag API that returns a noop logger and does not allow any changes */ function noopDiagApi(): DiagAPI { - const noopApi = createNoopDiagLogger() as DiagAPI; - - noopApi.getLogger = () => noopApi; - noopApi.setLogger = noopApi.getLogger; - noopApi.setLogLevel = () => {}; - - return noopApi; + return Object.assign( + { disable: nop, setLogger: nop }, + createNoopDiagLogger() + ); } /** @@ -71,21 +66,18 @@ export class DiagAPI implements DiagLogger { * @private */ private constructor() { - let _logLevel: DiagLogLevel = DiagLogLevel.INFO; - let _filteredLogger: DiagLogger | null; - let _logger: DiagLogger = createNoopDiagLogger(); + let _filteredLogger: DiagLogger | undefined; function _logProxy(funcName: keyof DiagLogger): DiagLogFunction { return function () { - const orgArguments = arguments as unknown; - const theLogger = _filteredLogger || _logger; - const theFunc = theLogger[funcName]; - if (typeof theFunc === 'function') { - return theFunc.apply( - theLogger, - orgArguments as Parameters - ); - } + // shortcut if logger not set + if (!_filteredLogger) return; + return _filteredLogger[funcName].apply( + _filteredLogger, + // work around Function.prototype.apply types + // eslint-disable-next-line @typescript-eslint/no-explicit-any + arguments as any + ); }; } @@ -94,52 +86,47 @@ export class DiagAPI implements DiagLogger { // DiagAPI specific functions - self.getLogger = (): DiagLogger => { - // Return itself if no existing logger is defined (defaults effectively to a Noop) - return _logger; - }; - - self.setLogger = (logger?: DiagLogger): DiagLogger => { - const prevLogger = _logger; - if (!logger || logger !== self) { - // Simple special case to avoid any possible infinite recursion on the logging functions - _logger = logger || createNoopDiagLogger(); - _filteredLogger = createLogLevelDiagLogger(_logLevel, _logger); + self.setLogger = ( + logger: DiagLogger, + logLevel: DiagLogLevel = DiagLogLevel.INFO + ) => { + if (logger === self) { + if (_filteredLogger) { + const err = new Error( + 'Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation' + ); + _filteredLogger.error(err.stack ?? err.message); + logger = _filteredLogger; + } else { + // There isn't much we can do here. + // Logging to the console might break the user application. + return; + } } - return prevLogger; + _filteredLogger = createLogLevelDiagLogger(logLevel, logger); }; - self.setLogLevel = (maxLogLevel: DiagLogLevel) => { - if (maxLogLevel !== _logLevel) { - _logLevel = maxLogLevel; - if (_logger) { - _filteredLogger = createLogLevelDiagLogger(maxLogLevel, _logger); - } - } + self.disable = () => { + _filteredLogger = undefined; }; - for (let i = 0; i < diagLoggerFunctions.length; i++) { - const name = diagLoggerFunctions[i]; - self[name] = _logProxy(name); - } + self.verbose = _logProxy('verbose'); + self.debug = _logProxy('debug'); + self.info = _logProxy('info'); + self.warn = _logProxy('warn'); + self.error = _logProxy('error'); } /** - * Return the currently configured logger instance, if no logger has been configured - * it will return itself so any log level filtering will still be applied in this case. - */ - public getLogger!: () => DiagLogger; - - /** - * Set the DiagLogger instance - * @param logger - [Optional] The DiagLogger instance to set as the default logger, if not provided it will set it back as a noop + * 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 logLevel - [Optional] The DiagLogLevel used to filter logs sent to the logger. If not provided it will default to INFO. * @returns The previously registered DiagLogger */ - public setLogger!: (logger?: DiagLogger) => DiagLogger; - - /** Set the default maximum diagnostic logging level */ - public setLogLevel!: (maxLogLevel: DiagLogLevel) => void; + public setLogger!: (logger: DiagLogger, logLevel?: DiagLogLevel) => void; // DiagLogger implementation public verbose!: DiagLogFunction; @@ -147,4 +134,9 @@ export class DiagAPI implements DiagLogger { public info!: DiagLogFunction; public warn!: DiagLogFunction; public error!: DiagLogFunction; + + /** + * Unregister the global logger and return to Noop + */ + public disable!: () => void; } diff --git a/src/diag/consoleLogger.ts b/src/diag/consoleLogger.ts index 7ea2e9cd..8e18e0fa 100644 --- a/src/diag/consoleLogger.ts +++ b/src/diag/consoleLogger.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { DiagLogger, DiagLogFunction } from './logger'; +import { DiagLogger, DiagLogFunction } from './types'; const consoleMap: { n: keyof DiagLogger; c: keyof Console }[] = [ { n: 'error', c: 'error' }, diff --git a/src/diag/index.ts b/src/diag/index.ts new file mode 100644 index 00000000..751b5eed --- /dev/null +++ b/src/diag/index.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export * from './consoleLogger'; +export * from './types'; diff --git a/src/diag/internal/logLevelLogger.ts b/src/diag/internal/logLevelLogger.ts new file mode 100644 index 00000000..e9205b36 --- /dev/null +++ b/src/diag/internal/logLevelLogger.ts @@ -0,0 +1,51 @@ +/* + * 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 { DiagLogFunction, DiagLogger, DiagLogLevel } from '../types'; + +export function createLogLevelDiagLogger( + maxLevel: DiagLogLevel, + logger: DiagLogger +): DiagLogger { + if (maxLevel < DiagLogLevel.NONE) { + maxLevel = DiagLogLevel.NONE; + } else if (maxLevel > DiagLogLevel.ALL) { + maxLevel = DiagLogLevel.ALL; + } + + // In case the logger is null or undefined + logger = logger || {}; + + function _filterFunc( + funcName: keyof DiagLogger, + theLevel: DiagLogLevel + ): DiagLogFunction { + const theFunc = logger[funcName]; + + if (typeof theFunc === 'function' && maxLevel >= theLevel) { + return theFunc.bind(logger); + } + return function () {}; + } + + return { + error: _filterFunc('error', DiagLogLevel.ERROR), + warn: _filterFunc('warn', DiagLogLevel.WARN), + info: _filterFunc('info', DiagLogLevel.INFO), + debug: _filterFunc('debug', DiagLogLevel.DEBUG), + verbose: _filterFunc('verbose', DiagLogLevel.VERBOSE), + }; +} diff --git a/src/diag/internal/noopLogger.ts b/src/diag/internal/noopLogger.ts new file mode 100644 index 00000000..0c4e7d13 --- /dev/null +++ b/src/diag/internal/noopLogger.ts @@ -0,0 +1,34 @@ +/* + * 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 { DiagLogger } from '../types'; + +function noopLogFunction() {} + +/** + * Returns a No-Op Diagnostic logger where all messages do nothing. + * @implements {@link DiagLogger} + * @returns {DiagLogger} + */ +export function createNoopDiagLogger(): DiagLogger { + return { + verbose: noopLogFunction, + debug: noopLogFunction, + info: noopLogFunction, + warn: noopLogFunction, + error: noopLogFunction, + }; +} diff --git a/src/diag/logLevel.ts b/src/diag/logLevel.ts deleted file mode 100644 index 362bb135..00000000 --- a/src/diag/logLevel.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 { DiagAPI } from '../api/diag'; -import { DiagLogger, DiagLogFunction, createNoopDiagLogger } from './logger'; - -/** - * Defines the available internal logging levels for the diagnostic logger, the numeric values - * of the levels are defined to match the original values from the initial LogLevel to avoid - * compatibility/migration issues for any implementation that assume the numeric ordering. - */ -export enum DiagLogLevel { - /** Diagnostic Logging level setting to disable all logging (except and forced logs) */ - NONE = 0, - - /** Identifies an error scenario */ - ERROR = 30, - - /** Identifies a warning scenario */ - WARN = 50, - - /** General informational log message */ - INFO = 60, - - /** General debug log message */ - DEBUG = 70, - - /** - * Detailed trace level logging should only be used for development, should only be set - * in a development environment. - */ - VERBOSE = 80, - - /** Used to set the logging level to include all logging */ - ALL = 9999, -} - -/** - * This is equivalent to: - * type LogLevelString = 'NONE' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'VERBOSE' | 'ALL'; - */ -export type DiagLogLevelString = keyof typeof DiagLogLevel; - -/** Mapping from DiagLogger function name to logging level. */ -const levelMap: { n: keyof DiagLogger; l: DiagLogLevel }[] = [ - { n: 'error', l: DiagLogLevel.ERROR }, - { n: 'warn', l: DiagLogLevel.WARN }, - { n: 'info', l: DiagLogLevel.INFO }, - { n: 'debug', l: DiagLogLevel.DEBUG }, - { n: 'verbose', l: DiagLogLevel.VERBOSE }, -]; - -/** - * Create a Diagnostic logger which limits the messages that are logged via the wrapped logger based on whether the - * message has a {@link DiagLogLevel} equal to the maximum logging level or lower, unless the {@link DiagLogLevel} is - * NONE which will return a noop logger instance. This can be useful to reduce the amount of logging used for the - * system or for a specific component based on any local configuration. - * If you don't supply a logger it will use the global api.diag as the destination which will use the - * current logger and any filtering it may have applied. - * To avoid / bypass any global level filtering you should pass the current logger returned via - * api.diag.getLogger() however, any changes to the logger used by api.diag won't be reflected for this case. - * @param maxLevel - The max level to log any logging of a lower - * @param logger - The specific logger to limit, if not defined or supplied will default to api.diag - * @implements {@link DiagLogger} - * @returns {DiagLogger} - */ - -export function createLogLevelDiagLogger( - maxLevel: DiagLogLevel, - logger?: DiagLogger | null -): DiagLogger { - if (maxLevel < DiagLogLevel.NONE) { - maxLevel = DiagLogLevel.NONE; - } else if (maxLevel > DiagLogLevel.ALL) { - maxLevel = DiagLogLevel.ALL; - } - - if (maxLevel === DiagLogLevel.NONE) { - return createNoopDiagLogger(); - } - - if (!logger) { - logger = DiagAPI.instance(); - } - - function _filterFunc( - theLogger: DiagLogger, - funcName: keyof DiagLogger, - theLevel: DiagLogLevel - ): DiagLogFunction { - if (maxLevel >= theLevel) { - return function () { - const orgArguments = arguments as unknown; - const theFunc = theLogger[funcName]; - if (theFunc && typeof theFunc === 'function') { - return theFunc.apply( - logger, - orgArguments as Parameters - ); - } - }; - } - return function () {}; - } - - const newLogger = {} as DiagLogger; - for (let i = 0; i < levelMap.length; i++) { - const name = levelMap[i].n; - newLogger[name] = _filterFunc(logger, name, levelMap[i].l); - } - - return newLogger; -} diff --git a/src/diag/logger.ts b/src/diag/types.ts similarity index 74% rename from src/diag/logger.ts rename to src/diag/types.ts index f718076b..3a633a5b 100644 --- a/src/diag/logger.ts +++ b/src/diag/types.ts @@ -59,28 +59,33 @@ export interface DiagLogger { verbose: DiagLogFunction; } -// DiagLogger implementation -export const diagLoggerFunctions: Array = [ - 'verbose', - 'debug', - 'info', - 'warn', - 'error', -]; - -function noopLogFunction() {} - /** - * Returns a No-Op Diagnostic logger where all messages do nothing. - * @implements {@link DiagLogger} - * @returns {DiagLogger} + * Defines the available internal logging levels for the diagnostic logger, the numeric values + * of the levels are defined to match the original values from the initial LogLevel to avoid + * compatibility/migration issues for any implementation that assume the numeric ordering. */ -export function createNoopDiagLogger(): DiagLogger { - const diagLogger = {} as DiagLogger; +export enum DiagLogLevel { + /** Diagnostic Logging level setting to disable all logging (except and forced logs) */ + NONE = 0, + + /** Identifies an error scenario */ + ERROR = 30, + + /** Identifies a warning scenario */ + WARN = 50, - for (let i = 0; i < diagLoggerFunctions.length; i++) { - diagLogger[diagLoggerFunctions[i]] = noopLogFunction; - } + /** General informational log message */ + INFO = 60, + + /** General debug log message */ + DEBUG = 70, + + /** + * Detailed trace level logging should only be used for development, should only be set + * in a development environment. + */ + VERBOSE = 80, - return diagLogger; + /** Used to set the logging level to include all logging */ + ALL = 9999, } diff --git a/src/index.ts b/src/index.ts index 37d3b59e..b36eaccd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,11 +14,12 @@ * limitations under the License. */ +export * from './baggage'; export * from './common/Exception'; export * from './common/Time'; -export * from './propagation/TextMapPropagator'; +export * from './diag'; export * from './propagation/NoopTextMapPropagator'; -export * from './baggage'; +export * from './propagation/TextMapPropagator'; export * from './trace/attributes'; export * from './trace/Event'; export * from './trace/link_context'; @@ -39,9 +40,6 @@ export * from './trace/trace_flags'; export * from './trace/trace_state'; export * from './trace/tracer_provider'; export * from './trace/tracer'; -export * from './diag/consoleLogger'; -export * from './diag/logger'; -export * from './diag/logLevel'; export { INVALID_SPANID, diff --git a/test/api/api.test.ts b/test/api/api.test.ts index 50b905be..5287b38c 100644 --- a/test/api/api.test.ts +++ b/test/api/api.test.ts @@ -32,12 +32,20 @@ import api, { defaultTextMapSetter, defaultTextMapGetter, diag, - diagLoggerFunctions, } from '../../src'; import { DiagAPI } from '../../src/api/diag'; import { _global } from '../../src/api/global-utils'; import { NoopSpan } from '../../src/trace/NoopSpan'; +// DiagLogger implementation +const diagLoggerFunctions = [ + 'verbose', + 'debug', + 'info', + 'warn', + 'error', +] as const; + describe('API', () => { it('should expose a tracer provider via getTracerProvider', () => { const tracer = api.trace.getTracerProvider(); @@ -191,6 +199,7 @@ describe('API', () => { diagLoggerFunctions.forEach(fName => { it(`no argument logger ${fName} message doesn't throw`, () => { + //@ts-expect-error an undefined logger is not allowed diag.setLogger(); assert.doesNotThrow(() => { diag[fName](`${fName} message`); diff --git a/test/diag/consoleLogger.test.ts b/test/diag/consoleLogger.test.ts index 07269bc9..56b8e4c2 100644 --- a/test/diag/consoleLogger.test.ts +++ b/test/diag/consoleLogger.test.ts @@ -16,7 +16,14 @@ import * as assert from 'assert'; import { DiagConsoleLogger } from '../../src/diag/consoleLogger'; -import { diagLoggerFunctions } from '../../src/diag/logger'; + +export const diagLoggerFunctions = [ + 'verbose', + 'debug', + 'info', + 'warn', + 'error', +] as const; const consoleFuncs: Array = [ 'debug', diff --git a/test/diag/logLevel.test.ts b/test/diag/logLevel.test.ts index 3b7fa548..3786fba9 100644 --- a/test/diag/logLevel.test.ts +++ b/test/diag/logLevel.test.ts @@ -16,23 +16,20 @@ import * as assert from 'assert'; import { diag } from '../../src'; -import { - createNoopDiagLogger, - DiagLogger, - diagLoggerFunctions, -} from '../../src/diag/logger'; -import { - DiagLogLevel, - createLogLevelDiagLogger, -} from '../../src/diag/logLevel'; +import { createLogLevelDiagLogger } from '../../src/diag/internal/logLevelLogger'; +import { createNoopDiagLogger } from '../../src/diag/internal/noopLogger'; +import { DiagLogger, DiagLogLevel } from '../../src/diag/types'; // Matches the previous Logger definition -const incompleteLoggerFuncs: Array = [ +const incompleteLoggerFuncs = ['debug', 'info', 'warn', 'error'] as const; + +export const diagLoggerFunctions = [ + 'verbose', 'debug', 'info', 'warn', 'error', -]; +] as const; describe('LogLevelFilter DiagLogger', () => { const calledArgs: any = { @@ -50,8 +47,7 @@ describe('LogLevelFilter DiagLogger', () => { beforeEach(() => { // Set no logger so that sinon doesn't complain about TypeError: Attempted to wrap xxxx which is already wrapped - diag.setLogger(); - diag.setLogLevel(DiagLogLevel.INFO); + diag.disable(); // mock dummyLogger = {} as DiagLogger; @@ -148,6 +144,7 @@ describe('LogLevelFilter DiagLogger', () => { }); it('should be noop and not throw for null and no default Logger log', () => { + // @ts-expect-error null logger is not allowed const testLogger = createLogLevelDiagLogger(map.level, null); testLogger[fName](`${fName} called %s`, 'param1'); diagLoggerFunctions.forEach(lName => { @@ -156,6 +153,7 @@ describe('LogLevelFilter DiagLogger', () => { }); it('should be noop and not throw for undefined and no default Logger log', () => { + // @ts-expect-error undefined logger is not allowed const testLogger = createLogLevelDiagLogger(map.level, undefined); testLogger[fName](`${fName} called %s`, 'param1'); diagLoggerFunctions.forEach(lName => { @@ -163,71 +161,14 @@ describe('LogLevelFilter DiagLogger', () => { }); }); - it('should use default logger for undefined and log', () => { - diag.setLogger(dummyLogger); - diag.setLogLevel(DiagLogLevel.ALL); - const testLogger = createLogLevelDiagLogger(map.level, undefined); - testLogger[fName](`${fName} called %s`, 'param1'); - diagLoggerFunctions.forEach(lName => { - if (fName === lName && map.ignoreFuncs.indexOf(lName) === -1) { - assert.deepStrictEqual(calledArgs[lName], [ - `${fName} called %s`, - 'param1', - ]); - } else { - assert.strictEqual(calledArgs[lName], null); - } - }); - }); - - it('should use default logger for null and log', () => { - diag.setLogger(dummyLogger); - diag.setLogLevel(DiagLogLevel.ALL); - const testLogger = createLogLevelDiagLogger(map.level, null); - testLogger[fName](`${fName} called %s`, 'param1'); - diagLoggerFunctions.forEach(lName => { - if (fName === lName && map.ignoreFuncs.indexOf(lName) === -1) { - assert.deepStrictEqual(calledArgs[lName], [ - `${fName} called %s`, - 'param1', - ]); - } else { - assert.strictEqual(calledArgs[lName], null); - } - }); - }); - levelMap.forEach(masterLevelMap => { describe(`when diag logger is set to ${masterLevelMap.message}`, () => { - it('diag setLogLevel is not ignored and using default logger', () => { - diag.setLogger(dummyLogger); - diag.setLogLevel(masterLevelMap.level); - - const testLogger = createLogLevelDiagLogger(map.level); - testLogger[fName](`${fName} called %s`, 'param1'); - diagLoggerFunctions.forEach(lName => { - if ( - fName === lName && - map.ignoreFuncs.indexOf(lName) === -1 && - masterLevelMap.ignoreFuncs.indexOf(lName) === -1 - ) { - assert.deepStrictEqual(calledArgs[lName], [ - `${fName} called %s`, - 'param1', - ]); - } else { - assert.strictEqual(calledArgs[lName], null); - } - }); - }); - - it('diag setLogLevel is ignored when using a specific logger', () => { - diag.setLogger(dummyLogger); - diag.setLogLevel(masterLevelMap.level); + it('diag.setLogger level is ignored when using a specific logger', () => { + diag.setLogger(dummyLogger, masterLevelMap.level); const testLogger = createLogLevelDiagLogger( map.level, - diag.getLogger() + dummyLogger ); testLogger[fName](`${fName} called %s`, 'param1'); diagLoggerFunctions.forEach(lName => { @@ -247,9 +188,8 @@ describe('LogLevelFilter DiagLogger', () => { }); }); - it('diag setLogLevel and logger should log', () => { - diag.setLogger(dummyLogger); - diag.setLogLevel(map.level); + it('diag.setLogger level and logger should log', () => { + diag.setLogger(dummyLogger, map.level); diag[fName](`${fName} called %s`, 'param1'); diagLoggerFunctions.forEach(lName => { if (fName === lName && map.ignoreFuncs.indexOf(lName) === -1) { diff --git a/test/diag/logger.test.ts b/test/diag/logger.test.ts index a957445b..308c2603 100644 --- a/test/diag/logger.test.ts +++ b/test/diag/logger.test.ts @@ -15,13 +15,18 @@ */ import * as assert from 'assert'; +import sinon = require('sinon'); import { diag, DiagLogLevel } from '../../src'; -import { - DiagLogger, - createNoopDiagLogger, - diagLoggerFunctions, -} from '../../src/diag/logger'; +import { createNoopDiagLogger } from '../../src/diag/internal/noopLogger'; +import { DiagLogger } from '../../src/diag/types'; +export const diagLoggerFunctions = [ + 'verbose', + 'debug', + 'info', + 'warn', + 'error', +] as const; describe('DiagLogger functions', () => { const calledArgs: any = { error: null, @@ -48,6 +53,7 @@ describe('DiagLogger functions', () => { diagLoggerFunctions.forEach(fName => { calledArgs[fName] = null; }); + diag.disable(); }); describe('constructor', () => { @@ -68,8 +74,7 @@ describe('DiagLogger functions', () => { }); it(`diag should log with ${fName} message`, () => { - diag.setLogger(dummyLogger); - diag.setLogLevel(DiagLogLevel.ALL); + diag.setLogger(dummyLogger, DiagLogLevel.ALL); diag[fName](`${fName} called %s`, 'param1'); diagLoggerFunctions.forEach(lName => { if (fName === lName) { @@ -91,4 +96,27 @@ describe('DiagLogger functions', () => { }); }); }); + + describe('diag is used as the diag logger in setLogger', () => { + it('should not throw', () => { + diag.setLogger(diag); + }); + + it('should use the previously registered logger to log the error', () => { + const error = sinon.stub(); + diag.setLogger({ + verbose: () => {}, + debug: () => {}, + info: () => {}, + warn: () => {}, + error, + }); + + sinon.assert.notCalled(error); + + diag.setLogger(diag); + + sinon.assert.calledOnce(error); + }); + }); }); diff --git a/tsconfig.docs.json b/tsconfig.docs.json deleted file mode 100644 index 0d2f7ed0..00000000 --- a/tsconfig.docs.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "rootDir": ".", - "outDir": "build" - }, - "include": [ - "src/**/*.ts" - ], - "typedocOptions": { - "name": "OpenTelemetry API for JavaScript", - "out": "docs/out", - "entryPoints": ["./src/index.ts"], - "hideGenerator": true - } -}