Posted on

在K8S內node js紀錄log的解決方案

千萬不要使用PM2

PM2是一個在linux裡面管理nodejs程序的好工具,它可以讓nodejs在死掉時自動控制重啟,並可於重啟次數超過時停止重啟
但是由於在K8S之中,這種管理的機制已經交由K8S去管理了,因此,若再於裡面包一層PM2,很容易出問題

可能發生的問題

  • pm2 一開始起來時會依你的參數去試著把 resource 給最大化,所以會一下子把 resource 吃滿,這會讓 k8s 覺得 是不是這個 pod 又很忙了,就馬上又起一個 pod 要來試著接手
  • pm2 會自己重啟 node process : 這會讓 k8s 不知道其實 pod 已經死了,就不會再建新的 pod 來接手

PM2其他功能的替代方案

因為PM2的部分功能與K8S重疊,不推薦使用,那關於PM2另外的文字檔log功能,則有幾種方案可解決

  • container 是吐到 stdout,k8s 的 cri 會寫到 host 上
  • 自己實作log系統

而我們公司由於管K8S的系統的運營部門不處理我們的log的儲存以及打至ELK裡的問題,所以就只能採用第二種方案,以下為我們nodeJS的解決方案log4js

使用nodeJS所推出的log管理系統

https://www.npmjs.com/package/log4js
官方的說明非常簡單好懂,下面為一個基礎使用範例,可每日分檔案,儲存三天

const log4js = require("log4js");
log4js.configure({
    appenders: {
        log: { type: "dateFile", filename: "logs/log.log", pattern: "yyyy-MM-dd", layout: { type: "pattern", pattern: "[%d] %m", }, keepFileExt: true, fileNameSep: "-", numBackups: 3 },
        error: { type: "dateFile", filename: "logs/error.log", pattern: "yyyy-MM-dd", layout: { type: "pattern", pattern: "[%d] %m", }, keepFileExt: true, fileNameSep: "-", numBackups: 3 },
    },
    categories: { default: { appenders: ["log"], level: "debug" }, error: { appenders: ["error"], level: "error" } }
});
var logger = log4js.getLogger();
var logger_error = log4js.getLogger("error");
logger.level = "debug";

exports.log = (...msg) => {
    logger.debug(...msg);
}

exports.error = (...msg) => {
    logger_error.error(...msg);
}