Files
lst_v3/backend/logger/logger.controller.ts

91 lines
1.9 KiB
TypeScript

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 { emitToRoom } from "../socket.io/roomEmitter.socket.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<number, string> = {
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,
})
.returning(),
);
if (res.error) {
console.error(res.error);
}
if (obj.room) {
emitToRoom(obj.room, res.data ? res.data[0] : obj);
}
emitToRoom("logs", res.data ? res.data[0] : obj);
callback();
} catch (err) {
console.error("DB log insert error:", err);
callback();
}
},
});
const rootLogger: Logger = pino(
{
level: logLevel,
redact: { paths: ["email", "password"], remove: true },
},
pino.multistream([
{
level: logLevel,
stream: pino.transport({
target: "pino-pretty",
options: {
colorize: true,
singleLine: true,
},
}),
},
{
level: logLevel,
stream: dbStream,
},
]),
);
/**
*
*
* example data to put in as a reference
* rooms logs | labels | etc
*/
export const createLogger = (bindings: Record<string, unknown>): Logger => {
return rootLogger.child(bindings);
};