返回 presentation-ai
logger.ts
根目录 / src / lib / observability / logger.ts
1 type LogLevel = "info" | "warn" | "error";
2
3 type LogDetails = Record<string, unknown>;
4
5 function serializeError(error: unknown) {
6 if (error instanceof Error) {
7 return {
8 name: error.name,
9 message: error.message,
10 stack: error.stack,
11 };
12 }
13
14 if (typeof error === "string") {
15 return { message: error };
16 }
17
18 return { value: error };
19 }
20
21 function writeLog(
22 level: LogLevel,
23 scope: string,
24 message: string,
25 details?: LogDetails,
26 error?: unknown,
27 ) {
28 const payload = {
29 timestamp: new Date().toISOString(),
30 scope,
31 ...(details ? { details } : {}),
32 ...(error !== undefined ? { error: serializeError(error) } : {}),
33 };
34 const prefix = `[presentation-ai][${scope}] ${message}`;
35
36 if (level === "error") {
37 console.error(prefix, payload);
38 return;
39 }
40
41 if (level === "warn") {
42 console.warn(prefix, payload);
43 return;
44 }
45
46 console.info(prefix, payload);
47 }
48
49 export function createLogger(scope: string) {
50 return {
51 child(childScope: string) {
52 return createLogger(`${scope}:${childScope}`);
53 },
54 info(message: string, details?: LogDetails) {
55 writeLog("info", scope, message, details);
56 },
57 warn(message: string, details?: LogDetails) {
58 writeLog("warn", scope, message, details);
59 },
60 error(message: string, error?: unknown, details?: LogDetails) {
61 writeLog("error", scope, message, details, error);
62 },
63 };
64 }
65
66 export const appLogger = createLogger("app");
67
67 lines TYPESCRIPT