天天看點

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多程序陷阱與避免