Winston 日志框架:功能与应用指南

为什么使用 winston:

  1. 多种日志级别:支持 npm 风格的日志级别,如 error、warn、info、verbose、debug 和 silly,
  2. 自定义日志格式:可自定义日志消息的格式,包括添加时间戳、设置日志格式(如 JSON、纯文本)、位置等。
  3. 多种存储选项:多种存储日志的方式,包括控制台、文件、数据库等。
  4. 日志轮转:可以按照文件大小或时间自动创建新的日志文件。
  5. **查询日志:**提供了查询和筛选日志的 api
  6. **性能和社区:**为异步日志记录设计,可以减少对应用性能的影响。同时也是 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:

  1. Console(控制台)传输: 将日志输出到控制台,方便开发人员在开发和调试过程中查看日志信息。
  2. File(文件)传输: 将日志写入文件,适用于长期存储和后续分析。
  3. HTTP 传输: 将日志通过 HTTP 请求发送到指定的远程服务器,方便集中管理和监控。
  4. Database(数据库)传输: 将日志信息存储到数据库中,便于后续查询和分析。

社区还有很多的 Transport,比如 winston-mongodbwinston-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(最低优先级):

  1. error (0): 错误日志,记录系统无法运行的情况。
  2. warn (1): 警告信息,记录不正常但不影响系统运行的情况。
  3. info (2): 重要的运行信息,通常用于生产环境。
  4. http (3): HTTP 请求日志,记录 HTTP 请求数据。
  5. verbose (4): 详细信息,比 info 级别更详细的日志。
  6. debug (5): 调试信息,通常用于开发环境。
  7. 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'); 自行测试下。

相关推荐
小白学习日记1 小时前
【复习】HTML常用标签<table>
前端·html
丁总学Java1 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
姜学迁1 小时前
Rust-枚举
开发语言·后端·rust
yanlele2 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
爱学习的小健2 小时前
MQTT--Java整合EMQX
后端
懒羊羊大王呀2 小时前
CSS——属性值计算
前端·css
DOKE2 小时前
VSCode终端:提升命令行使用体验
前端
北极小狐2 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
xgq2 小时前
使用File System Access API 直接读写本地文件
前端·javascript·面试
用户3157476081352 小时前
前端之路-了解原型和原型链
前端