Skip to content

Commit

Permalink
feat(core): add stringToLogLevel utility
Browse files Browse the repository at this point in the history
  • Loading branch information
pichlermarc committed Feb 13, 2025
1 parent cf445a5 commit 66d4704
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ For semantic convention package changes, see the [semconv CHANGELOG](packages/se
* feat(sdk-trace-base): add stack trace warning to debug instrumentation [#5363](https://github.com/open-telemetry/opentelemetry-js/pull/5363) @neilfordyce
* feat(core): add more scalable replacements for getEnv(), getEnvWithoutDefaults() [#5443](https://github.com/open-telemetry/opentelemetry-js/pull/5443) @pichlermarc
* refactor(exporter-jaeger): migrate away from getEnv() [#5464](https://github.com/open-telemetry/opentelemetry-js/pull/5464) @pichlermarc
* feat(core): add stringToLogLevel utility [#5475](https://github.com/open-telemetry/opentelemetry-js/pull/5475) @pichlermarc

### :bug: (Bug Fix)

Expand Down
1 change: 1 addition & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ All notable changes to experimental packages in this project will be documented
* refactor(exporter-prometheus): remove unnecessary isNaN() check [#5377](https://github.com/open-telemetry/opentelemetry-js/pull/5377) @cjihrig
* refactor(sdk-node): move code to auto-instantiate propagators into utils [#5355](https://github.com/open-telemetry/opentelemetry-js/pull/5355) @pichlermarc
* chore: unpin `@opentelemetry/semantic-conventions` dep to allow better de-duplication in installs [#5439](https://github.com/open-telemetry/opentelemetry-js/pull/5439) @trentm
* refactor(sdk-node): migrate away from getEnv() [#5475](https://github.com/open-telemetry/opentelemetry-js/pull/5475) @pichlermarc

## 0.57.0

Expand Down
1 change: 1 addition & 0 deletions packages/opentelemetry-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export { merge } from './utils/merge';
export { TimeoutError, callWithTimeout } from './utils/timeout';
export { isUrlIgnored, urlMatches } from './utils/url';
export { BindOnceFuture } from './utils/callback';
export { stringToLogLevel } from './utils/configuration';
import { _export } from './internal/exporter';
export const internal = {
_export,
Expand Down
51 changes: 51 additions & 0 deletions packages/opentelemetry-core/src/utils/configuration.ts
Original file line number Diff line number Diff line change
@@ -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 { diag, DiagLogLevel } from '@opentelemetry/api';
import { inspect } from 'util';

const logLevelMap: { [key: string]: DiagLogLevel } = {
ALL: DiagLogLevel.ALL,
VERBOSE: DiagLogLevel.VERBOSE,
DEBUG: DiagLogLevel.DEBUG,
INFO: DiagLogLevel.INFO,
WARN: DiagLogLevel.WARN,
ERROR: DiagLogLevel.ERROR,
NONE: DiagLogLevel.NONE,
};

/**
* Convert a string to a {@link DiagLogLevel}, defaults to {@link DiagLogLevel} if the log level does not exist or undefined if the input is undefined.
* @param value
*/
export function stringToLogLevel(
value: string | undefined
): DiagLogLevel | undefined {
if (value == null) {
// don't fall back to default - no value set has different semantics for ús than an incorrect value (do not set vs. fall back to default)
return undefined;
}

const resolvedLogLevel = logLevelMap[value.toUpperCase()];

if (resolvedLogLevel == null) {
diag.warn(
`Unknown log level ${inspect(value)}, expected one of ${inspect(Object.keys(logLevelMap))}, using default`
);
return DiagLogLevel.INFO;
}

return resolvedLogLevel;
}
54 changes: 54 additions & 0 deletions packages/opentelemetry-core/test/common/utils/configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 { stringToLogLevel } from '../../../src';
import * as assert from 'assert';
import * as sinon from 'sinon';
import { diag, DiagLogLevel } from '@opentelemetry/api';

describe('stringToLogLevel', function () {
afterEach(function () {
sinon.restore();
});

it('should map valid string to log level', function () {
assert.strictEqual(stringToLogLevel('ALL'), DiagLogLevel.ALL);
assert.strictEqual(stringToLogLevel('VERBOSE'), DiagLogLevel.VERBOSE);
assert.strictEqual(stringToLogLevel('DEBUG'), DiagLogLevel.DEBUG);
assert.strictEqual(stringToLogLevel('INFO'), DiagLogLevel.INFO);
assert.strictEqual(stringToLogLevel('WARN'), DiagLogLevel.WARN);
assert.strictEqual(stringToLogLevel('ERROR'), DiagLogLevel.ERROR);
assert.strictEqual(stringToLogLevel('NONE'), DiagLogLevel.NONE);
});

it('should ignore casing when resolving', function () {
assert.strictEqual(stringToLogLevel('error'), DiagLogLevel.ERROR);
assert.strictEqual(stringToLogLevel('eRRoR'), DiagLogLevel.ERROR);
});

it('should return undefined on undefined input', function () {
assert.strictEqual(stringToLogLevel(undefined), undefined);
});

it('should return undefined on null input', function () {
assert.strictEqual(stringToLogLevel(undefined), undefined);
});

it('should fall back to INFO and warn on input that cannot be mapped', function () {
const warnStub = sinon.stub(diag, 'warn');
assert.strictEqual(stringToLogLevel('does not exist'), DiagLogLevel.INFO);
sinon.assert.calledOnceWithMatch(warnStub, 'Unknown');
});
});

0 comments on commit 66d4704

Please sign in to comment.