60 lines
1.4 KiB
TypeScript
60 lines
1.4 KiB
TypeScript
import { randomUUID } from "node:crypto";
|
|
import { consola } from "consola";
|
|
|
|
type LogMeta = Record<string, unknown>;
|
|
|
|
export const createApiLogger = (scope: string) => {
|
|
const requestId = randomUUID();
|
|
const startedAt = Date.now();
|
|
const prefix = `[${scope}]`;
|
|
|
|
const withBaseMeta = (meta?: LogMeta) => ({
|
|
requestId,
|
|
...(meta ?? {})
|
|
});
|
|
|
|
return {
|
|
requestId,
|
|
info(message: string, meta?: LogMeta) {
|
|
consola.info(`${prefix} ${message}`, withBaseMeta(meta));
|
|
},
|
|
warn(message: string, meta?: LogMeta) {
|
|
consola.warn(`${prefix} ${message}`, withBaseMeta(meta));
|
|
},
|
|
error(message: string, meta?: LogMeta) {
|
|
consola.error(`${prefix} ${message}`, withBaseMeta(meta));
|
|
},
|
|
done(message: string = "完成", meta?: LogMeta) {
|
|
consola.info(
|
|
`${prefix} ${message}`,
|
|
withBaseMeta({
|
|
...(meta ?? {}),
|
|
elapsedMs: Date.now() - startedAt
|
|
})
|
|
);
|
|
}
|
|
};
|
|
};
|
|
|
|
export const toSafeLogError = (error: unknown) => {
|
|
const maybeError = error as {
|
|
message?: string;
|
|
name?: string;
|
|
response?: {
|
|
status?: number;
|
|
};
|
|
stack?: string;
|
|
status?: number;
|
|
statusCode?: number;
|
|
statusMessage?: string;
|
|
};
|
|
|
|
return {
|
|
name: maybeError.name,
|
|
message: maybeError.message ?? maybeError.statusMessage,
|
|
status:
|
|
maybeError.status ?? maybeError.statusCode ?? maybeError.response?.status,
|
|
stack: maybeError.stack
|
|
};
|
|
};
|