NodeJS 中的日誌記錄

Isaac Tony 2023年10月12日
  1. 在 NodeJS 中使用 Logging 建立和儲存日誌
  2. 在 NodeJS 中使用 console.log() 跟蹤程式執行
  3. まとめ
NodeJS 中的日誌記錄

Logging 是記錄應用程式流程和行為的過程。Logging 應該在生產模式下執行到更持久的輸出流。

除了幫助應用程式開發之外,記錄是除錯複雜應用程式的一個重要方面。

此外,日誌提供了重要資訊,可用作審計跟蹤以監控系統行為並更快地診斷問題。

在 NodeJS 中使用 Logging 建立和儲存日誌

在生產環境中,正確儲存的日誌檔案也可以用作分析的資料來源,並簡化新功能的開發過程。

並非應監控應用程式的所有方面。決定記錄哪些資訊是記錄過程的重要部分。

某些無法記錄的資料型別包括個人資料,例如使用者名稱信用卡號密碼

在 Node js 和大多數程式語言中,各種日誌級別可以告知要記錄什麼樣的資料。它們包括:

  • 警告
  • 錯誤
  • 資訊
  • 除錯
  • 詳細

在 NodeJS 中使用 console.log() 跟蹤程式執行

我們可以使用各種方法在 Node js 中建立和管理日誌檔案。

console.log() 函式是最基本的方法之一,也許是開發階段使用最多的方法。其他類似的方法包括 console.err()console.warn()

console.log()console.err() 方法允許我們將訊息記錄到標準輸出 stdout 和標準錯誤 stderr

在下面的示例中,我們使用 console.log() 來跟蹤程式執行。

ages = [34, 33, 37, 29, 12, 10, 42, 44];

function check_ages(item) {
  if (item < 40) {
    console.info(`Age "${item}" is within the required range!`);
  } else {
    console.error(`Age "${item}" is out of the required range!`);
  }
}
for (const age of ages) {
  check_ages(age);
}

輸出:

Age "34" is within the required range!
Age "33" is within the required range!
Age "37" is within the required range!
Age "29" is within the required range!
Age "12" is within the required range!
Age "10" is within the required range!
Age "42" is out of the required range!
Age "44" is out of the required range!

現在,雖然使用 console.log() 編寫日誌訊息非常簡單,但無法將這種方法用於部署到生產環境的應用程式,因為在這個階段,你無法訪問控制檯。

此外,這些方法並不表示任何錯誤的嚴重性或緊迫性,因此在構建更強大的應用程式時並不可靠。

假設我們想將這些日誌儲存在某個檔案中以供進一步參考。為此,我們需要將 stdoutstderr 重定向到一個具有 .log 副檔名的檔案,該檔案將儲存這些日誌,如下所示。

node index.js > log_info.log

輸出:

Age "34" is within the required range!
Age "33" is within the required range!
Age "37" is within the required range!
Age "29" is within the required range!
Age "12" is within the required range!
Age "10" is within the required range!
Age "42" is out of the required range!
Age "44" is out of the required range!
Age "42" is out of the required range!
Age "44" is out of the required range!

使用此處顯示的命令將 stderrstdout 日誌儲存在不同的檔案中。

node index.js > stdout_main.log 2 > stderr_main.log

這將自動建立包含各自日誌的 stdout_main.logstderr_main.log 檔案,如下所示。

Age "34" is within the required range!
Age "33" is within the required range!
Age "37" is within the required range!
Age "29" is within the required range!
Age "12" is within the required range!
Age "10" is within the required range!
node : Age "42" is out of the required range!
At line:1 char:1
+ node index.js > stdout_main.log 2> stderr_main.log
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Age "42" is out of the required range!:Strin
   g) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Age "44" is out of the required range!

雖然這種方法適合生產環境中的開發階段需求,但我們需要一個更靈活的庫來支援所有日誌記錄級別並允許我們格式化和集中日誌。

Winston 平均每週有 9,686,809 次下載,是 Node js 開發人員最喜歡的簡單通用日誌庫。

它易於配置,同時支援不同的日誌格式,提供不同的日誌通道,也稱為傳輸,還允許我們為日誌級別分配不同的優先順序。

當我們想要儲存或共享我們的日誌檔案時,我們可以使用 Winston 支援的傳輸包括:儲存到檔案、電子郵件、資料庫和控制檯。

要開始使用 Winston,我們首先需要建立並初始化一個 Node js 應用程式。我們可以使用 npm 包管理器使用以下命令安裝 Winston 包。

npm install Winston.

然後我們可以在我們的程式中要求這個包來訪問它的功能,如下所示。

const winston = require('winston');

最推薦的使用 Winston 的方法是使用 Winston.createLogger() 方法建立我們的記錄器。

由於我們還需要指定傳輸、級別和格式等配置,我們可以在記錄器中建立一個單獨的配置物件。

const winston = require('winston');

const logger = winston.createLogger({

  transports: [new winston.transports.Console()

  ],

});

一旦配置到位,我們現在可以登出訊息。在這種情況下,我們的傳輸是控制檯;因此,我們的訊息將顯示在控制檯中。

const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [new winston.transports.Console()

  ],

});

logger.log({

  message: 'This is a message with Info log level !',

  level: 'info'
});

輸出:

{"level":"info","message":"This is a message with Info log level !"}

或者,我們可以建立一個單獨的配置物件並將物件的名稱傳遞給記錄器,如下所示。

const winston = require('winston');

const logConfigs = {
  level: 'info',
  format: winston.format.json(),
  transports: [

    new winston.transports.Console()

  ],

}

const logger = winston.createLogger(logConfigs);

logger.log({

  message: 'This is a message with Info log level !',

  level: 'info'
});

我們還可以將日誌檔案儲存到不同的傳輸中。在這種情況下,我們希望將日誌儲存在外部資料夾中的檔案中。

為此,我們需要更改配置物件下的傳輸,而不是新的 Winston.transports.Console() 具有新的 Winston.transports.File 並指定指示如何儲存日誌檔案的位置。

這是一個圖示。

const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  'transports': [new winston.transports.File({filename: 'logs/files.log'})],

});

logger.log({

  message: 'This is a message with Info log level !',

  level: 'info'
});

由於配置物件下 Winstone 包的靈活性,我們可以同時指定多種傳輸形式。

例如,我們可以指定所有日誌都顯示在控制檯中。同時,其他日誌級別(例如錯誤級別)的日誌專門針對外部檔案或資料庫。

const winston = require('winston');
const logConfigs = {
  transports: [
    new winston.transports.Console({level: 'warn'}),
    new winston.transports.File({
      level: 'error',
      // Create the log directory if it does not exist
      filename: 'logs/files.log'
    })
  ]
};
const logger = winston.createLogger(logConfigs);

logger.log({

  message: 'This is a message with warn log level !',

  level: 'warn'
});
logger.log({

  message: 'This is a message with error log level !',

  level: 'error'
});

輸出:

{"level":"warn","message":"This is a message with warn log level !"}
{"level":"error","message":"This is a message with error log level !"}

まとめ

Winston 包不限於我們上面討論過的傳輸介質。我們還可以將日誌儲存在伺服器的資料庫中或通過電子郵件共享。

還值得注意的是,Node js 中還有其他儲存和管理日誌的方式,例如使用中介軟體軟體,如 BunyanLog4jsMorgan

然而,Winston 包脫穎而出,因為它易於配置和靈活。

作者: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.

LinkedIn