Skip to content

Commit 9d270a2

Browse files
Merge branch 'julien/log-level-filtering' of github.com:y-nk/nest into y-nk-julien/log-level-filtering
2 parents 3c6c9ea + bb9e847 commit 9d270a2

File tree

2 files changed

+85
-2
lines changed

2 files changed

+85
-2
lines changed

packages/common/services/logger.service.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,51 @@ import { isObject } from '../utils/shared.utils';
33
import { ConsoleLogger } from './console-logger.service';
44
import { isLogLevelEnabled } from './utils';
55

6+
const LOG_LEVELS = [
7+
'verbose',
8+
'debug',
9+
'log',
10+
'warn',
11+
'error',
12+
'fatal',
13+
] as const satisfies string[];
14+
15+
/**
16+
* @publicApi
17+
*/
18+
export type LogLevel = (typeof LOG_LEVELS)[number];
19+
20+
/**
21+
* @publicApi
22+
*/
23+
export function isLogLevel(maybeLogLevel: any): maybeLogLevel is LogLevel {
24+
return LOG_LEVELS.includes(maybeLogLevel);
25+
}
26+
627
/**
728
* @publicApi
829
*/
9-
export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose' | 'fatal';
30+
export function filterLogLevels(parseableString = ''): LogLevel[] {
31+
const sanitizedSring = parseableString.replaceAll(' ', '').toLowerCase();
32+
33+
if (sanitizedSring[0] === '>') {
34+
const orEqual = sanitizedSring[1] === '=';
35+
36+
const logLevelIndex = (LOG_LEVELS as string[]).indexOf(
37+
sanitizedSring.substring(orEqual ? 2 : 1),
38+
);
39+
40+
if (logLevelIndex === -1) {
41+
throw new Error(`parse error (unknown log level): ${sanitizedSring}`);
42+
}
43+
44+
return LOG_LEVELS.slice(orEqual ? logLevelIndex : logLevelIndex + 1);
45+
} else if (sanitizedSring.includes(',')) {
46+
return sanitizedSring.split(',').filter(isLogLevel);
47+
}
48+
49+
return isLogLevel(sanitizedSring) ? [sanitizedSring] : LOG_LEVELS;
50+
}
1051

1152
/**
1253
* @publicApi

packages/common/test/services/logger.service.spec.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,51 @@
11
import { expect } from 'chai';
22
import 'reflect-metadata';
33
import * as sinon from 'sinon';
4-
import { ConsoleLogger, Logger, LoggerService, LogLevel } from '../../services';
4+
import {
5+
ConsoleLogger,
6+
filterLogLevels,
7+
Logger,
8+
LoggerService,
9+
LogLevel,
10+
} from '../../services';
511

612
describe('Logger', () => {
13+
describe('[log helpers]', () => {
14+
describe('when using filterLogLevels', () => {
15+
it('should correctly parse an exclusive range', () => {
16+
const returned = filterLogLevels('>warn');
17+
expect(returned).to.deep.equal(['error', 'fatal']);
18+
});
19+
20+
it('should correctly parse an inclusive range', () => {
21+
const returned = filterLogLevels('>=warn');
22+
expect(returned).to.deep.equal(['warn', 'error', 'fatal']);
23+
});
24+
25+
it('should correctly parse a string list', () => {
26+
const returned = filterLogLevels('verbose,warn,fatal');
27+
expect(returned).to.deep.equal(['verbose', 'warn', 'fatal']);
28+
});
29+
30+
it('should correctly parse a single log level', () => {
31+
const returned = filterLogLevels('debug');
32+
expect(returned).to.deep.equal(['debug']);
33+
});
34+
35+
it('should return all otherwise', () => {
36+
const returned = filterLogLevels();
37+
expect(returned).to.deep.equal([
38+
'verbose',
39+
'debug',
40+
'log',
41+
'warn',
42+
'error',
43+
'fatal',
44+
]);
45+
});
46+
});
47+
});
48+
749
describe('[static methods]', () => {
850
describe('when the default logger is used', () => {
951
let processStdoutWriteSpy: sinon.SinonSpy;

0 commit comments

Comments
 (0)