日志问题

来源:3-7 安装配置Docker&Docker核心概念

慕容8736893

2025-02-24

请问老师 这些通用的日志模块好像都没能解决 traceid 的问题 这个有什么好的方案吗

写回答

1回答

Brian

2025-02-25

先创建一个logger的配置:

export const appLogger = createLogger({
  level: environment.logLevel,
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.ms(),
  ),
  transports: [
    new winston.transports.Console({
      forceConsole: environment.logForceConsole,
      format: winston.format.combine(
        environment.logAsJson
          ? winston.format.json()
          : utilities.format.nestLike('YOUR-APP', {
              colors: true,
              prettyPrint: true,
            }),
      ),
    }),
    ...(environment.enableLogFile
      ? [
          new winston.transports.DailyRotateFile({
            json: environment.logAsJson,
            filename: environment.pathToLogFile,
            level: environment.logLevel,
            datePattern: 'YYYY-MM-DD-HH',
            zippedArchive: true,
            maxSize: '20m',
            maxFiles: '14d',
          }),
        ]
      : []),
  ],
});

安装 nj-request-scope ,下面创建TraceLogger:

import { Inject, Injectable, LoggerService, Scope } from '@nestjs/common';
import type { Logger as WinstonLogger } from 'winston';

import { CustomRequest } from '../../context-propagation/types/custom-request.type';

import { appLogger } from '../utils/app-logger.util';

@Injectable({ scope: Scope.TRANSIENT })
export class TrackableLogger implements LoggerService {
  constructor(
    @Inject('INQUIRER') inquirer: object,
    @Inject('NJRS_REQUEST')
    private readonly request: CustomRequest | null | undefined,
  ) {
    this.logger = appLogger.child({ context: inquirer.constructor.name });
  }

  private getTraceId() {
    if (!this.request) {
      return crypto.randomUUID();
    }

    if (!this.request.traceId) {
      this.request.traceId = crypto.randomUUID();
    }

    return this.request.traceId;
  }

  private readonly logger: WinstonLogger;

  log(message: string, params?: object) {
    const traceId = this.getTraceId();
    this.logger.info(message, { traceId, ...params });
  }

  info(message: string, params?: object) {
    const traceId = this.getTraceId();
    this.logger.info(message, { traceId, ...params });
  }

  fatal(message: string, params?: object) {
    const traceId = this.getTraceId();
    this.logger.error(message, { traceId, ...params });
  }

  error(message: string, params?: object) {
    const traceId = this.getTraceId();
    this.logger.error(message, { traceId, ...params });
  }

  warn(message: string, params?: object) {
    const traceId = this.getTraceId();
    this.logger.warn(message, { traceId, ...params });
  }

  debug(message: string, params?: object) {
    const traceId = this.getTraceId();
    this.logger.debug(message, { traceId, ...params });
  }

  verbose(message: string, params?: object) {
    const traceId = this.getTraceId();
    this.logger.verbose(message, { traceId, ...params });
  }
}


然后来使用上面的TraceLogger:

@Resolver(Foo)
export class FooResolver {
  constructor(
    private readonly service: FooService,
    private readonly logger: TrackableLogger,
  ) {}
}

打印出来的日志如下:

{"context":"FooResolver","level":"info","message":"foo","ms":"+1ms","timestamp":"2025-01-27T15:59:53.347Z","traceId":"e20451d0-089f-41fd-bdbd-88773c6c71e5"}


0
1
慕容8736893
非常感谢!
2025-02-25
共1条回复

NestJS 从拔高到精通,大型复杂业务架构落地实践

NestJS 从拔高到精通,大型复杂业务架构落地实践

163 学习 · 46 问题

查看课程