🪵

個人的log4js設定

2022/01/08に公開

TSのプロジェクトで、log4jsの設定を毎回調べて作ってる気がしたのでまとめメモ ✍

やりたいこと

  • ファイルとコンソールに全てのログを吐く
    • ファイルは日毎でローテーション & 旧いやつはgz圧縮
  • 全てのレコードを1行で出力
  • ロガーにオブジェクトが渡されたらいい感じに inspect される
  • ログメッセージ中にロギングしたソースファイル & 行が出る
log.ts
import log4js from "log4js";
import path from "path";
import util from "util";

const logDirectory = path.join(process.cwd(), "logs");
const logLayout = {
  type: "pattern",
  pattern: "%d %p %c %f:%l %x{singleLine}",
  tokens: {
    singleLine: function (logEvent: { data: Array<unknown> }) {
      return logEvent.data
        .map((d) => {
          if (
            typeof d === "boolean" ||
            typeof d === "number" ||
            typeof d === "string"
          ) {
            return d.toString().replace(/\n/gm, "\\n");
          } else {
            return util
              .inspect(d, { breakLength: Infinity })
              .replace(/\n/gm, "\\n");
          }
        })
        .filter((d) => d.length > 0)
        .join(" ");
    },
  },
};

log4js.configure({
  appenders: {
    console: {
      type: "console",
      layout: logLayout,
    },
    app: {
      type: "dateFile",
      layout: logLayout,
      filename: path.join(logDirectory, "app.log"),
      pattern: "-yyyy-MM-dd",
      daysToKeep: 7,
      compress: true,
    },
  },
  categories: {
    default: {
      appenders: ["console", "app"],
      level: "all",
      enableCallStack: true,
    },
  },
});

使う側はそのまま getLogger() を呼び出せばOK

import { getLogger } from "log4js";
const logger = getLogger();

// 略

logger.info("enqueued:", sqsResponse);
logger.error(new Error("piyo"));

吐かれるログのイメージ

log/app.log
2022-01-08T07:40:46.915 INFO default /app/src/sample.ts:10 enqueued: { ResponseMetadata: { RequestId: 'xxx' }, MD5OfMessageBody: 'yyy', MessageId: 'zzz' }
2022-01-08T07:40:46.916 ERROR default /app/src/sample.ts:11 Error: piyo\n    at TestService.<anonymous> ~

そんだけ 😌

参考文献

Discussion