Skip to content

Commit f1ca657

Browse files
committed
fix: address review comments
summary of changes - rename trace -> verbose - make log level NONE block all logging - use factory name for Noop logger - refactor tests to use arrays -- reducing test size - remove diagLogAdapterfix: address review changes summary - rename trace -> verbose - make log level NONE block all logging - use factory name for Noop logger - refactor tests to use arrays -- reducing test size - remove diagLogAdapter
1 parent f001290 commit f1ca657

File tree

9 files changed

+628
-1896
lines changed

9 files changed

+628
-1896
lines changed

packages/opentelemetry-api/src/api/diag.ts

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { DiagLogger, DiagLogFunction, noopDiagLogger } from '../diag/logger';
18-
import { DiagLogLevel, diagLogLevelFilter } from '../diag/logLevel';
17+
import {
18+
DiagLogger,
19+
DiagLogFunction,
20+
createNoopDiagLogger,
21+
diagLoggerFunctions,
22+
} from '../diag/logger';
23+
import { DiagLogLevel, createLogLevelDiagLogger } from '../diag/logLevel';
1924
import {
2025
API_BACKWARDS_COMPATIBILITY_VERSION,
2126
GLOBAL_DIAG_LOGGER_API_KEY,
@@ -25,7 +30,7 @@ import {
2530

2631
/** Internal simple Noop Diag API that returns a noop logger and does not allow any changes */
2732
function noopDiagApi(): DiagAPI {
28-
const noopApi = noopDiagLogger() as DiagAPI;
33+
const noopApi = createNoopDiagLogger() as DiagAPI;
2934

3035
noopApi.getLogger = () => noopApi;
3136
noopApi.setLogger = noopApi.getLogger;
@@ -40,7 +45,7 @@ function noopDiagApi(): DiagAPI {
4045
*/
4146
export class DiagAPI implements DiagLogger {
4247
/** Get the singleton instance of the DiagAPI API */
43-
public static inst(): DiagAPI {
48+
public static instance(): DiagAPI {
4449
let theInst = null;
4550
if (_global[GLOBAL_DIAG_LOGGER_API_KEY]) {
4651
// Looks like a previous instance was set, so try and fetch it
@@ -61,19 +66,21 @@ export class DiagAPI implements DiagLogger {
6166
return theInst;
6267
}
6368

64-
/** Private internal constructor
65-
* @private */
69+
/**
70+
* Private internal constructor
71+
* @private
72+
*/
6673
private constructor() {
6774
let _logLevel: DiagLogLevel = DiagLogLevel.INFO;
6875
let _filteredLogger: DiagLogger | null;
69-
let _logger: DiagLogger = noopDiagLogger();
76+
let _logger: DiagLogger = createNoopDiagLogger();
7077

7178
function _logProxy(funcName: keyof DiagLogger): DiagLogFunction {
7279
return function () {
7380
const orgArguments = arguments as unknown;
7481
const theLogger = _filteredLogger || _logger;
7582
const theFunc = theLogger[funcName];
76-
if (theFunc && typeof theFunc === 'function') {
83+
if (typeof theFunc === 'function') {
7784
return theFunc.apply(
7885
theLogger,
7986
orgArguments as Parameters<DiagLogFunction>
@@ -96,8 +103,8 @@ export class DiagAPI implements DiagLogger {
96103
const prevLogger = _logger;
97104
if (prevLogger !== logger && logger !== self) {
98105
// Simple special case to avoid any possible infinite recursion on the logging functions
99-
_logger = logger || noopDiagLogger();
100-
_filteredLogger = diagLogLevelFilter(_logLevel, _logger);
106+
_logger = logger || createNoopDiagLogger();
107+
_filteredLogger = createLogLevelDiagLogger(_logLevel, _logger);
101108
}
102109

103110
return prevLogger;
@@ -107,34 +114,25 @@ export class DiagAPI implements DiagLogger {
107114
if (maxLogLevel !== _logLevel) {
108115
_logLevel = maxLogLevel;
109116
if (_logger) {
110-
_filteredLogger = diagLogLevelFilter(maxLogLevel, _logger);
117+
_filteredLogger = createLogLevelDiagLogger(maxLogLevel, _logger);
111118
}
112119
}
113120
};
114121

115-
// DiagLogger implementation
116-
const theFuncs: Array<keyof DiagLogger> = [
117-
'trace',
118-
'debug',
119-
'info',
120-
'warn',
121-
'error',
122-
'critical',
123-
'terminal',
124-
'forcedInfo',
125-
];
126-
for (let lp = 0; lp < theFuncs.length; lp++) {
127-
const name = theFuncs[lp];
122+
for (let i = 0; i < diagLoggerFunctions.length; i++) {
123+
const name = diagLoggerFunctions[i];
128124
self[name] = _logProxy(name);
129125
}
130126
}
131127

132-
/** Return the currently configured logger instance, if no logger has been configured
128+
/**
129+
* Return the currently configured logger instance, if no logger has been configured
133130
* it will return itself so any log level filtering will still be applied in this case.
134131
*/
135132
public getLogger!: () => DiagLogger;
136133

137-
/** Set the DiagLogger instance
134+
/**
135+
* Set the DiagLogger instance
138136
* @param logger - The DiagLogger instance to set as the default logger
139137
* @returns The previously registered DiagLogger
140138
*/
@@ -144,7 +142,7 @@ export class DiagAPI implements DiagLogger {
144142
public setLogLevel!: (maxLogLevel: DiagLogLevel) => void;
145143

146144
// DiagLogger implementation
147-
public trace!: DiagLogFunction;
145+
public verbose!: DiagLogFunction;
148146
public debug!: DiagLogFunction;
149147
public info!: DiagLogFunction;
150148
public warn!: DiagLogFunction;

packages/opentelemetry-api/src/diag/consoleLogger.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const consoleMap: { n: keyof DiagLogger; c: keyof Console }[] = [
2323
{ n: 'warn', c: 'warn' },
2424
{ n: 'info', c: 'info' },
2525
{ n: 'debug', c: 'debug' },
26-
{ n: 'trace', c: 'trace' },
26+
{ n: 'verbose', c: 'trace' },
2727
{ n: 'forcedInfo', c: 'info' },
2828
];
2929

@@ -40,69 +40,71 @@ export class DiagConsoleLogger implements DiagLogger {
4040
if (console) {
4141
// Some environments only expose the console when the F12 developer console is open
4242
let theFunc = console[funcName];
43-
if (!theFunc) {
43+
if (typeof theFunc !== 'function') {
4444
// Not all environments support all functions
4545
theFunc = console.log;
4646
}
4747

4848
// One last final check
49-
if (theFunc && typeof theFunc === 'function') {
49+
if (typeof theFunc === 'function') {
5050
return theFunc.apply(console, orgArguments);
5151
}
5252
}
5353
};
5454
}
5555

56-
for (let lp = 0; lp < consoleMap.length; lp++) {
57-
const name = consoleMap[lp].n;
58-
let consoleFunc = consoleMap[lp].c;
59-
if (console && !console[consoleFunc]) {
60-
consoleFunc = 'log';
61-
}
62-
this[name] = _consoleFunc(consoleFunc);
56+
for (let i = 0; i < consoleMap.length; i++) {
57+
this[consoleMap[i].n] = _consoleFunc(consoleMap[i].c);
6358
}
6459
}
6560

66-
/** Log a terminal situation that would cause the API to completely fail to initialize,
61+
/**
62+
* Log a terminal situation that would cause the API to completely fail to initialize,
6763
* if this type of message is logged functionality of the API is not expected to be functional.
6864
*/
6965
public terminal!: DiagLogFunction;
7066

71-
/** Log a critical error that NEEDS to be addressed, functionality of the component that emits
67+
/**
68+
* Log a critical error that NEEDS to be addressed, functionality of the component that emits
7269
* this log detail may non-functional. While the overall API may be.
7370
*/
7471
public critical!: DiagLogFunction;
7572

7673
/** Log an error scenario that was not expected and caused the requested operation to fail. */
7774
public error!: DiagLogFunction;
7875

79-
/** Log a warning scenario to inform the developer of an issues that should be investigated.
76+
/**
77+
* Log a warning scenario to inform the developer of an issues that should be investigated.
8078
* The requested operation may or may not have succeeded or completed.
8179
*/
8280
public warn!: DiagLogFunction;
8381

84-
/** Log a general informational message, this should not affect functionality.
82+
/**
83+
* Log a general informational message, this should not affect functionality.
8584
* This is also the default logging level so this should NOT be used for logging
8685
* debugging level information.
8786
*/
8887
public info!: DiagLogFunction;
8988

90-
/** Log a general debug message that can be useful for identifying a failure.
89+
/**
90+
* Log a general debug message that can be useful for identifying a failure.
9191
* Information logged at this level may include diagnostic details that would
9292
* help identify a failure scenario. Useful scenarios would be to log the execution
9393
* order of async operations
9494
*/
9595
public debug!: DiagLogFunction;
9696

97-
/** Log a detailed (verbose) trace level logging that can be used to identify failures
97+
/**
98+
* Log a detailed (verbose) trace level logging that can be used to identify failures
9899
* where debug level logging would be insufficient, this level of tracing can include
99100
* input and output parameters and as such may include PII information passing through
100101
* the API. As such it is recommended that this level of tracing should not be enabled
101102
* in a production environment.
102103
*/
103-
public trace!: DiagLogFunction;
104+
public verbose!: DiagLogFunction;
104105

105-
/** Log a general informational message that should always be logged regardless of the
106+
/**
107+
* Log a general informational message that should always be logged regardless of the
106108
* current {@Link DiagLogLevel) and configured filtering level. This type of logging is
107109
* useful for logging component startup and version information without causing additional
108110
* general informational messages when the logging level is set to DiagLogLevel.WARN or lower.

packages/opentelemetry-api/src/diag/logLevel.ts

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

1717
import { DiagAPI } from '../api/diag';
18-
import { DiagLogger, DiagLogFunction } from './logger';
18+
import { Logger } from '../common/Logger';
19+
import { DiagLogger, DiagLogFunction, createNoopDiagLogger } from './logger';
1920

2021
/**
2122
* Defines the available internal logging levels for the diagnostic logger, the numeric values
@@ -26,12 +27,14 @@ export enum DiagLogLevel {
2627
/** DIagnostic Logging level setting to disable all logging (except and forced logs) */
2728
NONE = -99,
2829

29-
/** Identifies a terminal situation that would cause the API to completely fail to initialize,
30+
/**
31+
* Identifies a terminal situation that would cause the API to completely fail to initialize,
3032
* if this type of error is logged functionality of the API is not expected to be functional.
3133
*/
3234
TERMINAL = -2,
3335

34-
/** Identifies a critical error that needs to be addressed, functionality of the component
36+
/**
37+
* Identifies a critical error that needs to be addressed, functionality of the component
3538
* that emits this log detail may non-functional.
3639
*/
3740
CRITICAL = -1,
@@ -48,46 +51,54 @@ export enum DiagLogLevel {
4851
/** General debug log message */
4952
DEBUG = 3,
5053

51-
/** Detailed trace level logging should only be used for development, should only be set
54+
/**
55+
* Detailed trace level logging should only be used for development, should only be set
5256
* in a development environment.
5357
*/
54-
TRACE = 4,
58+
VERBOSE = 4,
5559

5660
/** Used to set the logging level to include all logging */
5761
ALL = 9999,
5862
}
5963

6064
/**
6165
* This is equivalent to:
62-
* type LogLevelString = 'NONE' | TERMINAL' | 'CRITICAL' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE' | 'ALL';
66+
* type LogLevelString = 'NONE' | TERMINAL' | 'CRITICAL' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'VERBOSE' | 'ALL';
6367
*/
6468
export type DiagLogLevelString = keyof typeof DiagLogLevel;
6569

6670
/**
67-
* Mapping from DiagLogger function name to logging level
71+
* Mapping from DiagLogger function name to Legacy Logger function used if
72+
* the logger instance doesn't have the DiagLogger function
6873
*/
74+
const fallbackLoggerFuncMap: { [n: string]: keyof Logger } = {
75+
terminal: 'error',
76+
critical: 'error',
77+
error: 'error',
78+
warn: 'warn',
79+
info: 'info',
80+
debug: 'debug',
81+
verbose: 'debug',
82+
forcedInfo: 'info',
83+
};
84+
85+
/** Mapping from DiagLogger function name to logging level. */
6986
const levelMap: { n: keyof DiagLogger; l: DiagLogLevel; f?: boolean }[] = [
7087
{ n: 'terminal', l: DiagLogLevel.TERMINAL },
7188
{ n: 'critical', l: DiagLogLevel.CRITICAL },
7289
{ n: 'error', l: DiagLogLevel.ERROR },
7390
{ n: 'warn', l: DiagLogLevel.WARN },
7491
{ n: 'info', l: DiagLogLevel.INFO },
7592
{ n: 'debug', l: DiagLogLevel.DEBUG },
76-
{ n: 'trace', l: DiagLogLevel.TRACE },
93+
{ n: 'verbose', l: DiagLogLevel.VERBOSE },
7794
{ n: 'forcedInfo', l: DiagLogLevel.INFO, f: true },
7895
];
7996

8097
/**
81-
* An Immutable Diagnostic logger that limits the reported diagnostic log messages to those at the
82-
* maximum logging level or lower.
83-
* This can be useful to reduce the amount of logging used for a specific component based on any
84-
* local configuration
85-
*/
86-
87-
/**
88-
* Create a Diagnostic filter logger which limits the logged messages to the defined provided maximum
89-
* logging level or lower. This can be useful to reduce the amount of logging used for the system or
90-
* for a specific component based on any local configuration.
98+
* Create a Diagnostic logger which limits the messages that are logged via the wrapped logger based on whether the
99+
* message has a {@link DiagLogLevel} equal to the maximum logging level or lower, unless the {@link DiagLogLevel} is
100+
* NONE which will return a noop logger instance. This can be useful to reduce the amount of logging used for the
101+
* system or for a specific component based on any local configuration.
91102
* If you don't supply a logger it will use the global api.diag as the destination which will use the
92103
* current logger and any filtering it may have applied.
93104
* To avoid / bypass any global level filtering you should pass the current logger returned via
@@ -98,20 +109,24 @@ const levelMap: { n: keyof DiagLogger; l: DiagLogLevel; f?: boolean }[] = [
98109
* @returns {DiagLogger}
99110
*/
100111

101-
export function diagLogLevelFilter(
112+
export function createLogLevelDiagLogger(
102113
maxLevel: DiagLogLevel,
103114
logger?: DiagLogger | null
104115
): DiagLogger {
105-
if (!logger) {
106-
logger = DiagAPI.inst() as DiagLogger;
107-
}
108-
109116
if (maxLevel < DiagLogLevel.NONE) {
110117
maxLevel = DiagLogLevel.NONE;
111118
} else if (maxLevel > DiagLogLevel.ALL) {
112119
maxLevel = DiagLogLevel.ALL;
113120
}
114121

122+
if (maxLevel === DiagLogLevel.NONE) {
123+
return createNoopDiagLogger();
124+
}
125+
126+
if (!logger) {
127+
logger = DiagAPI.instance().getLogger();
128+
}
129+
115130
function _filterFunc(
116131
theLogger: DiagLogger,
117132
funcName: keyof DiagLogger,
@@ -121,7 +136,8 @@ export function diagLogLevelFilter(
121136
if (isForced || maxLevel >= theLevel) {
122137
return function () {
123138
const orgArguments = arguments as unknown;
124-
const theFunc = theLogger[funcName];
139+
const theFunc =
140+
theLogger[funcName] || theLogger[fallbackLoggerFuncMap[funcName]];
125141
if (theFunc && typeof theFunc === 'function') {
126142
return theFunc.apply(
127143
logger,
@@ -134,9 +150,9 @@ export function diagLogLevelFilter(
134150
}
135151

136152
const newLogger = {} as DiagLogger;
137-
for (let lp = 0; lp < levelMap.length; lp++) {
138-
const name = levelMap[lp].n;
139-
newLogger[name] = _filterFunc(logger, name, levelMap[lp].l, levelMap[lp].f);
153+
for (let i = 0; i < levelMap.length; i++) {
154+
const name = levelMap[i].n;
155+
newLogger[name] = _filterFunc(logger, name, levelMap[i].l, levelMap[i].f);
140156
}
141157

142158
return newLogger;

0 commit comments

Comments
 (0)