为什么使用 winston:
- 多种日志级别:支持 npm 风格的日志级别,如 error、warn、info、verbose、debug 和 silly,
- 自定义日志格式:可自定义日志消息的格式,包括添加时间戳、设置日志格式(如 JSON、纯文本)、位置等。
- 多种存储选项:多种存储日志的方式,包括控制台、文件、数据库等。
- 日志轮转:可以按照文件大小或时间自动创建新的日志文件。
- **查询日志:**提供了查询和筛选日志的 api
- **性能和社区:**为异步日志记录设计,可以减少对应用性能的影响。同时也是 Node 最流行的日志框架,npm 官网上可以看到每周千万级的下载量
基本使用
创建项目:
bash
mkdir winston-test
cd winston-test
npm init -y
安装 winston:
bash
npm install winston
创建 logger.js:
创建 index.js 引入 logger:
用 node 跑一下:
bash
node index.js
控制台和文件都有日志了:
继续使用 node index.js 跑一遍:
日志继续追加在后面。
如果内容过多,winston 能自动分割文件:
我们指定 1024 字节,也就是超过 1kb 自动分割文件:
Transport
如果我们想按照日期分割文件,这时候就需要换 Transport,在 winston 文档里可以看到内置 Transport:
- Console(控制台)传输: 将日志输出到控制台,方便开发人员在开发和调试过程中查看日志信息。
- File(文件)传输: 将日志写入文件,适用于长期存储和后续分析。
- HTTP 传输: 将日志通过 HTTP 请求发送到指定的远程服务器,方便集中管理和监控。
- Database(数据库)传输: 将日志信息存储到数据库中,便于后续查询和分析。
社区还有很多的 Transport,比如 winston-mongodb 、winston-redis,就是把日志写入 mongodb 或 reids。
winston-daily-rotate-file
winston-daily-rotate-file ,这个就可以根据日期、小时或文件大小来轮转日志文件:
安装:
bash
npm install winston-daily-rotate-file
改下代码:
node 运行文件后:
多运行几次:
因为设置 zippedArchive: true
,轮转时,超出大小限制的旧文件会压缩,并且生成了 log.1 的新文件。
这里的轮转是基于日期模式的,datePattern: 'YYYY-MM-DD'
这一配置意味着每天都会创建一个新的日志文件。
Winston 创建新一天文件的时候,前一天文件也会被压缩。
我们注意到上面会额外生成个 .audit.json
结尾的文件,这是个审计文件,包含关于日志文件轮转的元数据,比如:
- 文件名
- 轮转时间戳
- 文件的大小
- 删除的文件(如果启用了最大文件数限制)
winston-log-server
再来试试 http 的 transport:
bash
nest new winston-test-server -p npm
AppController 添加一个路由:
跑起来:
bash
npm run start:dev
改下 logger.js:
使用 http 的 transport 往 localhost:3000/log 传输日志。
跑一下:
bash
node ./index.js
nest 收到了传过来的日志:
这些 transport 可以用 clear、 add、remove 方法来动态增删:
javascript
import winston from 'winston'
const console = new winston.transports.Console()
const file = new winston.transports.File({ filename: 'log.log' })
const logger = winston.createLogger({
level: 'debug',
format: winston.format.simple(),
})
logger.clear()
logger.add(console)
logger.remove(console)
logger.add(file)
最后就只有一个 file 的 transport。
日志级别
winston 有 6 种级别的日志,从 0(最高优先级)到 6(最低优先级):
- error (0): 错误日志,记录系统无法运行的情况。
- warn (1): 警告信息,记录不正常但不影响系统运行的情况。
- info (2): 重要的运行信息,通常用于生产环境。
- http (3): HTTP 请求日志,记录 HTTP 请求数据。
- verbose (4): 详细信息,比 info 级别更详细的日志。
- debug (5): 调试信息,通常用于开发环境。
- silly (6): 最低级别,记录非常详细的调试信息或开发时的临时日志。
如果设置了日志级别,那么优先级高于等于该级别的日志信息会记录下来。
例如,如果设置了日志级别为 warn,那么 error 和 warn 级别的日志会记录,而 info、http、verbose、debug 和 silly 级别的则不会。
format 格式
日志可以通过 format 指定格式:
Winston 提供了多种内置的日志格式化选项:
- simple() - 输出简单的、未格式化的日志消息。
- json() - 将日志消息输出为 JSON 格式。
- colorize() - 在日志消息中添加颜色,通常用于在控制台中区分不同级别的日志。
- label() - 添加一个标签,通常用于指示日志消息来源的模块或组件。
- timestamp() - 为每条日志消息添加时间戳。
- printf() - 使用自定义模板来格式化日志消息。
- combine() - 组合多个格式化函数。
可以组合这些格式化函数来创建复杂的日志格式。
例如,可能想要一个带时间戳和颜色编码以及标签的简单格式,你可以这样做:
javascript
const winston = require('winston');
const logger = winston.createLogger({
level: 'debug',
format: winston.format.combine(
winston.format.label({ label: '标签更好查找日志哦' }),
winston.format.colorize(),
winston.format.timestamp(),
winston.format.simple()
),
transports: [new winston.transports.Console()],
})
logger.info('云云云')
logger.error('牧牧牧')
logger.debug(666)
多 logger 实例
有的日志只想 console,而有的日志希望写入文件。
我们可以创建多个 logger 实例,每个 logger 实例有不同的 format、transport、level 等配置:
我们就成功创建了 2 个 logger 实例,其中一个只写入 console,另一个只写入 file。
运行下:
捕获错误日志
Winston 处理未捕获的错误:
javascript
const winston = require('winston');
const logger = winston.createLogger({
level: 'debug',
format: winston.format.simple(),
transports: [new winston.transports.Console()],
// 所有未捕获的异常都将被记录到 'error.log' 文件中
exceptionHandlers: [
new winston.transports.File({
filename: 'error.log',
}),
],
// 所有未处理的 Promise 拒绝都将被记录到 'rejections.log' 文件中
rejectionHandlers: [
new winston.transports.File({
filename: 'rejections.log',
}),
],
// 默认值是 true,表示在记录未捕获的异常后退出进程
exitOnError: true
})
可以代码中 throw new Error('This is an uncaught exception');
自行测试下。