日志打印
Kotori 提供了强大日志系统,由 @kotori-bot/logger
库提供后经由 @kotori-bot/loader
传递给 kotori-bot
重新导出。支持多级别日志输出、链式调用的标签系统、丰富的数据类型展示以及多种日志传输器。
初始化与配置
Logger 支持多种 transport 类型和配置选项。可以使用单一 transport,或组合多个 transport 来满足不同的日志需求:
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
export declare enum LoggerLevel {
TRACE = 10,
DEBUG = 20,
RECORD = 25,
INFO = 30,
WARN = 40,
ERROR = 50,
FATAL = 60,
SILENT = 70
}
基础使用
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
实例 意味着支持链式调用,可以将多个标签组合在一起,并在输出时打印出来。
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()
的封装
const chainLogger = logger
.extends({ label: ['API'] })
.extends({ level: LoggerLevel.DEBUG })
.extends({
transports: new FileTransport({ dir: 'api-logs' })
})
chainLogger.info('API started')
其它使用方式
在上下文中直接使用
通过 ctx.logger
:
export function main(ctx: Context) {
ctx.logger.info('Hello, world!')
}
推荐,因为这全权由 Kotori 进行控制和管理,同时还能追踪不同模块上下文打印的日志。
直接使用
Logger
构造函数本身也是一个不完全的 logger
实例,可以直接使用:
Logger.error('global error')
Logger.fatal('global fatal error')
Logger.warn('global warning')
Logger.info('global info')
CAUTION
完全不推荐,Logger
本身只支持 LoggerLevel.INFO
及以上级别的日志输出,传输器仅支持 ConsoleTransport
,且不可更改配置、不可继承、不可增加标签。