import { Writable } from "node:stream"; import pino, { type Logger } from "pino"; import { db } from "../db/db.controller.js"; import { logs } from "../db/schema/logs.schema.js"; import { tryCatch } from "../utils/trycatch.utils.js"; //import build from "pino-abstract-transport"; export const logLevel = process.env.LOG_LEVEL || "info"; const pinoLogLevels: Record = { 10: "trace", 20: "debug", 30: "info", 40: "warn", 50: "error", 60: "fatal", }; // ✅ Custom DB writable stream const dbStream = new Writable({ objectMode: true, async write(chunk, _enc, callback) { try { const obj = JSON.parse(chunk.toString()); const levelName = pinoLogLevels[obj.level] || "unknown"; const res = await tryCatch( db.insert(logs).values({ level: levelName, module: obj?.module?.toLowerCase(), subModule: obj?.subModule?.toLowerCase(), hostname: obj?.hostname?.toLowerCase(), message: obj.msg, stack: obj?.stack, }), ); if (res.error) { console.error(res.error); } callback(); } catch (err) { console.error("DB log insert error:", err); callback(); } }, }); // ✅ Multistream setup const streams = [ { stream: pino.transport({ target: "pino-pretty", options: { colorize: true, singleLine: true, }, }), }, { level: "info", stream: dbStream, }, ]; const rootLogger: Logger = pino( { level: logLevel, redact: { paths: ["email", "password"], remove: true }, }, pino.multistream(streams), ); export const createLogger = (bindings: Record): Logger => { return rootLogger.child(bindings); };