Skip to content

Commit ef827f7

Browse files
authored
Merge pull request #24 from Libertech-FR/implements-logger
logger feature
2 parents 303b9a4 + a26f662 commit ef827f7

File tree

9 files changed

+173
-405
lines changed

9 files changed

+173
-405
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ NAME_QUEUE="backend"
33
SECRET="secret"
44

55
REDIS_URI="redis://sesame-redis:6379"
6-
MONGO_URI="mongodb://sesame-mongo:27017/sesame"
6+
MONGO_URI="mongodb://sesame-mongodb:27017/sesame"
77
SWAGGER_PATH="/swagger"
88
SWAGGER_API="swagger.json"

LICENSE

Whitespace-only changes.

src/_common/filters/all-exception.filter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Response } from 'express';
33
@Catch()
44
export class AllExceptionFilter implements ExceptionFilter {
55
catch(exception: unknown, host: ArgumentsHost) {
6-
Logger.debug(exception['message'], 'MongooseValidationFilter');
6+
Logger.debug(exception['message'], 'AllExceptionFilter');
77

88
const ctx = host.switchToHttp();
99
const response = ctx.getResponse<Response>();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { LogLevel } from '@nestjs/common';
2+
3+
export function getLogLevel(logLevel?: string): LogLevel[] {
4+
const logLevelMap: Record<LogLevel | string, LogLevel[]> = {
5+
fatal: ['fatal'],
6+
error: ['error', 'fatal'],
7+
warn: ['error', 'fatal', 'warn'],
8+
info: ['error', 'fatal', 'warn', 'log'],
9+
debug: ['error', 'fatal', 'warn', 'log', 'debug'],
10+
verbose: ['error', 'fatal', 'warn', 'log', 'debug', 'verbose'],
11+
};
12+
return logLevelMap[logLevel] || logLevelMap['info'];
13+
}

src/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface MongoosePlugin {
1212
}
1313
export interface ConfigInstance {
1414
application: {
15+
logLevel: string;
1516
bodyParser: {
1617
limit: string;
1718
};
@@ -37,13 +38,13 @@ export interface ConfigInstance {
3738
api: string;
3839
options: SwaggerCustomOptions;
3940
};
40-
logLevel: string;
4141
nameQueue: string;
4242
secret: string;
4343
}
4444

4545
export default (): ConfigInstance => ({
4646
application: {
47+
logLevel: process.env['LOG_LEVEL'] || 'info',
4748
bodyParser: {
4849
limit: '500mb',
4950
},
@@ -91,7 +92,6 @@ export default (): ConfigInstance => ({
9192
// jwksUri: 'http://127.0.0.1:2000/jwks',
9293
},
9394
},
94-
logLevel: process.env['LOG_LEVEL'] || 'info',
9595
nameQueue: process.env['NAME_QUEUE'] || 'backend',
9696
secret: process.env['SECRET'] || 'mySecret',
9797
swagger: {

src/core/logger/internal.logger.ts

Lines changed: 143 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,149 @@
1-
import { ConsoleLogger } from '@nestjs/common';
1+
import { ConsoleLogger, Injectable, LogLevel } from '@nestjs/common';
2+
import { MongooseModuleOptions } from '@nestjs/mongoose';
3+
import { Request } from 'express';
4+
import { Connection, connect } from 'mongoose';
25

6+
export interface InternalLoggerOptions {
7+
logLevel: LogLevel[];
8+
mongoose: {
9+
uri: string;
10+
options: MongooseModuleOptions;
11+
};
12+
}
13+
14+
export enum InternalLogLevel {
15+
CONSOLE = 'console',
16+
DB = 'db',
17+
}
18+
19+
export interface InternalLogOptions {
20+
target: InternalLogLevel[];
21+
request?: Request;
22+
createdBy?: string;
23+
}
24+
25+
@Injectable()
326
export class InternalLogger extends ConsoleLogger {
4-
public constructor() {
27+
protected connection: Connection;
28+
29+
public constructor(private _options?: InternalLoggerOptions) {
530
super();
31+
this.setLogLevels(_options?.logLevel);
32+
}
33+
34+
public async initialize() {
35+
super.log('Initializing logs database connection...', this.constructor.name);
36+
try {
37+
const mongoose = await connect(this._options.mongoose.uri, this._options.mongoose.options);
38+
this.connection = mongoose.connection;
39+
} catch (e) {
40+
super.error('Failed to connect to the logs database', e, this.constructor.name);
41+
setTimeout(() => this.initialize(), 5000);
42+
}
643
}
744

8-
// error(message: any, stack?: string, context?: string) {
9-
// // @ts-ignore
10-
// super.error(...arguments);
11-
// }
12-
//
13-
// warn(message: any, context?: string) {
14-
// // @ts-ignore
15-
// super.warn(...arguments);
16-
// }
17-
//
18-
// log(message: any, context?: string) {
19-
// // @ts-ignore
20-
// super.log(...arguments);
21-
// }
22-
//
23-
// debug(message: any, context?: string) {
24-
// // @ts-ignore
25-
// super.debug(...arguments);
26-
// }
27-
//
28-
// verbose(message: any, context?: string) {
29-
// // @ts-ignore
30-
// super.verbose(...arguments);
31-
// }
32-
//
33-
// fatal(message: any, context?: string) {
34-
// // @ts-ignore
35-
// super.error(...arguments);
36-
// }
45+
error(message: any, ...optionalParams: [...any, string?]) {
46+
const [options] = optionalParams;
47+
//TODO: fix optionalParams system
48+
const stack = optionalParams[optionalParams.length - (optionalParams.length === 3 ? -2 : -1)];
49+
const context = optionalParams.length === 3 ? optionalParams[optionalParams.length - 1] : null;
50+
if (options instanceof Object) {
51+
if (options.target.includes(InternalLogLevel.DB)) this.commonLogDb({ level: 'error', message, context }, options);
52+
if (!options.target.includes(InternalLogLevel.CONSOLE)) return;
53+
}
54+
const args = [stack];
55+
if (context) args.push(context);
56+
super.error(...[message, ...args]);
57+
}
58+
59+
warn(message: any, ...optionalParams: [...any, string?]) {
60+
const [options] = optionalParams;
61+
const context = optionalParams[optionalParams.length - 1];
62+
if (options instanceof Object) {
63+
if (options.target.includes(InternalLogLevel.DB)) this.commonLogDb({ level: 'warn', message, context }, options);
64+
if (!options.target.includes(InternalLogLevel.CONSOLE)) return;
65+
}
66+
const args = [];
67+
if (context) args.push(context);
68+
super.warn(...[message, ...args]);
69+
}
70+
71+
log(message: any, ...optionalParams: [...any, string?]) {
72+
const [options] = optionalParams;
73+
const context = optionalParams[optionalParams.length - 1];
74+
if (options instanceof Object) {
75+
if (options.target.includes(InternalLogLevel.DB)) this.commonLogDb({ level: 'log', message, context }, options);
76+
if (!options.target.includes(InternalLogLevel.CONSOLE)) return;
77+
}
78+
const args = [];
79+
if (context) args.push(context);
80+
super.log(...[message, ...args]);
81+
}
82+
83+
debug(message: any, ...optionalParams: [...any, string?]) {
84+
const [options] = optionalParams;
85+
const context = optionalParams[optionalParams.length - 1];
86+
if (options instanceof Object) {
87+
if (options.target.includes(InternalLogLevel.DB)) this.commonLogDb({ level: 'debug', message, context }, options);
88+
if (!options.target.includes(InternalLogLevel.CONSOLE)) return;
89+
}
90+
const args = [];
91+
if (context) args.push(context);
92+
super.debug(...[message, ...args]);
93+
}
94+
95+
verbose(message: any, ...optionalParams: [...any, string?]) {
96+
const [options] = optionalParams;
97+
const context = optionalParams[optionalParams.length - 1];
98+
if (options instanceof Object) {
99+
if (options.target.includes(InternalLogLevel.DB))
100+
this.commonLogDb({ level: 'verbose', message, context }, options);
101+
if (!options.target.includes(InternalLogLevel.CONSOLE)) return;
102+
}
103+
const args = [];
104+
if (context) args.push(context);
105+
super.verbose(...[message, ...args]);
106+
}
107+
108+
fatal(message: any, ...optionalParams: [...any, string?]) {
109+
const [options] = optionalParams;
110+
const context = optionalParams[optionalParams.length - 1];
111+
if (options instanceof Object) {
112+
if (options.target.includes(InternalLogLevel.DB)) this.commonLogDb({ level: 'fatal', message, context }, options);
113+
if (!options.target.includes(InternalLogLevel.CONSOLE)) return;
114+
}
115+
const args = [];
116+
if (context) args.push(context);
117+
super.fatal(...[message, ...args]);
118+
}
119+
120+
private commonLogDb(
121+
payload: {
122+
level: string;
123+
message: any;
124+
context?: string;
125+
},
126+
options: InternalLogOptions,
127+
): void {
128+
console.log('logging');
129+
const data = payload.message instanceof Object ? payload.message : { message: payload.message };
130+
const metadata = {
131+
createdAt: new Date(),
132+
createdBy: options.createdBy || 'console',
133+
};
134+
if (payload.context) metadata['context'] = payload.context;
135+
// TODO: fix request user structure
136+
if (options.request && !options.createdBy) metadata['createdBy'] = (options.request.user as any)?.id;
137+
138+
try {
139+
this.connection.collection('logs').insertOne({
140+
level: payload.level,
141+
data,
142+
metadata,
143+
});
144+
} catch (e) {
145+
super.error('Failed to log to the database', e, this.constructor.name);
146+
console.log('Failed to log to the database', e);
147+
}
148+
}
37149
}

0 commit comments

Comments
 (0)