前言
因?yàn)榕驼嬲\(chéng),有更多的客戶和我們聚集在一起,為了共同目標(biāo),成都創(chuàng)新互聯(lián)在工作上密切配合,從創(chuàng)業(yè)型企業(yè)到如今不斷成長(zhǎng),要感謝客戶對(duì)我們的高要求,讓我們敢于面對(duì)挑戰(zhàn),才有今天的進(jìn)步與發(fā)展。從網(wǎng)站到重慶小程序開(kāi)發(fā)公司,軟件開(kāi)發(fā),app軟件開(kāi)發(fā),10年企業(yè)網(wǎng)站建設(shè)服務(wù)經(jīng)驗(yàn),為企業(yè)提供網(wǎng)站設(shè)計(jì),網(wǎng)站托管、服務(wù)器租用一條龍服務(wù).為企業(yè)提供成都全網(wǎng)營(yíng)銷推廣,按需定制開(kāi)發(fā),原創(chuàng)設(shè)計(jì),10年品質(zhì),值得您的信賴.
這次編寫Node.js項(xiàng)目的時(shí)候用到了日志模塊,其中碰到了一個(gè)小問(wèn)題。
這是一個(gè)定時(shí)執(zhí)行可配置自動(dòng)化任務(wù)的項(xiàng)目,所以輸出信息會(huì)不斷增加,也就意味著日志文件會(huì)隨時(shí)間不斷增大。如果對(duì)日志文件大小不加以控制,那么服務(wù)器的磁盤遲早會(huì)被撐滿。所以限制文件大小是有必要的。
最理想的控制方式就是當(dāng)文件大小超過(guò)限制時(shí),清除最先記錄的數(shù)據(jù)。類似一個(gè)FIFO的隊(duì)列。
# 刪除前面的數(shù)據(jù) - 1 xxx ...... 100 abc # 文件末尾追加數(shù)據(jù) + 101 xxxx
log4js的file rolling
一提到記錄日志很多Node.js開(kāi)發(fā)者肯定會(huì)找到log4js,先來(lái)看看log4js是怎么處理這個(gè)問(wèn)題的。
log4js分為很多appenders(可以理解為記錄日志的媒介),file rolling功能可以通過(guò)函數(shù)來(lái)進(jìn)行配置。
file rolling功能有兩種方式:日期和文件大小。
要控制文件大小,當(dāng)然選擇后者。
為了測(cè)試這個(gè)功能是否滿足我們要求,寫一段循環(huán)代碼來(lái)寫日志。
const log4js = require('log4js') // 配置log4js log4js.configure({ appenders: { everything: { type: 'file', filename: 'a.log', maxLogSize: 1000, backups: 0 }, }, categories: { default: { appenders: ['everything'], level: 'debug' } } }); const log = log4js.getLogger(); for (let i = 0; i < 41; i++) { const str = i.toString().padStart(6, '000000'); log.debug(str); }
執(zhí)行之后生成兩個(gè)文件a.log和a.log.1。
其中a.log.1有20行數(shù)據(jù),實(shí)際大小1kb,a.log只有1行數(shù)據(jù)。
雖然確實(shí)控制了文件大小,但是會(huì)帶來(lái)兩個(gè)問(wèn)題:
推測(cè)log4js的實(shí)現(xiàn)邏輯可能是下面這樣:
這顯然不能完全滿足需求。
字符串替換?
如果要在內(nèi)存中完成循環(huán)覆寫操作就比較簡(jiǎn)單了,使用字符串或Buffer的即可完成。
但是有一個(gè)很大的問(wèn)題:占用內(nèi)存。
比如限制文件大小為1GB,有10個(gè)日志文件同時(shí)寫入,那么至少占用10GB內(nèi)存空間!
內(nèi)存可是比磁盤空間更寶貴的,如此明顯的性能問(wèn)題,顯然也不是最優(yōu)解決方式。
file roll
按照需求可以把實(shí)現(xiàn)步驟拆成兩步:
這兩步不分先后順序,但是Node.js沒(méi)有提供API來(lái)刪除文件開(kāi)頭部分,只提供了修改文件指定位置的函數(shù)。
既然無(wú)法刪除文件開(kāi)頭部分內(nèi)容,那么我們就換個(gè)思路,只保留文件末尾部分內(nèi)容(不超出大小限制)。
什么?這不是一個(gè)意思么?
略有區(qū)別~
刪除是在原有文件上進(jìn)行的操作,而保留內(nèi)容可以借助臨時(shí)文件來(lái)進(jìn)行操作。
所以思路變成:
這樣就不會(huì)出現(xiàn)像log4js一樣日志文件內(nèi)容不全的現(xiàn)象,也不會(huì)保留額外的臨時(shí)文件。但是對(duì)IO的操作會(huì)增加~
對(duì)于寫操作可以采取tail命令來(lái)實(shí)現(xiàn),最終實(shí)現(xiàn)代碼如下:
private write(name: string, buf?: Buffer | string) { // append buf to tmp file const tmpName = name.replace(/(.*\/)(.*$)/, '$1_\.$2\.tmp'); if (!existsSync(tmpName)) { copyFileSync(name, tmpName); } buf && appendFileSync(tmpName, buf); // if busy, wait if (this.stream && this.stream.readable) { this.needUpdateLogFile[name] = true; } else { try { execSync(`tail -c ${limit} ${tmpName} > ${name}`); try { if (this.needUpdateLogFile[name]) { this.needUpdateLogFile[name] = false; this.write(name); } else { existsSync(tmpName) && unlinkSync(tmpName); } } catch (e) { console.error(e); } } catch (e) { console.error(e); } } }
總結(jié)
完成這個(gè)功能有兩點(diǎn)感悟:
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)創(chuàng)新互聯(lián)的支持。
本文名稱:利用Node.js如何實(shí)現(xiàn)文件循環(huán)覆寫
文章鏈接:http://muchs.cn/article18/ghiedp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、動(dòng)態(tài)網(wǎng)站、標(biāo)簽優(yōu)化、自適應(yīng)網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)公司、服務(wù)器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)