log4js快速寫一個Node服務訪問日誌

範兒發表於2019-03-08

log4js是Node.js中非常棒的日誌模組,使用起來非常簡單且好用。這一篇和大家分享下如何很快的寫一個日誌記錄服務,因為node的中介軟體模式,所以我們將日誌服務寫為一箇中介軟體。

下面將以koa為例寫一個訪問日誌中介軟體

安裝log4js

npm install log4js
複製程式碼

log4js配置講解

log4js.configure({
  appenders: {
    visitor: {
      type: "dateFile", 
      filename: `./logs/visitor-`,
      pattern: ".yyyy-MM-dd.log",
      alwaysIncludePattern: true,
      daysToKeep: 30,
      layout: {
        type: "messagePassThrough"
      }
    }
  },
  categories: { default: { appenders: ["visitor"], level: "info" } }
});
複製程式碼

appenders.visitor我們做了一些個性化配置,為什麼要這樣做呢?

  • type: "dateFile":日誌檔案可以安特定的日期模式滾動,例如今天輸出為visitor-2019-03-08.log,明天輸為visitor-2019-03-09.log
  • filename: './logs/visitor.log':設定log輸出的檔案路勁和檔名
  • alwaysIncludePattern: true: 和上面同時使用 設定每天生成log名
  • daysToKeep: 30: 日誌只儲存30天 layout.type 我們設為messagePassThrough,不適用log4js提供的日誌模版,完全使用自己的程式碼,這樣做的好處是當我們的日誌要和阿里雲日誌關聯的時候必須要寫成JSON的,為了方便查詢以及可控性,我們要使用自己的定義的JSON。

完整程式碼

const log4js = require("log4js");
log4js.configure({
  appenders: {
    visitor: {
      type: "dateFile", 
      filename: `./logs/visitor.log`,
      alwaysIncludePattern: true,
      daysToKeep: 30,
      layout: {
        type: "messagePassThrough"
      }
    }
  },
  categories: { default: { appenders: ["visitor"], level: "info" } }
});
const logger = log4js.getLogger("visitor");

module.exports = function() {
  return async function(ctx, next) {
    const start = new Date();
    await next();
    // 根據檔案結尾篩選
    const index = ctx.url.lastIndexOf(".");
    const ext = ctx.url.substr(index + 1);
    const extArr = ["js", "png", "otf", "txt", "html", "xml", "json", "ico"]; 
    if (extArr.indexOf(ext) === -1 ) {
      const end = new Date();
      // 這裡是取nginx反向代理後的ip資訊, ctx.ip + "i"這個是給壞人準備的,如果ip結尾帶了i且不是你們公司的ip,那是有很大概率是壞人的。如果你們沒有使用nginx那就只取 ctx.ip。
      const Uip =
        ctx.get("HTTP_X_REAL_IP") ||
        ctx.get("X-Read-IP") ||
        ctx.get("HTTP_X_FORWARDED_FOR") ||
        ctx.get("X-Forwarded-For") ||
        ctx.get("Remote_Addr") ||
        ctx.ip + "i";
      let data = {
        startTime: start.toJSON(),
        endTime: end.toJSON(),
        uri: ctx.url,
        ip: Uip || "",
        status: ctx.status,
        referrer: ctx.headers.referer || "",
        msec: end - start,
        ua: ctx.header["user-agent"]
      };
      logger.info(JSON.stringify(data));
    }
  };
};

複製程式碼

相關文章