ZetCode

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 记录器都可以在不同的级别配置多个传输。 Winston 带有三个核心传输:控制台、文件和 HTTP。 必须创建传输并将其添加到记录器中。

传输具有以下设置

Winston 日志级别

日志级别表示消息优先级,并由一个整数表示。 它们是为传输指定的。 Winston 带有预定义的日志级别集:npmsyslogcli

以下是默认的 npm 日志级别

任何特定级别或更高级别的内容都将被记录。 例如,通过指定信息级别,将记录错误、警告或信息级别的任何内容。 调用记录器时指定日志级别。

logger.info('Information message').

我们使用 info 函数记录一条信息消息。

logger.log('info', Information message').

这是记录信息消息的另一种方式。

Winston 格式

日志消息使用 Winston 格式进行格式化。 Winston 包含几个内置格式,包括

默认格式为 json。 格式可以使用 combine 组合,可以使用 printf 创建自定义格式。

Winston 简单示例

以下是一个简单的 Winston 示例。

simple.js
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 函数并将日志级别指定为第一个选项。

log_funs.js
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 函数,我们可以配置已创建的记录器。

configure_logger.js
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 模块直接访问默认记录器。 最初,未在默认记录器上设置任何传输。 我们必须通过 addremoveconfigure 方法添加或删除传输。

default_logger.js
const winston = require('winston');


const console = new winston.transports.Console();

winston.add(console);
winston.info('Information message');
winston.remove(console);

该示例使用默认记录器来记录一条信息消息。

Winston 格式 cli

cli 格式是 colorizepadLevels 格式的组合。

format_cli.js
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 组合。

format_combine.js
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');

在本例中,我们组合了 colorizetimestampalignprintf 格式。

$ node format_combine.js 
2020-04-04T17:17:48.882Z info:  Information message

Winston 传输 maxsize

传输的 maxsize 属性设置日志文件的最大大小(以字节为单位),然后创建一个新文件。

max_size.js
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 多个记录器

在下一个示例中,我们创建了两个写入文件的记录器。

loggers.js
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 GitHub 页面

在本文中,我们使用了 Winston 日志记录库。

作者

我叫 Jan Bodnar,是一位热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

查看 所有 JavaScript 教程。