技术 | 打造视觉感很棒的 Node.js Log 日志系统

6,017 阅读3分钟
原文链接: mp.weixin.qq.com

还在用console.log来写日志么?那就太Low了。


一个有明显色彩的日志,对于开发会是一个多么好的体验。警告是黄色,错误是红色,普通信息是绿色的标记,一眼就能区分,如果再带上时间,更完美了。今天想分享一个开源库:winston,专门来处理Node.js的日志,除了命令行之外,还能将日志保存为物理文件,而且是序列化过后的,留待将来可以排查定位问题。


github.com/winstonjs/w…



是不是看起来,比console.log要舒服很多呢?


我们主要使用到了winston这个日志库,老规矩:"npm install winston --save",给你的项目安装这个库吧。


导入winston之后,默认就可以使用info,log等方法来输出日志,不过这些默认格式化缺少很多详细的信息,比如时间戳,机器名,进程id等,显然这些不是那么适合机器来处理,怎么办呢?


你可以自己拼接这些信息:


 winston.log('info', 'Test Log Message', { anything: 'This is metadata' });


这是自己手动将信息拼接到日志里,方便自己查阅。而且log方法可以设置输出的级别,比如错误用红色标识,警告用黄色标识。



logger.log('warn','icepy')
logger.log('error','icepy')


这些都可以在开发环境里使用,如果到了线上生产部署的时候,这个命令行输出必然没有价值了,怎么办?只好将日志保存到物理文件中了。


winston对于输出和日志的配置给了很详细的配置清单,有兴趣的朋友可以看一看官方的配置信息。


// 错误日志

const errorTransport = new (winston.transports.File)({ name: 'error', filename: path.resolve(logDir,'error.log'), timestamp: dateFormat, level: 'error', colorize: true
});


正常情况下,错误的日志是没有行号的,如果你想抓去错误栈,还需要使用另外一个stack-trace(github.com/felixge/nod…)模块来配合使用,这个模块专门针对V8引擎来获取当前方法栈信息。


基本思路是替换掉winston的error方法:


const originLoggerMethod = logger.error;
logger.error = function () {
   const cellSite = stackTrace.get()[1];
   originLoggerMethod.apply(logger,[
       arguments[0]+'\n', { filePath:cellSite.getFileName(), lineNumber:cellSite.getLineNumber() } ]); }

 

那最终的代码该如何写呢?明显在生产环境中,我们并不需要日志,其实很简单。


const fs = require('fs');
const path = require('path');
const winston = require('winston');
const moment = require('moment');
const stackTrace = require('stack-trace');
const _ = require('lodash');
const RotateFile = require('winston-daily-rotate-file');
const env = process.env.NODE_ENV;
const logDir = path.resolve('.','log');
let logger;
const dateFormat = function () {
return moment().format('YYYY-MM-DD HH:mm:ss:SSS'); } logger = new (winston.Logger)({ transports: [
new winston.transports.Console({ timestamp: dateFormat, colorize: true }) ] });

logger.dbLogger = new (winston.Logger)({ transports: [
       new winston.transports.Console({ timestamp: dateFormat, colorize: true }) ] });
if (env === 'product') { //处理物理文件日志 }

module.exports = logger;


大家想一想,env === 'product' 中该补全怎样的代码,来提供输出物理日志功能。




欢迎大家关注象尘说-编程之道“小密圈”,如果你还不知道“小密圈”有什么作用,可以点击菜单栏上“小密圈”来获取详情。


地址链接:https://wx.xiaomiquan.com/mweb/views/joingroup/join_group.html?group_id=5414881224&secret=ql23uqjlnm80lxm9od6llkqijltb5r3u&extra=3e73c043fd796c547b54675d60d9b7bc343c71590f108862080eb35eb863bb1c




更多精彩内容可关注我的个人微信公众号:搜索fed-talk或者扫描下列二维码,也欢迎您将它分享给自己的朋友。