feat: add source location (src) to logs for locating call sites
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
43dacdba11
commit
2c4f3008cf
@ -1,10 +1,31 @@
|
|||||||
import { DynamicModule } from '@nestjs/common';
|
import { DynamicModule } from '@nestjs/common';
|
||||||
import { LoggerModule } from 'nestjs-pino';
|
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 结构化日志。
|
* 日志配置:pino 结构化日志。
|
||||||
* - stdout 默认开启:开发环境用 pino-pretty 可读格式(LOG_PRETTY 默认 true),生产设 false 输出 JSON
|
* - stdout 默认开启:开发环境用 pino-pretty 可读格式(LOG_PRETTY 默认 true),生产设 false 输出 JSON
|
||||||
* - 文件输出默认关闭,LOG_FILE_ENABLED=true 开启(文件始终为 JSON,便于采集)
|
* - 文件输出默认关闭,LOG_FILE_ENABLED=true 开启(文件始终为 JSON,便于采集)
|
||||||
|
* - 每条日志附加 src(文件:行号),便于定位打印位置
|
||||||
* - 级别 LOG_LEVEL(默认 info)、路径 LOG_FILE_PATH(默认 logs/app.log)
|
* - 级别 LOG_LEVEL(默认 info)、路径 LOG_FILE_PATH(默认 logs/app.log)
|
||||||
*/
|
*/
|
||||||
export function createLoggerModule(): DynamicModule {
|
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 } } });
|
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 } : {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user