Skip to content

Commit 883fa99

Browse files
committed
feat: Implement CustomLogger class
1 parent b2a567d commit 883fa99

File tree

8 files changed

+96
-1
lines changed

8 files changed

+96
-1
lines changed

.eslintrc.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module.exports = {
2828
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
2929
leadingUnderscore: 'allow',
3030
},
31-
{ selector: 'property', format: ['camelCase', 'UPPER_CASE'], leadingUnderscore: 'allow' },
31+
{ selector: 'property', format: ['camelCase', 'PascalCase', 'UPPER_CASE'], leadingUnderscore: 'allow' },
3232
{ selector: 'property', modifiers: ['requiresQuotes'], format: null },
3333
{ selector: 'method', format: ['camelCase'], leadingUnderscore: 'allow' },
3434
{ selector: 'function', format: ['camelCase', 'PascalCase'] },
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { TestAppLogger } from '../testing/logging';
2+
import { ApplicationLogLevel, CustomLogger } from './custom.logger';
3+
4+
describe('CustomLogger', () => {
5+
it('should be ok', () => {
6+
const logger = new CustomLogger();
7+
expect(logger).toBeDefined();
8+
expect(logger).toBeInstanceOf(CustomLogger);
9+
});
10+
11+
describe('ApplicationLogLevel', () => {
12+
it('should log the expected amount of messages with default logging enabled', () => {
13+
const logger = new TestAppLogger({
14+
logLevel: ApplicationLogLevel.Default,
15+
});
16+
logger.debug('hello world');
17+
logger.verbose('hello world');
18+
logger.log('hello world');
19+
logger.warn('hello world');
20+
logger.error('hello world');
21+
logger.fatal('hello world');
22+
expect(logger.printMessages).toHaveBeenCalledTimes(4);
23+
});
24+
25+
it('should log the expected amount of messages with verbose logging enabled', () => {
26+
const logger = new TestAppLogger({
27+
logLevel: ApplicationLogLevel.Verbose,
28+
});
29+
logger.debug('hello world');
30+
logger.verbose('hello world');
31+
logger.log('hello world');
32+
logger.warn('hello world');
33+
logger.error('hello world');
34+
logger.fatal('hello world');
35+
expect(logger.printMessages).toHaveBeenCalledTimes(6);
36+
});
37+
});
38+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ConsoleLogger } from '@nestjs/common';
2+
3+
/**
4+
* The application log level.
5+
*/
6+
export const ApplicationLogLevel = {
7+
Default: 'default',
8+
Verbose: 'verbose',
9+
} as const;
10+
export type ApplicationLogLevel = (typeof ApplicationLogLevel)[keyof typeof ApplicationLogLevel];
11+
12+
/**
13+
* The custom application logger. This logger extends the NestJS console logger, but
14+
* simplifies the API to set the application's log levels.
15+
* @example
16+
* // main.ts
17+
* const app = await NestFactory.create(AppModule, {
18+
* logger: new CustomLogger({ logLevel: ApplicationLogLevel.Verbose }),
19+
* });
20+
*/
21+
export class CustomLogger extends ConsoleLogger {
22+
constructor(options?: { logLevel?: ApplicationLogLevel; context?: string }) {
23+
super();
24+
const { logLevel, context } = { logLevel: 'default', ...options };
25+
if (logLevel === ApplicationLogLevel.Verbose) {
26+
this.setLogLevels(['debug', 'verbose', 'log', 'warn', 'error', 'fatal']);
27+
} else {
28+
this.setLogLevels(['log', 'warn', 'error', 'fatal']);
29+
}
30+
if (context) {
31+
this.setContext(context);
32+
}
33+
}
34+
}
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './custom.logger';

packages/nest-utils/src/main.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Otherwise, they will not be included into the bundle.
44
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55
export * from './env';
6+
export * from './logging';
67
export * from './transformers';
78

89
// As long as NestJS does not support TypeScript's newer resolution algorithms like 'Node16',

packages/nest-utils/src/testing.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55
export * from './testing/container';
66
export * from './testing/supertest';
7+
export * from './testing/logging';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './test.logger';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { CustomLogger } from '../../logging/custom.logger';
2+
3+
/**
4+
* A custom logger for testing purposes. Replaces `printMessages` with a mocked function
5+
* that can be spied on.
6+
* @example
7+
* const logger = new TestAppLogger();
8+
* logger.debug('hello world');
9+
* expect(logger.printMessages).toHaveBeenCalledTimes(1);
10+
*
11+
* // Or hand it over to TestContainer
12+
* const container = await TestContainer.create({
13+
* logger,
14+
* // ...
15+
* });
16+
*/
17+
export class TestAppLogger extends CustomLogger {
18+
printMessages = vitest.fn();
19+
}

0 commit comments

Comments
 (0)