首页 > 代码库 > polemo-logger 分析
polemo-logger 分析
polemo-logger 是网易游戏框架 polemo 所用的日志系统接口,对 log4js-node 进行了封装,有其弱化及增强之处。具体描述为:
- 增强部分
- 多前缀的支持
- 行号的支持
- 前缀、行号颜色的支持
- 配置项的取值来源支持:环境变量、 命令行参数、可选项
- 弱化部分(或限制部分)
- 定时配置文件的加载函数中去掉了 appender 的变化支持,只保留了 level、replaceConsole 的动态加载
- reloadSecs 从 opts 移动到了配置(config)中
- 大幅减少模块导出函数
一、多前缀、行号、及其颜色的显示
通常,每行的日志消息格式如下。
[2010-01-17 11:43:37.987] [DEBUG] [default] - Some debug messages
- DEBUG 为优先级
- default 为类别,category
而polemo-logger增加的多前缀,形如:
[2014-07-01 14:29:39.193] [INFO] log - [/Users/xxx/pomelo-logger/examples/log.js] [1334] test1
[/Users/pomelo-logger/examples/log.js]、[1334] 即为前缀。前缀格式可以为0个,也可以为1到多个。
支持多前缀的调用方式如:
var logger = require(‘pomelo-logger‘).getLogger(‘log‘, __filename, process.pid);
实现方式:
- 在 getLogger 中,获取到 log4js 的 logger 之后,重定义每个日志函数,如 log、error 等
- 在其中实现对前缀、行号、前缀及行号的颜色支持
重定义的日志函数的实现:
- 如果 catagoryName 为文件名,从中去掉当前的目录前缀
- 初始化 prefix 变量为空串
- 如果是原始模式(process.env.RAW_MESSAGE 为真,这个环境变量也是 polemo-logger 扩展的),直接调用原始 log4js 对应的日志函数,即跳转到 6
- 否则,如果存在前缀参数列表的话,构造参数列表字符串,形如 "[a] [b]",赋值到 prefix
- 如果存在参数列表的话,并且需要显示行号(process.env.LOGGER_LINE),则在 prefix 增加 行号,如“4: ”
- 调用 log4js 的对应日志函数
- 返回
二、行号的支持
行号的正确显示使用了技巧。
- 构造一个 Error 类
- 将其中的 stack 成员,按照回车拆分字符串,取第四行
- 按冒号拆分,取第二个
在 var e = new Error(); 后,打印 Error 的栈,如下:
Error
at getLine (/Users/xxx/pomelo-logger/lib/logger.js:243:10)
at Object.pLogger.(anonymous function) [as info] (/Users/xxx/pomelo-logger/lib/logger.js:39:10)
at Object.<anonymous> (/Users/xxx/pomelo-logger/examples/log.js:4:8)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3
三、颜色的支持
polemo-logger 对前缀、行号使用了与优先级一致的颜色。利用 ASCII 的控制码进行前景颜色的显示。Linux、MacOSX 的控制台支持它。
实现方式是:
- 从 log4js 中复制变量 styles,表示当前样式对应的 ASCII 转义
- 从 log4js 中复制变量 colours,表示不同优先级对应的样式
- 从 log4js 中复制 colorizeStart、colorizeEnd、colorize 函数,它们接收字符串与样式参数,返回处理后的字符串
- 由当前的日志优先级,获取到相应的样式,并调用 colorize 来获得带有颜色支持的字符串
四、配置项的取值来源扩展
configure 函数负责进行日志系统的配置(config,文件或对象)及选项(opts)设置。
polemo-logger 在 configure 函数中,对配置项的取值进行了扩展,支持环境变量(process.env)、 命令行参数(process.argv),及可选项(opts)。
当配置项的赋值类型为字符串,并且符合格式 {scope:arg-name} 时,就会触发此扩展。
scope 的有效值:env、args、opts。
arg-name 为其中 key 的名字。
五、ReloadSecs
ReloadSecs 表示自动重新加载配置文件的时间间隔,以秒为单位,为0时不会自动加载。
在 configure 函数中调用了重新加载的初始化函数 initReloadConfiguration,即初始化重新加载功能所需的参数。
并在 initReloadConfiguration 中调用了 setInterval 函数,定期执行重新加载操作 reloadConfiguration。
这个 reloadConfiguration 函数会检查并记录配置文件的最后修改时间,两相比较,不同时才会加载,以确保配置文件每次变化后只被加载一次。
polemo-logger 的 configure 最终还是会调用 log4js 的此函数。
从 configure 函数,直到 reload 相关的各个函数,polemo-logger 对 log4js 所做的修改为:
- 在 configure 函数中,对配置项的取值来源进行扩展
- 在 configure 函数中,支持自定义的 lineDebug(行号是否显示)、config.rawMessage(是否不显示前缀及行号)
- 在 configure 函数中,读取 reloadSecs,并调用 initReloadConfiguration
- 在 configureOnceOff 函数(reloadConfiguration 所调用的函数,即对具体配置项进行应用和设置的函数)中,去掉了 appenders(如文件 file、控制台 console 等) 的设置
ReloadSecs 从 opts 移动到了 config(配置文件或对象) 中,大概是为了让自动重新加载的时间间隔以配置项的形式存在。
而在重新加载函数中去除了对 appenders 的应用和设置,意图不清楚,或者具体意义有多大也不清楚,代价就是从 log4js 中引入(复制)了6个函数。
六、模块导出 (module.exports)
因为 polemo-logger 是 log4js 的封装,那么它的导出也就是对使用方所期望使用的功能限定。从下表看, polemo-logger 是 log4js 的子集,并进行了小功能改进及限制。
分类 | 名称 | 实现位置 |
Logger | getLogger | polemo-logger |
getDefaultLogger | log4js | |
配置 | configure | polemo-logger |
Appender | addAppender | log4js |
loadAppender | log4js | |
clearAppenders | log4js | |
appenders | log4js | |
控制台 | replaceConsole | log4js |
restoreConsole | log4js | |
优先级 | levels | log4js |
setGlobalLogLevel | log4js | |
布局 | layouts | log4js |
七、综述
我的感觉是,增强部分意义较大,弱化部分中 appender 的去除意义较小,除非 log4js 的相关代码存在着 BUG。
八、参考:
https://github.com/NetEase/pomelo-logger/
https://github.com/nomiddlename/log4js-node/