Files
EpicNext-Cms/src/lib/logger.ts
T
Simo a2954e4408
CI / check (push) Successful in 56s
CI / deploy (push) Successful in 19s
CI / publish-container (push) Successful in 1m15s
feat(diagnostics): correlate staff operations errors and audit records
2026-09-11 00:34:49 +02:00

67 lines
2.0 KiB
TypeScript

import pino from "pino";
import { env } from "@/env";
import { captureCmsError } from "./error-monitor";
import { getOperationContext } from "./foundation/request-context";
type LogLevel = "debug" | "info" | "warn" | "error";
const level: LogLevel =
(env.LOG_LEVEL as LogLevel | undefined) ??
(env.NODE_ENV === "production" ? "info" : "debug");
const isProd = env.NODE_ENV === "production";
const isTest = env.NODE_ENV === "test" || process.env.VITEST === "true";
const pinoLogger = pino({
level,
base: { service: "atomcms-next" },
...(isProd || isTest
? {}
: {
transport: {
target: "pino-pretty",
options: { colorize: true, translateTime: "SYS:standard" },
},
}),
});
let requestIdCounter = 0;
export function generateRequestId(): string {
requestIdCounter += 1;
return `${Date.now().toString(36)}-${requestIdCounter.toString(36)}`;
}
/** Compatibility wrapper — existing call sites use (message, meta). */
export const logger = {
debug(message: string, meta: Record<string, unknown> = {}): void {
pinoLogger.debug({ ...meta, ...getOperationContext() }, message);
},
info(message: string, meta: Record<string, unknown> = {}): void {
pinoLogger.info({ ...meta, ...getOperationContext() }, message);
},
warn(message: string, meta: Record<string, unknown> = {}): void {
pinoLogger.warn({ ...meta, ...getOperationContext() }, message);
},
error(message: string, meta: Record<string, unknown> = {}): string {
const error =
meta.err instanceof Error
? meta.err
: meta.error instanceof Error
? meta.error
: new Error(
typeof meta.err === "string"
? meta.err
: typeof meta.error === "string"
? meta.error
: message,
);
const operation = getOperationContext();
// Keep trusted correlation first so bounded error context retains it.
const context = { ...operation, ...meta, ...operation };
const errorId = captureCmsError("server", message, error, context);
pinoLogger.error({ ...context, errorId }, message);
return errorId;
},
};