天天看点

PM2 && log4js && winston 日志管理

最近在为服务端添加日志,主要是利用PM2和winston、log4js,现将遇到的问题记录下来。

PM2被用于生产环境下进程管理,能够及时获取业务代码中日志信息。

PM2 基本设置如下

PM2 能够获得项目中

winston.log.error

or

console.log.info

信息。基本配置如下,访问localhost:8087,会在

error_file

打印出一条日志。

PS:建议不用直接使用console.log来输出日志信息,减少性能损耗。

// pm2.js
apps : [
        {
            name      : projectName,
            script    : 'app.js',
            env: {
                NODE_ENV: 'development',
                PORT: 8087
            },
            log_file : logFile,
            error_file : errorFile,
            out_file : outFile,
            merge_logs : true,
            log_date_format : 'YYYY-MM-DD HH:mm Z'
        }
    ]

// app.js
const Koa = require('koa');
const app = new Koa();
const winston = require('winston');

app.use(async ctx => {
    if (ctx.request.path === '/') {
        winston.log.error('测试日志');
    }
    ctx.body = 'Hello World';
});

app.listen(8087);
           

log4js 在 pm2 cluster 下不输出日志

log4js 在cluster模式时,worker进程将日志发送给master进程,然后记录到文件。但pm2 在cluster模式时,是将所有进程当做worker进程。导致log4js 在 PM2 cluster下不输出日志。

测试代码如下:

// logger.js
const log4js = require('log4js');

log4js.configure({
  appenders: {
    out: { type: 'file', filename: 'pm2logs.log' }
  },
  categories: {
    default: { appenders: ['out'], level: 'info' }
  }
});

const logger = log4js.getLogger('app');

setTimeout(() => {
  logger.info("I'm forever blowing bubbles");
}, 1000);
           

pm2.json 文件如下

{ 
    "apps": [
        { 
            "name": "testing",
            "script": "logger.js",
            "instances": "max",
            "exec_mode": "cluster"
        }
    ]
}
           

修复方法如下,需要安装pm2的pm2-intercom进程间通信模块

const log4js = require('log4js');

// NOTE: for PM2 support to work you'll need to install the pm2-intercom module
// `pm2 install pm2-intercom`
log4js.configure({
  appenders: {
    out: { type: 'file', filename: 'pm2logs.log' }
  },
  categories: {
    default: { appenders: ['out'], level: 'info' }
  },
  pm2: true,
  pm2InstanceVar: 'INSTANCE_ID'
});

const logger = log4js.getLogger('app');
setTimeout(() => {
  logger.info("I'm forever blowing bubbles");
}, 1000);
           

pm2.json 如下

{ "apps": [
    { "name": "testing",
      "script": "pm2.js",
      "instances": 0,
      "instance_var": "INSTANCE_ID",
      "exec_mode": "cluster"
      }
    ]
}
           

问题思考

  1. PM2 cluster or Node cluster 真有好处吗?好处能有多大?
  2. 通过什么样的压力测试才能检验出性能,才能查看系统的鲁棒性?
  3. 如何做小流量?

参考

  1. log4js donestn't work with pm2 cluster mode
  2. Frequently Asked Questions in log4js
  3. log4js多进程陷阱与避免