Winston 教程
最后修改于 2023 年 10 月 18 日
在本文中,我们将展示如何使用 Winston.js 库在 JavaScript 中进行日志记录,并通过几个代码示例演示日志记录。
日志记录
日志记录 是将信息写入日志文件的过程。日志文件包含有关操作系统、软件或通信中发生的各种事件的信息。
日志记录的目的
日志记录的目的如下:
- 故障排除
- 信息收集
- 性能分析
- 审计
- 生成统计数据
日志记录不仅限于识别软件开发中的错误。它还用于检测安全事件、监控策略违规、在出现问题时提供信息、查找应用程序瓶颈或生成使用数据。
记录哪些事件
应记录的事件包括输入验证失败、身份验证和授权失败、应用程序错误、配置更改以及应用程序启动和关闭。
不记录哪些事件
不应记录的事件包括应用程序源代码、会话标识值、访问令牌、敏感个人数据、密码、数据库连接字符串、加密密钥、银行账户和持卡人数据。
日志记录最佳实践
以下是一些日志记录的最佳实践:
- 日志记录应有意义。
- 日志记录应该是有结构的,并在不同的级别进行。
- 日志记录应包含上下文。
- 日志消息应该易于人类理解,并且可以被机器解析。
- 日志记录应平衡;它不应包含过少或过多的信息。
- 日志记录应适应开发和生产环境。
- 在更复杂的应用程序中,日志记录应该分成几个日志文件。
Winston
Winston 是一个流行的 JavaScript 日志记录库。 它被设计为简单和通用。 每个 Winston 记录器都可以在不同的级别配置多个传输。 Winston 默认使用 JSON 格式进行日志记录。
$ npm i winston
我们使用 npm
工具安装 winston
包。
Winston 记录器
Winston 记录器将消息记录到日志文件中。 使用 createLogger
函数创建 Winston 记录器。 此外,如果没有显式指定记录器,则存在一个默认记录器。
createLogger
函数接受以下选项
名称 | 默认 | 描述 |
---|---|---|
级别 | info | 要记录的日志消息的最高级别 |
级别 | winston.config.npm.levels | 选择的级别消息类型集合 |
格式 | winston.format.json | 日志消息的格式 |
传输 | 无传输 | 日志消息的日志记录目标集合 |
exitOnError | true | 是否处理的异常导致 process.exit |
静默 | false | 如果为 true,则会抑制所有日志 |
Winston 传输
传输是我们日志的存储设备或输出机制。 每个 Winston 记录器都可以在不同的级别配置多个传输。 Winston 带有三个核心传输:控制台、文件和 HTTP。 必须创建传输并将其添加到记录器中。
传输具有以下设置
- 级别 - 设置要记录的消息的级别。
- 文件名 - 这是写入日志数据的文件名。
- handleExceptions - 确定是否捕获和记录未处理的异常。
- json - 以 JSON 格式记录日志数据。
- maxsize - 设置日志文件的最大大小(以字节为单位),然后创建一个新文件。
- maxFiles - 限制在超出日志文件大小时创建的文件数。
- colorize - 为输出着色; 在查看控制台日志时很有帮助。
Winston 日志级别
日志级别表示消息优先级,并由一个整数表示。 它们是为传输指定的。 Winston 带有预定义的日志级别集:npm
、syslog
和 cli
。
以下是默认的 npm 日志级别
- 0:错误
- 1:警告
- 2:信息
- 3:http
- 4:详细
- 5:调试
- 6:冗余
任何特定级别或更高级别的内容都将被记录。 例如,通过指定信息级别,将记录错误、警告或信息级别的任何内容。 调用记录器时指定日志级别。
logger.info('Information message').
我们使用 info
函数记录一条信息消息。
logger.log('info', Information message').
这是记录信息消息的另一种方式。
Winston 格式
日志消息使用 Winston 格式进行格式化。 Winston 包含几个内置格式,包括
- 简单
- json
- cli
- padlevels
- colorize
- splat
- align
默认格式为 json
。 格式可以使用 combine
组合,可以使用 printf
创建自定义格式。
Winston 简单示例
以下是一个简单的 Winston 示例。
const winston = require('winston'); const logger = winston.createLogger({ transports: [ new winston.transports.Console() ] }); logger.info('Information message'); logger.warn('Warning message'); logger.error('Error message');
我们创建一个控制台记录器并记录三个消息。 由于默认日志级别为 info
,因此所有三个消息都被记录。
$ node simple.js {"message":"Information message","level":"info"} {"message":"Warning message","level":"warn"} {"message":"Error message","level":"error"}
在输出中,我们可以看到三个 JSON 消息。
Winston 日志函数
我们可以使用自定义日志函数 (info
, warn
) 记录消息,或者使用通用的 log
函数并将日志级别指定为第一个选项。
const winston = require('winston'); const logger = winston.createLogger({ transports: [ new winston.transports.Console() ] }); logger.info('Information message'); logger.warn('Warning message'); logger.log('info', 'Information message') logger.log('warn', 'Warning message')
在本例中,我们以两种方式记录消息。
$ node log_funs.js {"message":"Information message","level":"info"} {"message":"Warning message","level":"warn"} {"level":"info","message":"Information message"} {"level":"warn","message":"Warning message"}
Winston 配置记录器
使用 configure
函数,我们可以配置已创建的记录器。
const winston = require('winston'); const logger = winston.createLogger({ transports: [ new winston.transports.Console() ] }); logger.info('Information message'); logger.warn('Warning message'); logger.error('Error message'); logger.configure({ level: 'error', transports: [ new winston.transports.Console() ] }); logger.info('Information message 2'); logger.warn('Warning message 2'); logger.error('Error message 2');
在本例中,我们将日志级别更改为 'error'
,并调用另外三个日志函数。 仅从附加消息中输出第二条错误消息。
$ node configure_logger.js {"message":"Information message","level":"info"} {"message":"Warning message","level":"warn"} {"message":"Error message","level":"error"} {"message":"Error message 2","level":"error"}
Winston 默认记录器
可以通过 winston 模块直接访问默认记录器。 最初,未在默认记录器上设置任何传输。 我们必须通过 add
、remove
或 configure
方法添加或删除传输。
const winston = require('winston'); const console = new winston.transports.Console(); winston.add(console); winston.info('Information message'); winston.remove(console);
该示例使用默认记录器来记录一条信息消息。
Winston 格式 cli
cli
格式是 colorize
和 padLevels
格式的组合。
const winston = require('winston'); const myformat = winston.format.cli({ colors: { info: 'blue' }}); const logger = winston.createLogger({ transports: [ new winston.transports.Console({ format: myformat }) ] }); logger.info('Information message');
在本例中,我们将 cli 格式传递给控制台传输。 我们选择蓝色。
Winston 组合格式
格式可以使用 combine
组合。
const winston = require('winston'); const myformat = winston.format.combine( winston.format.colorize(), winston.format.timestamp(), winston.format.align(), winston.format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`) ); const logger = winston.createLogger({ transports: [ new winston.transports.Console({ format: myformat }) ] }); logger.info('Information message');
在本例中,我们组合了 colorize
、timestamp
、align
和 printf
格式。
$ node format_combine.js 2020-04-04T17:17:48.882Z info: Information message
Winston 传输 maxsize
传输的 maxsize
属性设置日志文件的最大大小(以字节为单位),然后创建一个新文件。
const path = require('path'); const winston = require('winston'); const logger = winston.createLogger({ level: 'info', format: winston.format.printf(info => `${info.message}`), transports: [ new winston.transports.File({ filename: path.join(__dirname, 'error.log'), level: 'info', maxsize: 500 }) ] }); logger.info(`${'a'.repeat(200)}`); logger.info(`${'b'.repeat(200)}`); logger.info(`${'c'.repeat(200)}`); setTimeout(() => { logger.info(`${'d'.repeat(200)}`); logger.info(`${'e'.repeat(200)}`); }, 1500);
我们使用文件传输,并将 maxsize
设置为 500 字节。 稍后我们将写入超过 500 个字符到文件中。 前 600 个字符被写入 error.log
文件中,其余 400 个字符被写入 error1.log
文件中。
Winston 多个记录器
在下一个示例中,我们创建了两个写入文件的记录器。
const winston = require('winston'); const loggers = { mjson: winston.createLogger({ level: 'info', format: winston.format.json(), transports: [new winston.transports.File({ filename: 'app-info.log'})], }), simple: winston.createLogger({ level: 'error', format: winston.format.simple(), transports: [new winston.transports.File({ filename: 'app-error.log'}),], }) }; loggers.mjson.info('Information message'); loggers.mjson.error('Error message'); loggers.mjson.debug('Some message'); loggers.simple.error('Error message'); loggers.simple.info('Information message'); loggers.simple.warn('Warning message'); loggers.simple.debug('Some message');
mjson
记录器以 json 格式写入,simple
记录器以简单格式写入。 记录器具有不同的日志级别。
$ node loggers.js $ cat app-error.log error: Error message $ cat app-info.log {"message":"Information message","level":"info"} {"message":"Error message","level":"error"}
我们运行该程序并显示文件内容。
来源
在本文中,我们使用了 Winston 日志记录库。