Nodejs使用winston進(jìn)行日志記錄詳解
在我們開發(fā)過程中,日志記錄是非常重要的一環(huán),它可以提供我們程序的運(yùn)行狀況、錯(cuò)誤和異常、性能和安全等方面的關(guān)鍵信息,讓開發(fā)人員和運(yùn)維團(tuán)隊(duì)更好地管理和維護(hù)應(yīng)用程序。
那么在NodeJS中該如何進(jìn)行日志記錄呢? 有小伙伴就會(huì)說console.log
! 確實(shí),Node.js中可以使用console.log
進(jìn)行簡單的日志記錄,但是它將信息輸出到控制臺(tái)就結(jié)束了,不會(huì)被持久化保存到文件或其他存儲(chǔ)設(shè)備中。所以通常只是在開發(fā)和調(diào)試階段使用一下。
在生產(chǎn)環(huán)境中,更常見的做法是使用專門的日志記錄庫,如winston
、log4js
等,來實(shí)現(xiàn)更靈活和可配置的日志記錄功能。本篇文章將介紹的是winston
的強(qiáng)大的日志記錄功能。下面我們就從一個(gè)簡單的node項(xiàng)目開始吧!
初始化項(xiàng)目
新建目錄執(zhí)行
npm init
初始化一個(gè) node 項(xiàng)目。
然后在 package.json 文件中新增type:module
字段,這樣我們就可以使用 ES6 語法了
{ "name": "winston", "version": "1.0.0", "description": "", "main": "index.js", "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
新建一個(gè)index.js
文件。ok,接下來我們就可以使用 winston 了
安裝使用 winston
執(zhí)行命令npm i winston -S
安裝winston
,安裝完成我們就可以在程序中導(dǎo)入使用了
比如在index.js
中我們可以使用 winston.createLogger 創(chuàng)建一個(gè)日志記錄器
import winston from "winston"; const { format, transports } = winston; const logger = winston.createLogger({ level: "debug", format: format.simple(), transports: [new transports.Console()], }); logger.info("cxkhtw");
然后我們執(zhí)行node index.js
就會(huì)看到控制臺(tái)打印了
info: cxkhtw
日志記錄器接受以下參數(shù):
名稱 | 默認(rèn)值 | 描述 |
---|---|---|
level | 'info' | 僅在 info.level 小于或等于此級(jí)別時(shí)記錄 |
levels | winston.config.npm.levels | 表示日志優(yōu)先級(jí)的級(jí)別(和顏色) |
format | winston.format.json | 用于 info 消息的格式化(參見:Formats) |
transports | [] | 日志傳傳輸方式 |
exitOnError | true | 如果為 false,則處理的異常不會(huì)導(dǎo)致進(jìn)程退出 |
exceptionHandlers | [] | 未捕獲異常處理方式 |
silent | false | 如果為 true,則所有日志都將被禁止 |
我們簡單看下上面常用的參數(shù)
level
它表示日志記錄的最低等級(jí),在 winston 中,日志級(jí)別遵循 RFC5424 指定的嚴(yán)重性順序:所有級(jí)別的嚴(yán)重性被規(guī)定為從最重要到最不重要的數(shù)字遞增。
const levels = { error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6, };
比如上面我們指定的 level 為 debug,那么 debug 及以上都會(huì)被記錄,下面的則不會(huì)被打印,比如我們加幾種打印類型
logger.info("cxkhtw"); logger.debug("cxkhtw"); logger.warn("cxkhtw"); logger.silly("cxkhtw");
執(zhí)行程序后會(huì)發(fā)現(xiàn)只記錄了前三個(gè)
format
format
可以規(guī)定日志的格式,默認(rèn)是format.json
也就是 JSON 格式,比如我們將format
去掉再執(zhí)行程序
const logger = winston.createLogger({ level: "debug", transports: [new transports.Console()], });
你會(huì)發(fā)現(xiàn)打印出來的變成 JSON 格式了
我們還可以使用format.combine
組合我們需要的格式
format: format.combine(format.timestamp(), format.simple()),
更多格式可以參見formats
transports
transports
可以理解為日志的傳輸方式,比如我們想傳輸?shù)娇刂婆_(tái),文件,數(shù)據(jù)庫,接口等等,都可以選擇對(duì)應(yīng)transports
,比如上面的new transports.Console()
就可以讓我們?cè)诳刂婆_(tái)看到打印的日志。
1. transports.File
如果我們想將日志記錄在文件中,可以使用new transports.File
進(jìn)行配置
const logger = winston.createLogger({ level: "debug", format: format.simple(), transports: [ new transports.Console(), new transports.File({ dirname: "logs", filename: "index.log", }), ], });
這時(shí)候再執(zhí)行程序你就會(huì)發(fā)現(xiàn)多了個(gè) logs/index.log 文件并且記錄了打印的日志
如果將所有日志都記錄在一個(gè)文件中,那這個(gè)文件豈不是越來越大? 不用擔(dān)心。winston
還給我們提供了日志分割的功能,只需要配置maxsize
屬性即可,單位是字節(jié),為了更好的演示這里我們?cè)O(shè)置 1024 字節(jié)也就是 1kb
const logger = winston.createLogger({ level: "debug", format: format.simple(), transports: [ new transports.Console(), new transports.File({ dirname: "logs", filename: "index.log", maxsize: 1024, }), ], });
然后多執(zhí)行幾次就會(huì)發(fā)現(xiàn)日志文件新增了一個(gè),并且第一個(gè)日志文件大小剛好 1kb 左右
一般來說我們進(jìn)行日志分割都是根據(jù)時(shí)間來分割的,這樣方便后期排查問題,那么winston
支持按時(shí)間分割嗎? 答案是肯定的
2. transports.DailyRotateFile
如果想根據(jù)時(shí)間分割日志,我們需要換別的 Transport ,winston
提供了很多transport,感興趣的可以點(diǎn)進(jìn)去看下。我們這里使用DailyRotateFile
來分割日志
我們首先要安裝npm install winston-daily-rotate-file -S
,然后導(dǎo)入就可以使用了
import winston from "winston"; import "winston-daily-rotate-file"; const { format, transports } = winston; const logger = winston.createLogger({ level: "debug", format: format.simple(), transports: [ new transports.Console(), new transports.DailyRotateFile({ level: "debug", dirname: "logs", filename: "index-%DATE%.log", datePattern: "YYYY-MM-DD-HH-mm", maxSize: 1024, }), ], }); logger.info("cxkhtw"); logger.debug("cxkhtw"); logger.warn("cxkhtw"); logger.info("cxkhtw");
這時(shí)候每分鐘的日志都會(huì)被記錄在不同的文件中了,當(dāng)然你可以設(shè)置datePattern來規(guī)定這個(gè)時(shí)間
3. transports.Http
有的時(shí)候我們想將日志上報(bào)到指定接口中進(jìn)行記錄 winston 也是支持的,可以使用內(nèi)置的 transport.Http 進(jìn)行配置,為了更好的演示,我們用express
寫一個(gè)簡單的接口,安裝express
后新建一個(gè) server.js
import express from "express"; import bodyParser from "body-parser"; const app = express(); const port = 3000; app.use(bodyParser.json()); // 定義一個(gè) POST請(qǐng)求的路由 app.post("/", (req, res) => { console.log(req.body); res.send("Hello, World!"); }); // 啟動(dòng)服務(wù)器 app.listen(port, () => { console.log(`Server is running on port ${port}`); });
注意這里還需要安裝body-parser
讓我們的接口可以接收 JSON 文件,然后新建一個(gè)終端執(zhí)行node server.js
啟動(dòng)一個(gè)端口為 3000 的接口
在我們程序中的transports添加一個(gè)transports.Http
,并傳入一些配置參數(shù)
import winston from "winston"; import "winston-daily-rotate-file"; const { format, transports } = winston; const logger = winston.createLogger({ level: "debug", format: format.simple(), transports: [ new transports.Console(), new transports.Http({ level: "info", host: "localhost", port: 3000, path: "/", }), ], }); logger.info("cxkhtw"); logger.debug("cxkhtw"); logger.warn("cxkhtw"); logger.info("cxkhtw");
然后執(zhí)行一下,可以發(fā)現(xiàn)我們接口中拿到了日志信息,后面可以根據(jù)自己的需求將這些信息存儲(chǔ)下來
winston的transport還有很多,由于篇幅有限這里先只介紹這幾個(gè)常用的,感興趣的可以自己查看
exceptionHandlers
除了上述功能外,winston 還可以配置處理未捕獲異常,如下
import winston from "winston"; import "winston-daily-rotate-file"; const { format, transports } = winston; const logger = winston.createLogger({ level: "debug", format: format.simple(), transports: [new transports.Console()], exceptionHandlers: [ new transports.File({ dirname: "errorlogs", filename: "error.log", }), ], }); throw Error("這是一條錯(cuò)誤信息");
運(yùn)行就會(huì)發(fā)現(xiàn)多了一個(gè)errorlogs/error.log
文件
總結(jié)
本篇文章介紹 winston 一些常見用法,包括 level 的優(yōu)先級(jí)、日志打印的格式format
以及一些transport
的使用等等。
其中,重點(diǎn)介紹了transport
的用法,通過transport
實(shí)現(xiàn)了生成日志文件,日志分割,日志上傳接口等常見日志處理功能。
到此這篇關(guān)于Nodejs使用winston進(jìn)行日志記錄詳解的文章就介紹到這了,更多相關(guān)Nodejs winston內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
nodejs+express最簡易的連接數(shù)據(jù)庫的方法
這篇文章主要介紹了nodejs+express 最簡易的連接數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12nodejs不用electron實(shí)現(xiàn)打開文件資源管理器并選擇文件
最近在開發(fā)一些小腳本,用 nodejs 實(shí)現(xiàn),其中很多功能需要選擇一個(gè)/多個(gè)文件,或者是選擇一個(gè)文件夾,這種情況下網(wǎng)上給出的解決方案都是 electron,但是我一個(gè)小腳本用 electron 屬實(shí)有點(diǎn)夸張了,后來轉(zhuǎn)念一想可以通過 powershell 來實(shí)現(xiàn)類似的功能,需要的朋友可以參考下2024-01-01從零開始學(xué)習(xí)Node.js系列教程二:文本提交與顯示方法
這篇文章主要介紹了Node.js文本提交與顯示方法,結(jié)合實(shí)例形式分析了nodejs基于http的文本提交、傳輸與顯示相關(guān)操作技巧,需要的朋友可以參考下2017-04-04node.js同步/異步文件讀寫-fs,Stream文件流操作實(shí)例詳解
這篇文章主要介紹了node.js同步/異步文件讀寫-fs,Stream文件流操作,結(jié)合實(shí)例形式詳細(xì)分析了node.js針對(duì)文件的同步/異步讀寫與文件流相關(guān)操作技巧,需要的朋友可以參考下2023-06-06詳解Nodejs get獲取遠(yuǎn)程服務(wù)器接口數(shù)據(jù)
這篇文章主要介紹了Nodejs get獲取遠(yuǎn)程服務(wù)器接口數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03