Nodejs中使用Log4js

时间:2024-05-23 20:12:53


因为log4js-node从log4js移植而来,两者并不属于同一个模块,也有很多区别,下面为了区分和防止误解统一使用“log4js-node”这个名称,注意nodejs代码中引入模块时还是要用“require(‘log4js’)”。

1. 快速开始
1.1. 简单终端log
先看一下使用log4js-node 最简单的代码:
Nodejs中使用Log4js

运行的结果如下:
Nodejs中使用Log4js
首先log4js-node将输出的log分为六个的level,每个level的含义从字面就可以看出, 对于不同的level,log输出到终端时会使用不同的颜色(trace: 蓝色,debug: 青色, info:绿色,warn:黄色,error:红色, fatal:粉色)。终端是log4js-node的默认输出地点。

默认情况下,log4js-node的每条log输出格式有如下几个字段:日志产生时间,level,日志分类,日志内容。如果用户没有配置,日志分类字段为“default”。

1.2. 文件log
代码:
Nodejs中使用Log4js

运行结果如下:
Nodejs中使用Log4js

Nodejs中使用Log4js

这个例子当中我们将日志存储到文件当中,并进行文件分割,具体的日志tag(或category)使用文件名。

2. 基本配置和基本分类

代码,注意用户需要先在项目目录下创建名为“logs”的目录:
Nodejs中使用Log4js

终端结果:
Nodejs中使用Log4js

__dirname/logs/login.log文件中输出结果,其中__dirname是项目根目录:
Nodejs中使用Log4js

__dirname/logs/signup.log文件中得输出结果:
Nodejs中使用Log4js

代码中我们调用了log4js-node的configure函数,该函数中我们传入了一个json对象,json对象中我们为log4js-node指定了三个appender,分别是一个终端和两个文件。我们也为两个文件appender指定了存储文件路径,和分类,路径决定了每个appender输出的log所存储文件的位置和名称,分类对应于前文提到的日志输出格式的分类字段。一个appender相当于一个日志输出目标,该目标决定了对应日志的输出格式,存储位置等。

指定不同的appender后,我们在调用log4js-node的getLogger()时需要指定对应的appedner的分类名,比如“getLogger(‘login’)”, 如果不指定默认为输出到终端的appender。

我们还可以以配置文件的方式来提供配置,只需要将文件路径传给log4js-node的configure的函数即可,效果一样。上面的配置我们改为以下实现方式,首先我们在项目的根目录下新创建一个“conf”目录(这里的名称可以根据自己的情况随意取),然后将如下配置内容存到conf目录下,并命名为“log4js_conf.json”(这里的文件名称也可以随便取,但后缀名要为.json):
Nodejs中使用Log4js

然后我们将之前代码中的log4js.configure()调用语句改为:log4js.configure(__dirname + '/conf/log4js_conf.json’)。运行后结果与前面相同。注意文件配置时, filename对应的路径默认从app的根目录开始。

到这里,我们已经能够将日志进行分类输出,并存储到不同的文件当中,这已经能够满足一般的业务需求了。但是,如果我们想定制日志的输出格式该怎么办呢?另外,目前日志虽然分到不同的文件中,但是每个文件都是无限增长的,话句话说如果日志足够多的话,我们的单个日志文件将会非常大,这为我们打开日志文件和分析日志增加了难度,如何才能解决这个问题呢?这些问题我们将在后文种做详细介绍。

3. 高级设置
3.1. 为log设置不同的level
设置log level有两种主要的方式,一种是在代码中通过调用每个logger的setLevel函数,另外一种是在配置文件中加入levels选项。首先看第一种,我们为之前的两个logger“loginLogger4js”和“signupLogger4js”分别调用setLevel函数,具体如下:
Nodejs中使用Log4js

终端输出结果如下:
Nodejs中使用Log4js

然后我们将第一种方式的setLevel函数调用去掉,换用第二种方式,在之前的配置文件“log4js_conf.json”中加入level配置选项如下:
Nodejs中使用Log4js

终端的输出结果如下,与第一种方式相同:
Nodejs中使用Log4js
当然我们还可以,直接设置全局的level,这样我们就不用为每个logger单独配置了,如果全局配置和具体logger的配置同时存在,那么log4js-node会以具体logger的配置为准。全局level也是两种方式:代码中和文件中。首先看前者,我们将之前的每个logger的level配置代码都去掉,然后再代码中加入如下一句:
Nodejs中使用Log4js

运行结果如下:
Nodejs中使用Log4js

第二种全局level配置方式,我们把配置文件“log4js_conf.json”内容改为如下:
Nodejs中使用Log4js

运行结果如下:
Nodejs中使用Log4js
3.2. 将日志文件分开存储
这个配置并不是使用所有的appender的,比如在console就是不需要的,这里只讨论appender 的type为’file’的情况。首先我们看一下log4js内置的file appender的初始化函数:
Nodejs中使用Log4js

从注释中我们就可以看书第三个参数“logSize”和第四个参数“numBackups”决定了是否要分割日志文件,每个日志文件的最大容量,以及最大的文件数。这两个参数对应于配置中的“maxLogSize”和“backups”选项, 前者单位是bytes, 后者单位是个。接着前面的例子,我们在将配置文件改为如下内容(后面内容我们统一用配置文件的方式):
Nodejs中使用Log4js

生成的日志备份如下:
Nodejs中使用Log4js

若果超出了总大小旧的文件会被覆盖掉。

3.3. http log
安装后log4js-node代码中自带一个“example-connect-logger.js”例子,它展示了如何使用log4js输出http log。这里不再赘述,不过要说明一下如何定制输出格式。

首先看源码中关于connect-logger.js中getLogger函数的注释:

/**
 * Log requests with the given `options` or a `format` string.
 *
 * Options:
 *
 *   - `format`        Format string, see below for tokens
 *   - `level`         A log4js levels instance. Supports also 'auto'
 *
 * Tokens:
 *
 *   - `:req[header]` ex: `:req[Accept]`
 *   - `:res[header]` ex: `:res[Content-Length]`
 *   - `:http-version`
 *   - `:response-time`
 *   - `:remote-addr`
 *   - `:date`
 *   - `:method`
 *   - `:url`
 *   - `:referrer`
 *   - `:user-agent`
 *   - `:status`
 *
 * @param {String|Function|Object} format or options
 * @return {Function}
 * @api public
 */

从注释中我们可以知道有哪些token可以用来定制我们自己的输出格式,这里只举出一个例子来说明。这个例子是比较精简的,主要用来调试,具体如下:

...
var HTTP_LOG_FORMAT_DEV = ':method :url :status :response-time ms - :res[content-length]';
...
app.use(log4js.connectLogger(logger, { level: 'auto', format: HTTP_LOG_FORMAT_DEV }));
...

其中的一个输出结果为:

[2014-12-30 11:48:35.784] [ERROR] log4jslog -GET /users 404 4 ms - 18

因为log4js-node从log4js移植而来,两者并不属于同一个模块,也有很多区别,下面为了区分和防止误解统一使用“log4js-node”这个名称,注意nodejs代码中引入模块时还是要用“require(‘log4js’)”。

1. 快速开始
1.1. 简单终端log
先看一下使用log4js-node 最简单的代码:
Nodejs中使用Log4js

运行的结果如下:
Nodejs中使用Log4js
首先log4js-node将输出的log分为六个的level,每个level的含义从字面就可以看出, 对于不同的level,log输出到终端时会使用不同的颜色(trace: 蓝色,debug: 青色, info:绿色,warn:黄色,error:红色, fatal:粉色)。终端是log4js-node的默认输出地点。

默认情况下,log4js-node的每条log输出格式有如下几个字段:日志产生时间,level,日志分类,日志内容。如果用户没有配置,日志分类字段为“default”。

1.2. 文件log
代码:
Nodejs中使用Log4js

运行结果如下:
Nodejs中使用Log4js

Nodejs中使用Log4js

这个例子当中我们将日志存储到文件当中,并进行文件分割,具体的日志tag(或category)使用文件名。

2. 基本配置和基本分类

代码,注意用户需要先在项目目录下创建名为“logs”的目录:
Nodejs中使用Log4js

终端结果:
Nodejs中使用Log4js

__dirname/logs/login.log文件中输出结果,其中__dirname是项目根目录:
Nodejs中使用Log4js

__dirname/logs/signup.log文件中得输出结果:
Nodejs中使用Log4js

代码中我们调用了log4js-node的configure函数,该函数中我们传入了一个json对象,json对象中我们为log4js-node指定了三个appender,分别是一个终端和两个文件。我们也为两个文件appender指定了存储文件路径,和分类,路径决定了每个appender输出的log所存储文件的位置和名称,分类对应于前文提到的日志输出格式的分类字段。一个appender相当于一个日志输出目标,该目标决定了对应日志的输出格式,存储位置等。

指定不同的appender后,我们在调用log4js-node的getLogger()时需要指定对应的appedner的分类名,比如“getLogger(‘login’)”, 如果不指定默认为输出到终端的appender。

我们还可以以配置文件的方式来提供配置,只需要将文件路径传给log4js-node的configure的函数即可,效果一样。上面的配置我们改为以下实现方式,首先我们在项目的根目录下新创建一个“conf”目录(这里的名称可以根据自己的情况随意取),然后将如下配置内容存到conf目录下,并命名为“log4js_conf.json”(这里的文件名称也可以随便取,但后缀名要为.json):
Nodejs中使用Log4js

然后我们将之前代码中的log4js.configure()调用语句改为:log4js.configure(__dirname + '/conf/log4js_conf.json’)。运行后结果与前面相同。注意文件配置时, filename对应的路径默认从app的根目录开始。

到这里,我们已经能够将日志进行分类输出,并存储到不同的文件当中,这已经能够满足一般的业务需求了。但是,如果我们想定制日志的输出格式该怎么办呢?另外,目前日志虽然分到不同的文件中,但是每个文件都是无限增长的,话句话说如果日志足够多的话,我们的单个日志文件将会非常大,这为我们打开日志文件和分析日志增加了难度,如何才能解决这个问题呢?这些问题我们将在后文种做详细介绍。

3. 高级设置
3.1. 为log设置不同的level
设置log level有两种主要的方式,一种是在代码中通过调用每个logger的setLevel函数,另外一种是在配置文件中加入levels选项。首先看第一种,我们为之前的两个logger“loginLogger4js”和“signupLogger4js”分别调用setLevel函数,具体如下:
Nodejs中使用Log4js

终端输出结果如下:
Nodejs中使用Log4js

然后我们将第一种方式的setLevel函数调用去掉,换用第二种方式,在之前的配置文件“log4js_conf.json”中加入level配置选项如下:
Nodejs中使用Log4js

终端的输出结果如下,与第一种方式相同:
Nodejs中使用Log4js
当然我们还可以,直接设置全局的level,这样我们就不用为每个logger单独配置了,如果全局配置和具体logger的配置同时存在,那么log4js-node会以具体logger的配置为准。全局level也是两种方式:代码中和文件中。首先看前者,我们将之前的每个logger的level配置代码都去掉,然后再代码中加入如下一句:
Nodejs中使用Log4js

运行结果如下:
Nodejs中使用Log4js

第二种全局level配置方式,我们把配置文件“log4js_conf.json”内容改为如下:
Nodejs中使用Log4js

运行结果如下:
Nodejs中使用Log4js
3.2. 将日志文件分开存储
这个配置并不是使用所有的appender的,比如在console就是不需要的,这里只讨论appender 的type为’file’的情况。首先我们看一下log4js内置的file appender的初始化函数:
Nodejs中使用Log4js

从注释中我们就可以看书第三个参数“logSize”和第四个参数“numBackups”决定了是否要分割日志文件,每个日志文件的最大容量,以及最大的文件数。这两个参数对应于配置中的“maxLogSize”和“backups”选项, 前者单位是bytes, 后者单位是个。接着前面的例子,我们在将配置文件改为如下内容(后面内容我们统一用配置文件的方式):
Nodejs中使用Log4js

生成的日志备份如下:
Nodejs中使用Log4js

若果超出了总大小旧的文件会被覆盖掉。

3.3. http log
安装后log4js-node代码中自带一个“example-connect-logger.js”例子,它展示了如何使用log4js输出http log。这里不再赘述,不过要说明一下如何定制输出格式。

首先看源码中关于connect-logger.js中getLogger函数的注释:

/**
 * Log requests with the given `options` or a `format` string.
 *
 * Options:
 *
 *   - `format`        Format string, see below for tokens
 *   - `level`         A log4js levels instance. Supports also 'auto'
 *
 * Tokens:
 *
 *   - `:req[header]` ex: `:req[Accept]`
 *   - `:res[header]` ex: `:res[Content-Length]`
 *   - `:http-version`
 *   - `:response-time`
 *   - `:remote-addr`
 *   - `:date`
 *   - `:method`
 *   - `:url`
 *   - `:referrer`
 *   - `:user-agent`
 *   - `:status`
 *
 * @param {String|Function|Object} format or options
 * @return {Function}
 * @api public
 */

从注释中我们可以知道有哪些token可以用来定制我们自己的输出格式,这里只举出一个例子来说明。这个例子是比较精简的,主要用来调试,具体如下:

...
var HTTP_LOG_FORMAT_DEV = ':method :url :status :response-time ms - :res[content-length]';
...
app.use(log4js.connectLogger(logger, { level: 'auto', format: HTTP_LOG_FORMAT_DEV }));
...

其中的一个输出结果为:

[2014-12-30 11:48:35.784] [ERROR] log4jslog -GET /users 404 4 ms - 18