继上篇 替换日志系统为winston 3.1.0

目标:打印日志格式如下,日志按天写入文件

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有出入,推荐去看官网手册)

 

posted @ 2019-01-14 17:45  章鱼樟  阅读(1017)  评论(0编辑  收藏  举报