96 lines
2.0 KiB
TypeScript
96 lines
2.0 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 { notifySystemIssue } from "./logger.notify.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.notify) {
|
|
notifySystemIssue(obj);
|
|
}
|
|
|
|
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);
|
|
};
|