前面在《​​Node.js 日志最佳实践指南​​​》介绍了关于日志的最佳实现指南,本文将使用 ​​Winston​​ 库来构建一个简单的日志功能。

​Winston​​​ 是强大、灵活的​​ Node.js​​​ 开源日志库之一,理论上, ​​Winston​​ 是一个可以记录所有信息的记录器。这是一个高度直观的工具,易于定制。可以通过更改几行代码来调整其背后的逻辑。它使对数据库或文件等持久存储位置的日志记录变得简单容易。

​Winston​​ 提供以下功能:

  • 集中控制日志记录的方式和时间:在一个地方更改代码即可
  • 控制日志发送的位置:将日志同步保存到多个目的地(如Elasticsearch、MongoDB、Postgres等)。
  • 自定义日志格式:带有时间戳、颜色日志级别、JSON格式等前缀。

winston实践

const { createLogger, format, transports } = require("winston");

module.exports = createLogger({
transports: [
new transports.File({
filename: "logs/server.log",
level: "info",
format: format.combine(
format.timestamp({ format: "MMM-DD-YYYY HH:mm:ss" }),
format.align(),
format.printf(
(info) =>
`${info.level}: ${[info.timestamp]}: ${info.message}`
)
),
}),
],
});
复制代码

通过调用 ​​winston​​ 库中的 ​​createLogger​​ 函数来初始化记录器。在 ​​transports​​ 对象中,可以提供一个文件名将日志存储在文件中。默认情况下,日志记录未格式化并打印为带有两个参数的 JSON 字符串,日志消息和等级。

下面对之前的 ​​logger​​ 进行修改,将​​winston​​ 日志记录器加入进去,具体修改方式参阅代码,下面给出其使用方法:

const winlogger = require("./winstonLogger");
("日志内容");
复制代码

执行程序后可以会在根目录生成相应的日志文件​​ logs/server.log​

Node.js 日志之winston使用指南_Apache Log4j

也可以更改日志级别,修改 ​​logger​​ ,只在 ​​console.error ​​方式下使用 ​​winston​​:

Node.js 日志之winston使用指南_node.js_02

记录了数据库连接错误信息,上面的信息仅只是为了演示。

多 transports

​winston​​ 允许设置多种 ​​transport​​ ,在 ​​winstonLogger.js​​ 中更改 ​​createLogger​​ 函数如下:

const { createLogger, format, transports } = require("winston");

module.exports = createLogger({
format: format.combine(
format.timestamp({ format: "MMM-DD-YYYY HH:mm:ss" }),
format.align(),
format.printf((i) => `${i.level}: ${[i.timestamp]}: ${i.message}`)
),
transports: [
new transports.File({
filename: "logs/info.log",
level: "info",
format: format.combine(
format.printf((i) =>
i.level === "info"
? `${i.level}: ${i.timestamp} ${i.message}`
: ""
)
),
}),
new transports.File({
filename: "logs/error.log",
level: "error",
}),
],
});
复制代码

再次执行程序,将会看到 ​​error.log​​ 和​​ info.log​​ 文件,由于在 ​​logger​​ 中未设置 ​​info​​ ,因此 ​​info.log​​ 的内容为空,​​error.log​​ 内容和上面的一样。

多 loggers

​winston​​ 允许设置多个 ​​logger​​ ,在实际项目中可以为每个模块创建一个记录器 ​​logger​​ , 如下代码,创建一个用户日志记录器和登录验证记录器:

const { createLogger, format, transports } = require("winston");

const customFormat = format.combine(
format.timestamp({ format: "MMM-DD-YYYY HH:mm:ss" }),
format.align(),
format.printf((i) => `${i.level}: ${[i.timestamp]}: ${i.message}`)
);

const globalLogger = createLogger({
format: customFormat,
transports: [
new transports.File({
filename: "logs/info.log",
level: "info",
format: format.combine(
format.printf((i) =>
i.level === "info"
? `${i.level}: ${i.timestamp} ${i.message}`
: ""
)
),
}),
new transports.File({
filename: "logs/error.log",
level: "error",
}),
],
});

const authLogger = createLogger({
transports: [
new transports.File({
filename: "logs/authLog.log",
format: customFormat,
}),
],
});

module.exports = {
globalLogger: globalLogger,
authLogger: authLogger,
};
复制代码

修改后代码创建了一个全局记录器 ​​globalLogger​​ 和一个鉴权记录器 ​​authLogger​​ ,对应修改​​ logger.js​​:

const { globalLogger } = require("./winstonLogger");
globalLogger.error(message);
复制代码

每日滚动日志文件

正如前面介绍的最佳实践中提到的,按照特定的条件对日志文件进行分割,通常按照日期、大小进行分割,并设置保存的日志天数。为实现这些需求,要有一个安装一个 Winston 相关的依赖库。

npm install winston-daily-rotate-file --save
复制代码

安装完成后使用以下代码更新到 ​​winstonLogger.js​​ 文件:

const { createLogger, format, transports } = require("winston");
require("winston-daily-rotate-file");

const customFormat = format.combine(
format.timestamp({ format: "MMM-DD-YYYY HH:mm:ss" }),
format.align(),
format.printf((i) => `${i.level}: ${[i.timestamp]}: ${i.message}`)
);
const defaultOptions = {
format: customFormat,
datePattern: "YYYY-MM-DD",
zippedArchive: true,
maxSize: "20m",
maxFiles: "14d",
};
const globalLogger = createLogger({
format: customFormat,
transports: [
new transports.DailyRotateFile({
filename: "logs/info-%DATE%.log",
level: "info",
...defaultOptions,
}),
new transports.DailyRotateFile({
filename: "logs/error-%DATE%.log",
level: "error",
...defaultOptions,
}),
],
});

const authLogger = createLogger({
transports: [
new transports.DailyRotateFile({
filename: "logs/authLog-%DATE%.log",
...defaultOptions,
}),
],
});

module.exports = {
globalLogger: globalLogger,
authLogger: authLogger,
};



运行项目,可以看到日志文件:

Node.js 日志之winston使用指南_日志记录_03

至此, ​​Winston​​ 的基本使用指南介绍完了,以上这些基本可以满足日常项目的需要了。