Skip to content

Commit 9ee6b88

Browse files
author
Mario Moreno
committed
add file log
1 parent 4955b8a commit 9ee6b88

File tree

10 files changed

+101
-20
lines changed

10 files changed

+101
-20
lines changed

.env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
TZ=America/Buenos_Aires
2+
3+
LOG_FILE_PATH=./logs/app.log
4+
LOG_FILE_ENABLED=false

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
TZ=UTC
2+
3+
LOG_FILE_PATH=./logs/app.log
4+
LOG_FILE_ENABLED=false

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@ Logger global interceptor library for Nest apps
88
$ npm install @mariomorenodev/nest-response-logger
99
```
1010

11+
Copy the variables from the `.env.example` file to the `.env` file
12+
13+
```bash
14+
$ cp .env.example .env
15+
```
16+
17+
Or add variables to the environment
18+
19+
```bash
20+
TZ=America/Buenos_Aires
21+
22+
LOG_FILE_PATH=./logs/app.log
23+
LOG_FILE_ENABLED=false
24+
```
1125
## Usage
1226

1327
Add the NestResponseLogger service globally in the `main.ts` file:

libs/nest-response-logger/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@mariomorenodev/nest-response-logger",
3-
"version": "1.0.7",
3+
"version": "1.0.8",
44
"description": "Logger global interceptor library for Nest apps",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -26,6 +26,7 @@
2626
"@nestjs/core": "^10.0.0",
2727
"@nestjs/platform-express": "^10.0.0",
2828
"moment": "^2.29.4",
29+
"moment-timezone": "^0.5.43",
2930
"reflect-metadata": "^0.1.13",
3031
"rxjs": "^7.8.1"
3132
},

libs/nest-response-logger/src/logger.interceptor.spec.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('LoggerInterceptor', () => {
1919
jest.clearAllMocks();
2020
});
2121

22-
it('Registrar log cuando la respuesta es correcta y enableLog es verdadero', async () => {
22+
it('Record log when response is correct and enableLog is true', async () => {
2323
const value = { enableLog: true };
2424
const context = createMockContext(HttpStatus.OK);
2525
const next = createMockNext({ enableLog: true });
@@ -31,7 +31,7 @@ describe('LoggerInterceptor', () => {
3131
expect(result).toEqual(value);
3232
});
3333

34-
it('No Registrar log cuando la respuesta es correcta y enableLog es falso', async () => {
34+
it('Don not log when response is correct and enableLog log es false', async () => {
3535
const value = { enableLog: false };
3636
const context = createMockContext(HttpStatus.OK);
3737
const next = createMockNext({ enableLog: false });
@@ -43,7 +43,7 @@ describe('LoggerInterceptor', () => {
4343
expect(result).toEqual(value);
4444
});
4545

46-
it('Registrar log cuando la respuesta es de error', async () => {
46+
it('Record log when response is error', async () => {
4747
const value = new HttpException('Internal server error', HttpStatus.OK);
4848
const context = createMockContext(HttpStatus.OK);
4949
const next = createMockNext(
@@ -57,7 +57,6 @@ describe('LoggerInterceptor', () => {
5757
expect(result).toEqual(value);
5858
});
5959

60-
// Funciones de utilidad para crear objetos simulados
6160
function createMockContext(statusCode: number): ExecutionContext {
6261
return {
6362
switchToHttp: () => ({

libs/nest-response-logger/src/logger.interceptor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export class LoggerInterceptor implements NestInterceptor {
4343
}),
4444
// Maneja el error capturado en el servicio si ocurre y registrarlo en los logs
4545
catchError((error) => {
46-
const statusCode: number = error.getStatus() ?? 500;
46+
const statusCode: number = error.getStatus ? error.getStatus() : 500;
4747
const message = error.message ?? 'Internal server error';
4848
const stack = error.stack ?? 'No stack trace';
4949

libs/nest-response-logger/src/nest-response-logger.service.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('NestResponseLoggerService', () => {
1818
jest.clearAllMocks();
1919
});
2020

21-
it('Registrar logger console log', () => {
21+
it('Log logger console log', () => {
2222
const message = 'This is a log message';
2323
const logSpy = jest.spyOn(console, 'log');
2424

@@ -31,7 +31,7 @@ describe('NestResponseLoggerService', () => {
3131
);
3232
});
3333

34-
it('Registrar logger console error', () => {
34+
it('Log logger console error', () => {
3535
const message = 'This is a error message';
3636
const errorSpy = jest.spyOn(console, 'error');
3737

@@ -44,7 +44,7 @@ describe('NestResponseLoggerService', () => {
4444
);
4545
});
4646

47-
it('Registrar logger console warn', () => {
47+
it('Log logger console warn', () => {
4848
const message = 'This is a warn message';
4949
const warnSpy = jest.spyOn(console, 'warn');
5050

@@ -57,7 +57,7 @@ describe('NestResponseLoggerService', () => {
5757
);
5858
});
5959

60-
it('Registrar logger console debug', () => {
60+
it('Log logger console debug', () => {
6161
const message = 'This is a debug message';
6262
const debugSpy = jest.spyOn(console, 'debug');
6363

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,68 @@
11
import { Injectable, LoggerService } from '@nestjs/common';
2+
import 'moment-timezone';
23
import * as moment from 'moment';
4+
import { existsSync, mkdirSync, appendFileSync } from 'fs';
35

46
@Injectable()
57
export class NestResponseLoggerService implements LoggerService {
6-
private now: string;
8+
private timezone: string;
9+
private readonly logFilePath: string;
10+
private readonly logFileEnabled: string;
11+
712
constructor() {
8-
this.now = moment(new Date()).format('DD/MM/YYYY HH:mm:ss');
13+
this.timezone = process.env.TZ || 'UTC';
14+
this.logFilePath = process.env.LOG_FILE_PATH || './logs/app.log';
15+
this.logFileEnabled = process.env.LOG_FILE_ENABLED || 'false';
16+
this.ensureLogDirectoryExists();
917
}
1018

1119
log(message: any, ...optionalParams: any[]) {
12-
console.log(`[${this.now}] [LOG] ${message}`, optionalParams);
20+
const now = this.getCurrentTime();
21+
console.log(`[${now}] [LOG] ${message}`, optionalParams);
22+
this.writeToFile(`[${now}] [LOG] ${message} ${optionalParams}`);
1323
}
1424

1525
error(message: any, ...optionalParams: any[]) {
16-
console.error(`[${this.now}] [ERROR] ${message}`, optionalParams);
26+
const now = this.getCurrentTime();
27+
console.error(`[${now}] [ERROR] ${message}`, optionalParams);
28+
this.writeToFile(`[${now}] [LOG] ${message} ${optionalParams}`);
1729
}
1830

1931
warn(message: any, ...optionalParams: any[]) {
20-
console.warn(`[${this.now}] [WARN] ${message}`, optionalParams);
32+
const now = this.getCurrentTime();
33+
console.warn(`[${now}] [WARN] ${message}`, optionalParams);
34+
this.writeToFile(`[${now}] [LOG] ${message} ${optionalParams}`);
2135
}
2236

2337
debug?(message: any, ...optionalParams: any[]) {
24-
console.debug(`[${this.now}] [DEBUG] ${message}`, optionalParams);
38+
const now = this.getCurrentTime();
39+
console.debug(`[${now}] [DEBUG] ${message}`, optionalParams);
40+
this.writeToFile(`[${now}] [LOG] ${message} ${optionalParams}`);
2541
}
2642

2743
verbose?(message: any, ...optionalParams: any[]) {
28-
console.info(`[${this.now}] [VERBOSE] ${message}`, optionalParams);
44+
const now = this.getCurrentTime();
45+
console.info(`[${now}] [VERBOSE] ${message}`, optionalParams);
46+
this.writeToFile(`[${now}] [LOG] ${message} ${optionalParams}`);
47+
}
48+
49+
private getCurrentTime(): string {
50+
return moment().tz(this.timezone).format('DD/MM/YYYY HH:mm:ss');
51+
}
52+
53+
private ensureLogDirectoryExists(): void {
54+
const logDirectory = this.logFilePath.substring(
55+
0,
56+
this.logFilePath.lastIndexOf('/'),
57+
);
58+
if (!existsSync(logDirectory)) {
59+
mkdirSync(logDirectory, { recursive: true });
60+
}
61+
}
62+
63+
private writeToFile(log: string): void {
64+
if (this.logFileEnabled === 'true') {
65+
appendFileSync(this.logFilePath, log + '\n', 'utf8');
66+
}
2967
}
3068
}

package-lock.json

Lines changed: 22 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "response-logger-library",
3-
"version": "1.0.7",
3+
"version": "1.0.8",
44
"description": "",
55
"author": "",
66
"private": true,
@@ -26,6 +26,7 @@
2626
"@nestjs/core": "^10.0.0",
2727
"@nestjs/platform-express": "^10.0.0",
2828
"moment": "^2.29.4",
29+
"moment-timezone": "^0.5.43",
2930
"reflect-metadata": "^0.1.13",
3031
"rxjs": "^7.8.1"
3132
},

0 commit comments

Comments
 (0)