Skip to content

日志打印

Kotori 提供了强大日志系统,由 @kotori-bot/logger 库提供后经由 @kotori-bot/loader 传递给 kotori-bot 重新导出。支持多级别日志输出、链式调用的标签系统、丰富的数据类型展示以及多种日志传输器。

初始化与配置

Logger 支持多种 transport 类型和配置选项。可以使用单一 transport,或组合多个 transport 来满足不同的日志需求:

tsx
new Logger({
  level: LoggerLevel.TRACE, // 设置日志级别
  label: ['App'], // 默认标签
  transports: new ConsoleTransport() // 设置传输器:输出到控制台
})

new Logger({
  level: LoggerLevel.INFO,
  transports: [
    new ConsoleTransport(),
    new FileTransport({
      dir: 'logs' // 设置日志文件目录
    })
  ]
})

const logger = new Logger({
  level: LoggerLevel.DEBUG,
  transports: new ConsoleTransport({
    useColor: true, // 开启颜色输出
    template: '{time} [{level}] {labels} - {message}' // 设置日志格式
  })
})

传输器

传输器负责将日志输出到不同的位置,默认提供了以下传输器:

  • ConsoleTransport: 输出到控制台
  • FileTransport: 输出到文件,支持日志轮转

相关传输器的配置选项请参考 接口文档。当然,也可以自定义 Transport,只需要继承 Transport 基类并实现相关方法,如输出到浏览器控制台的 BrowserTransport

NOTE

对于 ConsoleTransport,当处于浏览器环境时使用 console.log()console.error() 输出日志,当处于 Node.js 环境时则使用 process.stdout.write()process.stderr.write() 输出日志。

日志输出级别

TRACE < DEBUG < INFO < WARN < ERROR < FATAL < SILENT

ts
export declare enum LoggerLevel {
    TRACE = 10,
    DEBUG = 20,
    RECORD = 25,
    INFO = 30,
    WARN = 40,
    ERROR = 50,
    FATAL = 60,
    SILENT = 70
}

基础使用

tsx
logger.label('HTTP').info('GET /api/users - 200 OK')
logger.label('Auth').warn('Invalid token received')

logger.label('Database').label('Query').error('Connection failed:', { code: 'ETIMEDOUT' })

logger.label('System').label('Memory').label('Heap').warn('High memory usage:', '85%')

logger.info('base type:', 'string', 233, null, undefined, true, false, 2.71828184)
logger.fatal('normal object (json):', { value: 1, content: 'content', extends: { value: 2 } }, [
  1,
  null,
  { value: false },
  'string'
])
// biome-ignore lint:
const obj: any = {}
obj.value = obj
logger.error('loop object:', obj)
logger.warn('javascript special type:', Symbol(233), BigInt('1234567891011121314151617181920'))
logger.debug('javascript object:', Math, globalThis)
logger.trace('javascript constructor:', Object, Function, String, Number, Boolean, Set, Map, Symbol, Error, Date)
logger.label('label1').info(
  'javascript object instance',
  new Map([
    [1, 3],
    [2, 3],
    [3, 4],
    [4, 5]
  ]),
  new Set([1, 3, 3, 4, 5, 6, 7, 7, 8]),
  new Proxy({}, {}),
  new Error('a error'),
  new Date()
)

标签系统

logger.label() 返回基于当前实例的新 logger 实例 意味着支持链式调用,可以将多个标签组合在一起,并在输出时打印出来。

tsx
try {
  throw new Error('Something went wrong')
} catch (err) {
  logger.error('Caught error:', err)
}

console.time('operation')
// ... some operations
console.timeEnd('operation')
logger.info('Operation completed in:', 'operation')

继承

logger.label() 本身即是对 logger.extend() 的封装

tsx
const chainLogger = logger
  .extends({ label: ['API'] })
  .extends({ level: LoggerLevel.DEBUG })
  .extends({
    transports: new FileTransport({ dir: 'api-logs' })
  })
chainLogger.info('API started')

其它使用方式

在上下文中直接使用

通过 ctx.logger

tsx
export function main(ctx: Context) {
  ctx.logger.info('Hello, world!')
}

推荐,因为这全权由 Kotori 进行控制和管理,同时还能追踪不同模块上下文打印的日志。

直接使用

Logger 构造函数本身也是一个不完全的 logger 实例,可以直接使用:

tsx
Logger.error('global error')
Logger.fatal('global fatal error')
Logger.warn('global warning')
Logger.info('global info')

CAUTION

完全不推荐,Logger 本身只支持 LoggerLevel.INFO 及以上级别的日志输出,传输器仅支持 ConsoleTransport,且不可更改配置、不可继承、不可增加标签。