File size: 1,636 Bytes
00a912e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import pino from 'pino'

const isDev = process.env.NODE_ENV !== 'production'
const useJson = process.env.LOG_FORMAT?.toLowerCase() === 'json'

const baseLogger = pino({
  level: process.env.LOG_LEVEL || 'info',
  base: undefined,
  redact: {
    paths: ['password', 'cookie', 'authorization', 'token', '*.password', '*.cookie', '*.authorization', '*.token'],
    censor: '[已隐藏]',
  },
  ...(!useJson && {
    transport: {
      target: 'pino-pretty',
      options: {
        colorize: isDev,
        translateTime: 'SYS:yyyy-mm-dd HH:MM:ss.l',
        singleLine: true,
        levelFirst: true,
        hideObject: false,
      },
    },
  }),
})

/**
 * Logger wrapper that keeps the same call signature as our previous hand-rolled logger.
 * All existing call sites (10+ files) need zero changes.
 *
 * Signatures:
 *   logger.debug(message, context?)
 *   logger.info(message, context?)
 *   logger.warn(message, context?)
 *   logger.error(message, err?, context?)
 */
export const logger = {
  debug(message: string, context?: Record<string, unknown>) {
    baseLogger.debug(context ?? {}, message)
  },
  info(message: string, context?: Record<string, unknown>) {
    baseLogger.info(context ?? {}, message)
  },
  warn(message: string, context?: Record<string, unknown>) {
    baseLogger.warn(context ?? {}, message)
  },
  error(message: string, err?: unknown, context?: Record<string, unknown>) {
    const errObj = err instanceof Error ? err : undefined
    const extra = { ...context, ...(err && !(err instanceof Error) ? { error: String(err) } : {}) }
    baseLogger.error({ ...extra, err: errObj }, message)
  },
}