Skip to content

dsrvlabs/nest-logger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

11 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

nest-logger

NestJS Winston Logger Module with HTTP Request/Response Logging

Features

  • ๐ŸŽฏ Winston ๊ธฐ๋ฐ˜ ๋กœ๊น… ๋ชจ๋“ˆ
  • ๐Ÿ“ HTTP ์š”์ฒญ/์‘๋‹ต ๊ฐ„๊ฒฐํ•œ ๋กœ๊น… (method, url, statusCode, responseTime)
  • โฑ๏ธ ์‘๋‹ต ์‹œ๊ฐ„ ์ธก์ • (์ดˆ ๋‹จ์œ„)

Installation

# pnpm
pnpm add git+https://github.com/dsrvlabs/nest-logger.git

# npm
npm install git+https://github.com/dsrvlabs/nest-logger.git

# yarn
yarn add git+https://github.com/dsrvlabs/nest-logger.git

์ฐธ๊ณ : ๋นŒ๋“œ๋œ ํŒŒ์ผ์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด pnpm approve-builds ์—†์ด ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Usage

1. Module Import

import { Module } from '@nestjs/common';
import { LoggerModule } from 'nest-logger';

@Module({
  imports: [LoggerModule],
  // ...
})
export class AppModule {}

2. HTTP ๋กœ๊น… Middleware ์„ค์ •

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerModule, HttpLoggerMiddleware } from 'nest-logger';

@Module({
  imports: [LoggerModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(HttpLoggerMiddleware).forRoutes('*');
  }
}

๋˜๋Š” ํŠน์ • ๊ฒฝ๋กœ์—๋งŒ ์ ์šฉ:

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerModule, HttpLoggerMiddleware } from 'nest-logger';

@Module({
  imports: [LoggerModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(HttpLoggerMiddleware).forRoutes('api/*'); // ํŠน์ • ๊ฒฝ๋กœ์—๋งŒ ์ ์šฉ
  }
}

3. Logger Service ์‚ฌ์šฉ

import { Injectable } from '@nestjs/common';
import { LoggerService } from 'nest-logger';

@Injectable()
export class YourService {
  constructor(private readonly logger: LoggerService) {}

  someMethod() {
    // context์— ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๋ช…์‹œ์ ์œผ๋กœ ์ „๋‹ฌ
    this.logger.log(
      'Info message',
      `${this.constructor.name}.${this.someMethod.name}`,
    );
    this.logger.error(
      'Error message',
      'stack trace',
      `${this.constructor.name}.${this.someMethod.name}`,
    );
    this.logger.warn(
      'Warning message',
      `${this.constructor.name}.${this.someMethod.name}`,
    );
    this.logger.debug(
      'Debug message',
      `${this.constructor.name}.${this.someMethod.name}`,
    );
    this.logger.verbose(
      'Verbose message',
      `${this.constructor.name}.${this.someMethod.name}`,
    );
  }

  // ๋˜๋Š” ํด๋ž˜์Šค ์ด๋ฆ„๋งŒ ์‚ฌ์šฉ
  anotherMethod() {
    this.logger.log('Info message', this.constructor.name);
  }

  // ๋˜๋Š” ํ•จ์ˆ˜ ์ด๋ฆ„๋งŒ ์‚ฌ์šฉ
  thirdMethod() {
    this.logger.log('Info message', this.thirdMethod.name);
  }
}

4. Winston Logger ์ง์ ‘ ์‚ฌ์šฉ

winston Logger ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

import { Injectable, Inject } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-logger';
import type { Logger } from 'winston';

@Injectable()
export class YourService {
  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  someMethod() {
    // winston Logger์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    this.logger.info('Info message', { context: 'YourService', userId: 123 });
    j;
    this.logger.error('Error message', {
      error: new Error('Something went wrong'),
    });
    this.logger.warn('Warning message', { data: { key: 'value' } });
    this.logger.debug('Debug message', { metadata: 'some data' });

    // winston์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ ์‚ฌ์šฉ
    this.logger.log({
      level: 'info',
      message: 'Custom log',
      timestamp: new Date().toISOString(),
      metadata: { custom: 'data' },
    });
  }
}

๋˜๋Š” LoggerService๋ฅผ ํ†ตํ•ด winston Logger ์ธ์Šคํ„ด์Šค ๊ฐ€์ ธ์˜ค๊ธฐ:

import { Injectable } from '@nestjs/common';
import { LoggerService } from 'nest-logger';

@Injectable()
export class YourService {
  constructor(private readonly loggerService: LoggerService) {}

  someMethod() {
    const winstonLogger = this.loggerService.getWinstonLogger();

    // winston Logger ์ง์ ‘ ์‚ฌ์šฉ
    winstonLogger.info('Info message', { context: 'YourService' });
    winstonLogger.error('Error message', { error: new Error('Error') });
  }
}

Log Output

HTTP ์š”์ฒญ/์‘๋‹ต ๋กœ๊ทธ๋Š” ์ค„๋ฐ”๊ฟˆ ์—†์ด ํ•œ ์ค„๋กœ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

Request Log (REQ)

2024-01-01 12:00:00 info [HttpLogger] REQ {"method":"GET","url":"/api/users","body":{"name":"test"},"query":{"page":"1"},"params":{"id":"123"}}

Response Log (RES)

2024-01-01 12:00:00 info [HttpLogger] RES {"method":"GET","url":"/api/users","statusCode":200,"responseTime":"0.123s","body":{"data":"result"}}

Custom Configuration

import { LoggerModule } from 'nest-logger';
import * as winston from 'winston';

@Module({
  imports: [
    LoggerModule.forRoot({
      transports: [
        new winston.transports.File({
          filename: 'error.log',
          level: 'error',
        }),
        new winston.transports.Console(),
      ],
    }),
  ],
})
export class AppModule {}

Development

ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜์ •ํ•œ ํ›„ GitHub์— ํ‘ธ์‹œํ•˜๊ธฐ ์ „์— ๋ฐ˜๋“œ์‹œ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

# ๋นŒ๋“œ ์‹คํ–‰
pnpm build

# ๋˜๋Š” prepush ์Šคํฌ๋ฆฝํŠธ ์‚ฌ์šฉ (๋นŒ๋“œ + git add dist/)
pnpm run prepush

# ์ปค๋ฐ‹ ๋ฐ ํ‘ธ์‹œ
git commit -m "Your changes"
git push

์ค‘์š”: ์†Œ์Šค ์ฝ”๋“œ(src/)๋ฅผ ์ˆ˜์ •ํ•œ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ๋นŒ๋“œ ํ›„ ํ‘ธ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ ์˜ค๋ž˜๋œ ๋นŒ๋“œ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Git Hook ์‚ฌ์šฉ (์„ ํƒ์‚ฌํ•ญ)

์ž๋™์œผ๋กœ ๋นŒ๋“œํ•˜๋ ค๋ฉด .git/hooks/pre-push hook์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

chmod +x .git/hooks/pre-push

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด git push ์‹œ ์ž๋™์œผ๋กœ ๋นŒ๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

License

MIT

About

NestJS Winston Logger Module

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published