213  
查询码:00000475
Winston日志框架使用
作者: 朱凡 于 2020年06月23日 发布在分类 / FM组 / FM_App 下,并于 2020年06月23日 编辑

winston日志框架使用

原来一直是使用log4js做日志输出,原来只是输出到标准输出中,一直没换过。现在为了将详细的日志都记录下来,不光输出到标准出,而且根据服务的分层输出到不同的文件中。如:全部的log都输出到debug文件及标准输出中,service层的log输出service.log文件中,dao层的log输出到dao.log文件中,为了防止log文件过大,需按日期切分,如:按天。

为何选择winston

1.githubstart数多,够直接把。

2.更加灵活,可以灵活的组织transport,来完成比较复杂的日志输出任务。

3.日志格式为json字符串,方便后期分析,当然可以自定义format.

4.支持简单的log分析,Profiling。

5.支持streamApi。

6.简单Log QueryApi,当然无法和专业的日志分析工具比。

达到的效果

1.按天生成日志文件。

2.根据不同的代码分层来产生不同的log输出到不同的文件。

3.所有分层产生的log不光输出到log文件还要输出到标准输出。

4.自定义格式化日志输出,输出到标准输出的格式便于读取,输出到log文件的格式便于分析。

5.可以捕获系统崩溃异常。

日志输出方法

整合多个transport及封装

格式化输出到标准输出的日志格式。

格式为

[2017-09-21 23:41:05.122] [DEBUG] - 输出日志的module 日志详细信息

但是在winston中没有可以像log4js一样可以定义category,为了达到这个效果,我们利用winston的 meta 特性来实现这一功能。winston中log方法输出的最后一个参数为对象的话,会被解析成 meta,我们在meta中自定义一个
module字段来标记日志来自哪个模块。

constmyLogFormatter=function(options) {

consttimestamp=options.timestamp();

constlevel=options.level.toUpperCase();

constmessage=options.message||'';

letmodule='default';

// meta中module,标记日志来自哪个模块

if(options.meta&&options.meta.module) {

module=options.meta.module;

}

constformatted=`[${timestamp}] [${level}]${module}- `;

if(options.colorize) {

constcolorStr=winston.config.colorize(options.level, formatted);

return`${colorStr}${message}`;

}

return`${formatted}${message}`;

};

创建标准输出的transport

consttransportConsole=newwinston.transports.Console({

json:false,

prettyPrint:true,

colorize:true,

level:'debug',

timestamp:function() {

returnmoment().format('YYYY-MM-DDHH:MM:ss.SSS');

},

formatter:myLogFormatter,

});

创建所有日志输出到文件的transport,日志输出到debug.log

constdebugTransportFile=newwinston.transports.File({

name:'full',

filename: __dirname+'/logs/debug.log',

json:true,

level:'debug',

maxsize:1024*1024*10// 10MB

});

service模块专用输出到文件的transport,日志输出到service.log

constserviceTransportFile=newwinston.transports.File({

name:'service',

filename: __dirname+'/logs/service.log',

json:true,

level:'debug',

maxsize:1024*1024*10// 10MB

});


dao模块专用输出到文件的transport,日志输出到dao.log

constdaoTransportFile=newwinston.transports.File({

name:'dao',

filename: __dirname+'/logs/dao.log',

json:true,

level:'debug',

maxsize:1024*1024*10// 10MB

});


为各个container添加transport。

// default container输出日志到标准输出及debug.log文件中

winston.loggers.add('default', {

transports: [

transportConsole,

debugTransportFile

],

});

// service container输出日志到标准输出、debug.log及service.log文件中

winston.loggers.add('service', {

transports: [

transportConsole,

serviceTransportFile,

debugTransportFile

],

});

//daocontainer输出日志到标准输出、debug.log及dao.log文件中

winston.loggers.add('dao', {

transports: [

transportConsole,

daoTransportFile,

debugTransportFile

],

});

代理各个container的debug、info等方法,达到可以显示日志来自哪个module的功能。

constdefaultLog=winston.loggers.get('default');

constserviceLog=winston.loggers.get('service');

constdaoLog=winston.loggers.get('dao');

//封装default

constgetDefaultLogger=(module)=>{

return{

debug: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

defaultLog.debug.apply(defaultLog,fullParams);

},

info: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

defaultLog.info.apply(defaultLog,fullParams);

},

warn: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

defaultLog.warn.apply(defaultLog,fullParams);

},

error: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

defaultLog.error.apply(defaultLog,fullParams);

}

};

};

//封装service

constgetServiceLogger=(module)=>{

return{

debug: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

serviceLog.debug.apply(serviceLog,fullParams);

},

info: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

serviceLog.info.apply(serviceLog,fullParams);

},

warn: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

serviceLog.warn.apply(serviceLog,fullParams);

},

error: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

serviceLog.error.apply(serviceLog,fullParams);

}

};

};

//封装dao

constgetDaoLogger=(module)=>{

return{

debug: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

daoLog.debug.apply(daoLog,fullParams);

},

info: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

daoLog.info.apply(daoLog,fullParams);

},

warn: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

daoLog.warn.apply(daoLog,fullParams);

},

error: (...args)=>{

constmeta={ module};

constfullParams=args.concat(meta);

daoLog.error.apply(daoLog,fullParams);

}

};

};

封装后如何使用?

比如在我们代码代码的service层中的userService中打印日志“登录成功”,日志级别为info。

getServiceLogger('userService').info('登录成功');

控制台输出为:

[2017-09-22 00:09:45.026] [INFO]userService-登录成功

此日志会输出在标准输出中、debug.log中及service.log中,日志中写入的控制台输出的略有不同。

写入的日志格式为:

{"module":"userService","level":"info","message":"登录成功","timestamp":"2017-09-21T16:01:45.026Z"}



 推荐知识

 历史版本

修改日期 修改人 备注
2020-06-23 20:41:18[当前版本] 朱凡 创建版本

知识分享平台 -V 4.8.7 -wcp