winston을 사용하여 db에 log를 저장하는 방법을 배워야 했다. 처음 사용해서 많이 헷갈려서 조금 힘들었지만, 내가 생각했던 흐름대로 잘 진행되었다.
WinstonModule.forRootAsync({
useFactory: () => ({
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple(),
),
}),
],
}),
}),
// nest 로거를 winston 기반으로 체인지
app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER))
import * as TransportStream from 'winston-transport';
import { Injectable } from '@nestjs/common';
import { SubmissionLog } from './entities/submission-log.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
// 커스텀 DB 트랜스포트
@Injectable()
export class DBTransport extends TransportStream {
constructor(
@InjectRepository(SubmissionLog)
private readonly submissionLogRepository: Repository<SubmissionLog>,
) {
super();
}
async log(info: any, callback: () => void): Promise<void> {
// winston에서 처리하는 로그 정보
const { result, apiEndPoint, traceId, latency, message, submission } = info;
try {
// winston에서 받아서 db에 저장
const logEntry = this.submissionLogRepository.create({
result,
apiEndPoint,
traceId,
latency,
message,
submission,
});
await this.submissionLogRepository.save(logEntry);
} catch (error) {
console.error('DB Logging Error:', error);
}
callback();
}
}
import { Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { EntityManager, Repository } from 'typeorm';
import { SubmissionLog } from './entities/submission-log.entity';
import * as winston from 'winston';
import { DBTransport } from './db-transport';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { v4 as uuidv4 } from 'uuid';
@Injectable()
export class SubmissionLogService {
constructor(
@InjectRepository(SubmissionLog)
private readonly submissionLogRepository: Repository<SubmissionLog>,
@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: winston.Logger,
) {
// winston 로거 초기화
this.logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.colorize(),
winston.format.printf(({ timestamp, level, message }) => {
return `[${timestamp}] ${process.pid} [${level}] ${message}`;
}),
),
transports: [
new winston.transports.Console(),
new DBTransport(this.submissionLogRepository),
],
});
}
// winston 로그를 db-transport에 보내준다.
async saveLog(info: any): Promise<any> {
// 로그 작성
const traceId = uuidv4();
this.logger.info('info', {
result: info.result, // 로그 항목에 대한 예시
apiEndPoint: info.apiEndPoint,
traceId: traceId,
latency: info.latency,
message: info.message,
submission: info.submission,
});
return { success: true };
}
}