subi333's picture
Initial commit for AI coding assistant
e8a6607
Raw
History Blame Contribute Delete
2.13 kB
import pino, { LoggerOptions, Logger } from 'pino';
import path from 'path';
import dotenv from 'dotenv';
const envFile: string = process.env.NODE_ENV === 'production' ? '.env.production' : '.env.development';
dotenv.config({ path: envFile });
const isProduction = process.env.NODE_ENV === 'production';
const options: LoggerOptions = {
level: process.env.LOG_LEVEL || (isProduction ? 'info' : 'debug')
};
// 1. FOR PRODUCTION (JSON Output Layout)
// Appends a clean "caller" property tracking the file and line number
options.hooks = {
logMethod(inputArgs: any[], method, level) {
// Generate a quick call stack trace
const stack = new Error().stack;
// Split and target line 3 (which points back to where logger.info was called)
const callerLine = stack?.split('\n')[3];
// Use RegExp to isolate the file path, row, and column position
const match = callerLine?.match(/\((.*):(\d+):(\d+)\)/) || callerLine?.match(/at\s+(.*):(\d+):(\d+)/);
let callerContext = 'unknown';
if (match) {
const filePath = match[1];
const line = match[2];
const fileName = path.basename(filePath);
callerContext = `${fileName}:${line}`;
}
// Inject the context directly into the log arguments array
return method.apply(this, [ { caller: callerContext }, ...inputArgs ]);
}
};
// Pretty logs only in dev
if (!isProduction) {
options.transport = {
target: 'pino-pretty',
options: {
colorize: true,
messageFormat: '\x1b[36m[{caller}]\x1b[0m {msg}',
translateTime: 'HH:MM:ss',
ignore: 'pid,hostname,caller'
}
}
}
const logger: Logger = pino(options);
export default logger;
/* Usage
Log level Dev Prod
debug βœ… ❌
info βœ… βœ…
warn βœ… βœ…
error βœ… βœ… */
// e.g., output - in prod. - {"level":20,"time":...,"pid":12345,"hostname":"server-1","ip":"192.168.1.10","msg":"WiFi IP detected"}
// e.g., output in dev. -
// 15:42:11 DEBUG WiFi IP detected
// ip: 192.168.1.10