首页 > 代码库 > 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);

 

实现方式:

  1. 在 getLogger 中,获取到 log4js 的 logger 之后,重定义每个日志函数,如 log、error 等
  2. 在其中实现对前缀、行号、前缀及行号的颜色支持

 

重定义的日志函数的实现:

  1. 如果 catagoryName 为文件名,从中去掉当前的目录前缀
  2. 初始化 prefix 变量为空串
  3. 如果是原始模式(process.env.RAW_MESSAGE 为真,这个环境变量也是 polemo-logger 扩展的),直接调用原始 log4js 对应的日志函数,即跳转到 6
  4. 否则,如果存在前缀参数列表的话,构造参数列表字符串,形如 "[a] [b]",赋值到 prefix
  5. 如果存在参数列表的话,并且需要显示行号(process.env.LOGGER_LINE),则在 prefix 增加 行号,如“4: ”
  6. 调用 log4js 的对应日志函数
  7. 返回

 

二、行号的支持

行号的正确显示使用了技巧。

 

  1. 构造一个 Error 类
  2. 将其中的 stack 成员,按照回车拆分字符串,取第四行
  3. 按冒号拆分,取第二个

 

在 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 的控制台支持它。

 

实现方式是:

  1. 从 log4js 中复制变量 styles,表示当前样式对应的 ASCII 转义
  2. 从 log4js 中复制变量 colours,表示不同优先级对应的样式
  3. 从 log4js 中复制 colorizeStart、colorizeEnd、colorize 函数,它们接收字符串与样式参数,返回处理后的字符串
  4. 由当前的日志优先级,获取到相应的样式,并调用 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 的子集,并进行了小功能改进及限制。

 

分类名称实现位置
LoggergetLoggerpolemo-logger
 getDefaultLoggerlog4js
配置configurepolemo-logger
AppenderaddAppenderlog4js
 loadAppenderlog4js
 clearAppenderslog4js
 appenderslog4js
控制台replaceConsolelog4js
 restoreConsolelog4js
优先级levelslog4js
 setGlobalLogLevellog4js
布局layoutslog4js

 

七、综述

我的感觉是,增强部分意义较大,弱化部分中 appender 的去除意义较小,除非 log4js 的相关代码存在着 BUG。

 

八、参考:

https://github.com/NetEase/pomelo-logger/

https://github.com/nomiddlename/log4js-node/