目标:打印日志格式如下,日志按天写入文件
Logging levels in winston
conform to the severity ordering specified by
from most important to least important.
数字越小日志等级越高
const levels = {
error: 0,
warn: 1,
info: 2,
verbose: 3,
debug: 4,
silly: 5
};
const winston = require("winston");
// 写入日志文件配置 详情:https://github.com/winstonjs/winston/blob/HEAD/docs/transports.md#file-transport
const files = new winston.transports.File({ filename: 'combined.log' });
// 控制台输出配置 详情:https://github.com/winstonjs/winston/blob/HEAD/docs/transports.md#console-transport
const console = new winston.transports.Console({
level:'debug'
});
// 方法一
// winston.add(console);
// winston.add(files);
// 方法二
winston.configure({
transports: [
console,
files
]
});
winston.debug('a', 'b', 'c', 'd');
winston.info('a', 'b', 'c', 'd');
winston.warn('a', 'b', 'c', 'd');
winston.error('a', 'b', 'c', 'd');
// 打印结果
{"level":"debug","message":"a"}
{"level":"info","message":"a"}
{"level":"warn","message":"a"}
{"level":"error","message":"a"}
和我的预期相差甚大
继续。。。。
实例化自己的logger
const { createLogger, transports } = require('winston');
const getLogger = (name="default") => {
return createLogger({
transports: [
// 日志打印
new transports.Console({
colorize: true,
level:'debug',
}),
// 日志写入文件
new transports.File({
filename: 'combined.log',
level: 'info'
})
]
});
};
let logger = getLogger('testDefault1');
logger.debug('a', 'b', 'c', 'd');
logger.info('a', 'b', 'c', 'd');
logger.warn('a', 'b', 'c', 'd');
logger.error('a', 'b', 'c', 'd');
// 打印结果
{"level":"debug","message":"a"}
{"level":"info","message":"a"}
{"level":"warn","message":"a"}
{"level":"error","message":"a"}
修改日志打印格式——format ,我发现很多介绍winston的博客版本都是2.X的,format配置是在 transports.Console 里的,但是当前最新版是3.1.0,format 已经已经被移出来了,注意版本变化!!!
const { createLogger, transports } = require('winston');
const { combine, timestamp, label, printf } = format;
const myFormat = printf(info => `${info.timestamp} [${info.level}] [${info.label}] - ${info.message}`);
const getLogger = (name="default") => {
return createLogger({
format: combine(
label({label: name}),
timestamp(),
myFormat
),
transports: [
new transports.Console({
level:'debug',
}),
new transports.File({
filename: 'combined.log',
level: 'info'
})
]
});
};
let logger = getLogger();
logger.debug('a', 'b', 'c', 'd');
logger.info('a', 'b', 'c', 'd');
logger.warn('a', 'b', 'c', 'd');
logger.error('a', 'b', 'c', 'd');
// 打印结果
2019-01-14T06:39:05.866Z [debug] [default] - a
2019-01-14T06:39:05.867Z [info] [default] - a
2019-01-14T06:39:05.868Z [warn] [default] - a
2019-01-14T06:39:05.869Z [error] [default] - a
发现时间差了8小时,查源码:
module.exports = format((info, opts) => {
if (opts.format) {
info.timestamp = typeof opts.format === 'function'
? opts.format()
: fecha.format(new Date(), opts.format);
}
if (!info.timestamp) {
info.timestamp = new Date().toISOString();
}
if (opts.alias) {
info[opts.alias] = info.timestamp;
}
return info;
});
默认是 ISO 格式,我们可以配置 timestamp() 传入 format 字段,type function;
format: combine(
label({label: name}),
timestamp({format: () => moment().format("YYYY-MM-DD HH:mm Z")}),
myFormat
)
// 打印结果
2019-01-14 16:46 +08:00 [debug] [default] - a
2019-01-14 16:46 +08:00 [info] [default] - a
2019-01-14 16:46 +08:00 [warn] [default] - a
2019-01-14 16:46 +08:00 [error] [default] - a
其实也可以直接在输出格式里用moment,这样就不用 timestamp 了
const myFormat = printf(info => `${moment().format('YYYY-MM-DD HH:mm Z')} [${info.level}] [${info.label}] - ${info.message}`);
日志格式搞定。
日志按天写入文件
winston 自身没有这个功能,要使用 winston-daily-rotate-file 这个包
require('winston-daily-rotate-file'); transports: [ new transports.Console({ colorize: true, level:'debug', }), new transports.DailyRotateFile({ filename: './logs/test-%DATE%.log', // DATE必须大写 json: true, level:'debug', datePattern: 'YYYYMMDD' // DATE }) ]
至此我想要的功能已经实现。
现在回到上一篇的问题,放到项目里,pm2 cluster 4个进程,写同一日志文件,会不会产生覆盖问题呢
测试:
5000请求并发,每次请求打印2条日志,一共10000条日志。
测试环境 | 日志是否缺失 | time |
本地多进程 | 否 | 7470.553ms |
测试环境多进程 | 否 | 21360.996ms |
参考资料:
https://www.npmjs.com/package/winston-daily-rotate-file
https://github.com/winstonjs/logform
https://github.com/winstonjs/winston
https://www.jianshu.com/p/09927f1f80eb (这篇博客 winston 版本是 2.3.1, 和 3.1.0有出入,推荐去看官网手册)