diff --git a/src/logging/logger.config.ts b/src/logging/logger.config.ts index bf60232..7895fc9 100644 --- a/src/logging/logger.config.ts +++ b/src/logging/logger.config.ts @@ -1,10 +1,31 @@ import { DynamicModule } from '@nestjs/common'; import { LoggerModule } from 'nestjs-pino'; +/** 解析调用栈,返回打印日志的「文件:行号」(相对 src 的源码路径)。 */ +function getCaller(): string | undefined { + const stack = new Error().stack?.split('\n') ?? []; + for (const line of stack) { + const m = line.match(/(?:file:\/\/)?(\/[^\s:]+):(\d+):\d+\)?$/); + if (!m) continue; + const path = m[1]; + // 跳过依赖与日志模块自身;只认本项目编译产物(dist)里的调用帧 + if (path.includes('node_modules') || path.includes('/logging/')) continue; + if (!path.includes('/dist/')) continue; + const parts = path.split('/'); + const distIdx = parts.indexOf('dist'); + const rel = distIdx >= 0 ? parts.slice(distIdx + 1) : parts.slice(-2); + const file = rel[rel.length - 1].replace(/\.js$/, '.ts'); + const dir = rel.slice(0, -1).join('/'); + return dir ? `${dir}/${file}:${m[2]}` : `${file}:${m[2]}`; + } + return undefined; +} + /** * 日志配置:pino 结构化日志。 * - stdout 默认开启:开发环境用 pino-pretty 可读格式(LOG_PRETTY 默认 true),生产设 false 输出 JSON * - 文件输出默认关闭,LOG_FILE_ENABLED=true 开启(文件始终为 JSON,便于采集) + * - 每条日志附加 src(文件:行号),便于定位打印位置 * - 级别 LOG_LEVEL(默认 info)、路径 LOG_FILE_PATH(默认 logs/app.log) */ export function createLoggerModule(): DynamicModule { @@ -22,5 +43,14 @@ export function createLoggerModule(): DynamicModule { targets.push({ target: 'pino-roll', options: { file: filePath, size: '10m', limit: { count: 10 } } }); } - return LoggerModule.forRoot({ pinoHttp: { level, transport: { targets } } }); + return LoggerModule.forRoot({ + pinoHttp: { + level, + transport: { targets }, + mixin() { + const src = getCaller(); + return src ? { src } : {}; + }, + }, + }); }