你怎麼能解決這個問題?也許通過回到代碼并檢查每一行代碼是否按預期運作。這對于小型應用程式來說更容易,但即便如此,嘗試觸發與使用者相同類型的錯誤也可能很困難。想象一下,這在大型應用程式中會有多難。
假設有一個執行個體,應用程式收集一些使用者的資訊并将它們儲存到資料庫中。
如果應用程式失敗,伺服器将向最終使用者傳回系統錯誤。最好能捕獲這些執行個體并解決這些錯誤。在這種情況下,您如何知道使用者 a 或使用者 b 遇到了單個系統錯誤?這些錯誤可能由代碼中的錯誤、損壞的檔案、錯誤的邏輯或資料類型不比對觸發。
如果你需要避免這種挫折,你就無法避免日志記錄。日志是程式員首先要查找的地方,用于跟蹤錯誤和事件流,尤其是來自伺服器的事件。日志會告訴您當應用程式運作并與使用者互動時會發生什麼。日志記錄的一個很好的用例是,例如,如果您的系統中有一個錯誤,并且您想了解導緻其發生的步驟。
日志記錄是将應用程式活動生成的資訊記錄到日志檔案中的過程。儲存在日志檔案中的消息稱為日志。日志是記錄在日志檔案中的單個執行個體。
在 Node.js 中建構應用程式日志至關重要。在本地運作應用程式時,可以将其挂接到調試器上,非常棒,可以在運作應用程式時發現問題。在開發過程中,您通常會使用 console.log 來擷取應用程式日志。
但是當一個應用程式投入生産并且使用者開始與之互動時,你就不能再使用 console.log 了。如果出現問題并且應用程式崩潰,則無法使用控制台進行檢查。如果你有一個簡潔、幹淨和高品質的日志中間件,比如 Winston,那會很有幫助。
Winston 處理您的應用程式活動并将有用的資訊生成到日志檔案或資料庫中。之後,您可以檢查應用程式生成的所有活動。
本指南将在 Winston 的上下文中解釋日志記錄。
了解生産應用程式是否出現問題的唯一方法是建立日志。 記錄重新建立并為您儲存該問題。 如果出現問題或出現問題,日志會告訴您。
了解系統的行為方式。 日志記錄将生成有關系統如何與使用者互動以及進出系統的資訊。
跟蹤您的系統活動。 日志可以顯示執行個體發生的時間以及觸發日志的原因。
通常,日志記錄的臨界值是:
錯誤跟蹤
調試
應用性能
選擇 winston 的收益
Winston 是最好的日志中間件之一,每周下載下傳量約為 4,000,000 次。以下屬性使 Winston 成為整體通用的日志記錄中間件。
它使用簡單且可配置。
日志級别(優先級)。 Winston 提供日志記錄級别。它們表示日志優先級;這使您能夠從需要較少關注的日志中整理出關鍵日志。例如:{錯誤:0,警告:1,資訊:2,詳細:3,調試:4,傻:5}。在這種情況下,錯誤日志的優先級高于詳細日志。
記錄通道(傳輸)。一個好的記錄器有不同的方式來選擇你的日志輸出目的地。使用 Winston,您可以以不同方式發送和儲存日志,例如檔案、資料庫、電子郵件和控制台。
日志格式。 Winston 為您提供了多種日志格式。例如,在将日志儲存到 Mongo 資料庫時,日志格式需要為 JSON 格式。
日志分析。 Winston 可幫助您分析代碼塊并測量成功執行代碼所需的時間。
Winston transporters
Winston 的特性之一是它支援各種傳輸,例如檔案傳輸。 這會将生成的日志消息儲存到日志檔案中。 該檔案是在您的系統中指定的。 如果應用程式建立了它的第一個日志執行個體,該檔案将自動生成。 之後,任何日志都将儲存到建立的檔案中。
為此,記錄器配置對象需要指向一個檔案(檔案傳輸器)。 隻需将新 winston.transports.File 中的傳輸配置對象 .transports.Console() 替換為 .transports.File() 即可,如下所示。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iY5gTOhhzNhNWO0YjZxEmYwIjM0E2YlF2YjRmZykTM08CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
const logConfiguration = {
transports: [
new winston.transports.Console({
level: 'warn'
}),
new winston.transports.File({
level: 'error',
// Create the log directory if it does not exist
filename: 'logs/example.log'
})
]
};
const logger = winston.createLogger(logConfiguration);
// Log some messages
logger.error("Hello, Winston logger, the first error!");
logger.warn("Hello, Winston logger, the first warning!");
logger.warn("Hello, Winston logger, the second warning!");
logger.error("Hello, Winston logger, the second error!");
logger.info("Hello, Winston logger, some info!");
logger.debug("Hello, Winston logger, a debug!");
這規定:
日志将顯示在控制台輸出中。
隻有屬于錯誤級别的日志才會記錄在 example.log 檔案中。
使用 Winston,您可以指定儲存日志的預設格式。
例如,假設我們想以 JSON 格式登入,我們可以使用 Winston.format 指定,并且日志執行個體将以 JSON 格式儲存。
format: winston.format(
)
該格式采用其他日志表單屬性,例如
ms() - 自記錄上次日志以來的時間(以毫秒為機關)。
label() - 向記錄的消息添加标簽。
timestamp() - 收到日志消息的時間戳。
splat() - 提供字元串插值。
要将其應用到您的日志中,您需要使用 format.combine,如下例所示。
const express = require('express');
// Require logger.js
const logger = require('./utils/logger');
const app = express();
const port = 3000;
const host = "localhost";
// Dummy Express GET call
app.get('/',(req,res) => {
res.send("Hello World!");
logger.info("Server Sent A Hello World!");
})
// Introduce error by using undefined variable 'y'
app.get('/calc',(req,res) => {
const x = y + 10;
res.send(x.toString());
})
// Capture 500 errors
app.use((err,req,res,next) => {
res.status(500).send('Could not perform the calculation!');
logger.error(`${err.status || 500} - ${res.statusMessage} - ${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
})
// Capture 404 erors
app.use((req,res,next) => {
res.status(404).send("PAGE NOT FOUND");
logger.error(`400 || ${res.statusMessage} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
})
// Run the server
app.listen(port, () => {
console.log("Server started...");
logger.info(`Server started and running on http://${host}:${port}`)
})
每次伺服器啟動時,Winston 都會将日志記錄到 server.log 檔案中。
伺服器運作時,通路以下頁面會在每次調用連結時建立日志。
http://localhost:3000/ - 伺服器将發送一條 hello world 消息。 我們希望 Winston 捕獲它并将其記錄在我們的日志檔案中。
http://localhost:3000/calc - 我們試圖将變量 y 添加到變量 x。 在這種情況下,未定義變量 y。 這将産生一個錯誤,我們希望 Winston 為我們捕獲這個執行個體。
http://localhost:3000/hello - 我們建立的伺服器沒有這樣的 URL。 我們希望 Winston 在指向我們 IP 位址的連結被通路但無法找到時通知我們; 那是 404 錯誤。
output:
info: Nov-12-2020 10:07:59: Server started and running on http://localhost:3000
info: Nov-12-2020 10:08:02: Server Sent A Hello World!
error: Nov-12-2020 10:08:05: 500 - Internal Server Error - y is not defined - /calc - GET - ::1
error: Nov-12-2020 10:08:10: 400 || Not Found - /hello - GET - ::1