Lynne,一个能哭爱笑永远少女心的前端开发工程师。身处互联网浪潮之中,热爱生活与技术。
前言
一年前参加打卡活动将学习中匆忙整理的文章发了出来,大篇幅摘抄形成抄袭,首先向作者致歉,并附参考文章地址:zhuanlan.zhihu.com/p/22110802
原文内容很翔实,看到这儿的小伙伴可以去原文加强学习。
保留本文,一方面警醒自己,日后坚持原创,一方面决定重写本文,顺便复习下我的日志收集分类管理是如何做的。
本文还是从以下三个方面介绍,结合实际工作:
- 日志分级
- 日志分类
- 日志落盘
看完本文介绍的 log4js,你将可以:
- 了解log4js基本结构
- 在项目中使用log4js
实践指南
背景
项目采用服务端渲染同构框架,服务端渲染基于node开发,因此要收集node端请求日志,以及项目中的一些log 及错误日志。
对比过网上实践后决定借助 log4js 编写日志收集中间件。
举个栗子
// file: index.js
import config from '../config' // 导入config配置文件的基本配置信息
import log4jsLog from 'log4js'; // 导入依赖包
import log4jsLogConfig from '../log4js.config'; // 导入配置文件内的配置信息
const logConfig = log4jsLogConfig(config) // 生成最终的配置信息
log4jsLog.configure(logConfig); // 出于配置能更丰富更清晰,借助log4js的API .configure()方法配置日志分类
const graylog = log4jsLog.getLogger('grayLog'); // 生成log4js 的 Logger 实例
graylog.info(`###gtraceStart###${JSON.stringify(traceInfo)}###gtraceEnd### #PRIVATE_JSON_START#${JSON.stringify(statistics)}#PRIVATE_JSON_END#`); // 调用实例上的api方法
其中 Logger 实例上具有9个API方法是对应到下一小结要讲的日志分级。
为什么使用 log4js 之 log4js 基本能力
level - 日志分级
日志分级这一点可以对应到我们日常使用console.log()方法的console,我们都知道可以通过console的不同api方法输出不同格式日志。其实从日志类型级别的角度看,它也是可以分成不同级别的,主要有:log、info、trace、warn、error,而这里要讲的log4js的分级则更加丰富,也是我们为什么使用loag4js的主要原因。
log4js 的日志分为九个等级,各个级别的名字和权重参考log4js源码中设置如下:
Level.addLevels({
ALL: { value: Number.MIN_VALUE, colour: 'grey' },
TRACE: { value: 5000, colour: 'blue' },
DEBUG: { value: 10000, colour: 'cyan' },
INFO: { value: 20000, colour: 'green' },
WARN: { value: 30000, colour: 'yellow' },
ERROR: { value: 40000, colour: 'red' },
FATAL: { value: 50000, colour: 'magenta' },
MARK: { value: 9007199254740992, colour: 'grey' }, // 2^53
OFF: { value: Number.MAX_VALUE, colour: 'grey' }
});
理一下 log4js 通过日志分级展示日志的主要优点:
- 不同级别的日志可以在控制台中采用不同的颜色,比如 error 采用红色重点强调
- 在生产可以有选择的落盘日志:比如error日志、warn日志和其他级别日志单独存放,更方便仅对error日志进行报警处理
category - 日志类型
category可以理解为区分日志的另外一个维度。
通过设置一个 Logger 实例的类型,可以合并落盘不同级别的日志,按照自己的需求组合日志,毕竟实际情况下我们并非一定要完全区分九个级别的日志。
Appender -- 日志落盘
Appender 进一步解决日志落盘问题。
这里我们主要通过 .configure()方法配置日志分类,参数中包含对appender的配置,对日志的级别和类别进行过滤。
layout -- 日志格式
通过 layout 可以自定义输出日志的格式。log4js 内置了物五种类型的格式:
-
basic:在日志的内容前面会加上时间、日志的级别和类别,通常日志的默认 layout;
-
colored/coloured:在 basic 的基础上给日志加上颜色,官方提供参考:
TRACE- ‘blue’DEBUG- ‘cyan’INFO- ‘green’WARN- ‘yellow’ERROR- ‘red’FATAL- ‘magenta’
-
Message Pass-Through:只格式化日志事件数据,而不输出时间戳、级别或类别。通常用于使用特定格式序列化事件的追加器;
-
pattern:这是一种特殊类型,可以通过它来定义任何你想要的格式,这是最灵活也是我采用的一种;
-
Dummy:此布局只输出日志事件数据中的第一个值。它是为logstashUDP appender添加的。
配置实战
上面提到的知识点都体现在这个配置文件中了
// file: log4js.config.js
log4jsLog.configure(logConfig); // 借助log4js的API .configure()方法配置日志分类
export default function(logConfig: LogConfig) { // 入参即为上面import config from '../config'导入的基本配置信息
const logDir: string = logConfig.logDir || './logs/';
const logFilePrefix: string = logConfig.logFilePrefix || 'app';
const pattern: string =
logConfig.pattern || '%d{yyyy-MM-dd hh:mm:ss} %p %c %m%n'; // pattern配置日志输出格式
const pm2: boolean = logConfig.pm2;
return {
pm2,
pm2InstanceVar: 'INSTANCE_ID',
appenders: {
infoLog: createLog( // 业务应用 log 日志: - default: info-error
`${logFilePrefix}-out.log`,
true,
logDir,
pattern,
isProd
),
warnLog: createLog( // 业务应用 warn 日志 - default: warn
`${logFilePrefix}-warn.log`,
true,
logDir,
pattern,
isProd
),
errorLog: createLog( // 业务应用 error 日志 - default: error
`${logFilePrefix}-error.log`,
true,
logDir,
pattern,
isProd
),
grayLog: createLog( // 中间件请求日志:info-warn - graylog: info-warn
`${logFilePrefix}-ctx-access.log`,
true,
logDir,
pattern,
isProd
),
grayError: createLog( // 中间件请求日志:error-fatal - graylog: info-error
`${logFilePrefix}-ctx-error.log`,
true,
logDir,
pattern,
isProd
),
filterInfo: {
type: 'logLevelFilter',
appender: 'infoLog',
level: 'info',
maxLevel: 'error',
},
filterWarn: {
type: 'logLevelFilter',
appender: 'warnLog',
level: 'warn',
maxLevel: 'warn',
},
filterError: {
type: 'logLevelFilter',
appender: 'errorLog',
level: 'error',
maxLevel: 'error',
},
filterGrayLog: {
type: 'logLevelFilter',
appender: 'grayLog',
level: 'info',
maxLevel: 'warn',
},
filterGrayError: {
type: 'logLevelFilter',
appender: 'grayError',
level: 'error',
maxLevel: 'fatal',
}
},
categories: {
grayLog: {
appenders: ['filterGrayLog', 'filterGrayError'],
level: 'info',
},
default: {
appenders: isProd ? ['filterWarn', 'filterError'] : ['filterInfo'],
level: isProd ? 'warn' : 'info',
}
}
}
}
总结
上述近介绍了我对log4js的基本配置使用,一般我们是借助实例的api方法进行日志收集与落盘,借助log4js对日志的分级,我还做了一些诸如重写console的log、info、warn和error方法,在中间件上下文ctx添加log方法,实现业务与中间件中的日志落盘。更多地大家就可以自由发挥了。
最后为自己之前的抄袭行为反省致歉,发表到社区的文章不同于笔记,尊重作者。