配置

log4js.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
/**
* pm2 (boolean) (optional)
* - set this to true if you’re running your app using pm2,
* otherwise logs will not work (you’ll also need to install pm2-intercom as pm2 module: pm2 install pm2-intercom)
*/
pm2: true,
/**
* pm2InstanceVar (string) (optional, defaults to ‘NODE_APP_INSTANCE’)
* - set this if you’re using pm2 and have changed the default name of the NODE_APP_INSTANCE variable.
*/
pm2InstanceVar: "isMaster"
/**
* disableClustering (boolean) (optional)
* - set this to true if you liked the way log4js used to just ignore clustered environments,
* or you’re having trouble with PM2 logging. Each worker process will do its own logging. Be careful with this if you’re logging to files, weirdness can occur.
*/
// disableClustering: true,
...
}

pm2.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"apps": [
{
"name": "name",
"script": "bin/run",
"exec_mode": "cluster",
"ignoreWatch": ["node_modules"],
"instances": "4", #配置`max`,则自动匹配当前机器的cpu数
"watch": false,
"error_file": "log/pm2/error.log", #如果不输出则配置`/dev/null`
"out_file": "log/pm2/out.log", #如果不输出则配置`/dev/null`
"pid_file": "log/pm2/pid.log", #如果不输出则配置`/dev/null`
"merge_logs": true, #让所有进程日志都写进同一个日志,启动时添加参数--merge-logs <具体日志文件>
"instance_var": "isMaster" #对应pm2InstanceVar
}
]
}

日志插件pm2-intercom

对于一个线上的项目,可能需要一些其他手段来对日志做维护管理(例如日志文件的大小,以及日志保存多久)。既然现在说 pm2 ,就要看下其日志插件:pm2-logrotate

来看下具体配置:

1
2
3
4
5
6
7
8
9
10
11
C:\Users\94391>pm2 install pm2-intercom
C:\Users\94391>pm2 get pm2-logrotate
Module: pm2-logrotate
$ pm2 set pm2-logrotate:max_size 10M
$ pm2 set pm2-logrotate:retain 30
$ pm2 set pm2-logrotate:compress false
$ pm2 set pm2-logrotate:dateFormat YYYY-MM-DD_HH-mm-ss
$ pm2 set pm2-logrotate:workerInterval 30
$ pm2 set pm2-logrotate:rotateInterval 0 0 * * *
$ pm2 set pm2-logrotate:rotateModule true
Modules configuration. Copy/Paste line to edit values.

定时轮询

rotateIntervalworkerInterval 都有定时的作用。

前者通过编写 cron 表达式,约定每隔多少时间 强制 检查日志的状态。

1
2
3
4
# 每日零点
rotateInterval: 0 0 * * *
# 每分钟
rotateInterval: */1 * * * *

后者 workerInterval 是约定固定秒数来查询日志状况。(默认 30 秒)

日志分割条件

max_sizeretain 分别来约束日志的大小,和文件个数

每次 定时轮询 触发后,会对文件大小,数量进行检查。超过约定的值,则会重新创建新文件。

实际运用

假设单日日志产出为 10G ,按照 rotateInterval 每天零点进行切割日志,虽然有章法,但如果要从 10G 大小的日志文件中排查问题,这似乎有些困难。

我们可以设置 max_size 为 100M ,这样 10G 总大小的文件,将在一天中被切成 100 个。

甚至如果每天的访问量有迹可循,比如上午 9-12 点会出现高峰,其他时间相对低频。可以进一步优化 workerInterval 和 rotateInterval cron 表达式:

1
2
pm2 set pm2-logrotate:workerInterval 3600 #每小时轮训检查
pm2 set pm2-logrotate:rotateInterval 0/30 0,9,10,11,12 * * * #每天 0 点,以及 9~12 点每半小时触发

这样在高访问时间段,可以跟有效的分割日志。(美中不足的是如果符合日志分割条件,00:00 和 00:30 时,会出现两份日志,强迫症表示不太适应)