中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

Nodejs監(jiān)聽(tīng)日志文件的變化的過(guò)程解析

最近有在做日志文件的分析,其中有一個(gè)需求:A服務(wù)器項(xiàng)目需要用Nodejs監(jiān)聽(tīng)日志文件的變化,當(dāng)項(xiàng)目產(chǎn)生了新的日志信息,將新的部分通過(guò)socket傳輸?shù)紹服務(wù)器項(xiàng)目。socket暫時(shí)不做分析。

創(chuàng)新互聯(lián)自2013年創(chuàng)立以來(lái),先為沙河等服務(wù)建站,沙河等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為沙河企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

這個(gè)需求很簡(jiǎn)單,通過(guò)分析我們開(kāi)始擼碼吧。 在擼碼的過(guò)程中還能鞏固所學(xué)Nodejs的API,何樂(lè)而不為呢?

所用的API

fs.watchFile()

語(yǔ)法

fs.watchFile(filename[, options], listener)

參數(shù)解析

filename <string> | <Buffer> | <URL> ——文件名
options <Object>

 persistent <boolean> 默認(rèn)值: true?!欠駪?yīng)該繼續(xù)運(yùn)行
 interval <integer> 默認(rèn)值: 5007?!喸兡繕?biāo)的頻率
listener <Function>

 current <fs.Stats> ——當(dāng)前值
 previous <fs.Stats> ——之前值

監(jiān)視 filename 的更改。 每當(dāng)訪問(wèn)文件時(shí)都會(huì)調(diào)用 listener 回調(diào)。

listener 有兩個(gè)參數(shù),當(dāng)前的 stat 對(duì)象和之前的 stat 對(duì)象

這些 stat 對(duì)象是 fs.Stat 的實(shí)例。

要在修改文件(而不僅僅是訪問(wèn))時(shí)收到通知,則需要比較 curr.mtime 和 prev.mtime。

當(dāng) fs.watchFile 操作導(dǎo)致 ENOENT 錯(cuò)誤時(shí),它將調(diào)用一次監(jiān)聽(tīng)器,并將所有字段置零(或?qū)⑷掌谠O(shè)為 Unix 紀(jì)元)。 如果文件是在那之后創(chuàng)建的,則監(jiān)聽(tīng)器會(huì)被再次調(diào)用,且?guī)献钚碌?stat 對(duì)象。 這是 v0.10 之后的功能變化。

使用 fs.watch() 比 fs.watchFile fs.unwatchFile 更高效。 應(yīng)盡可能使用 fs.watch 代替 fs.watchFile 和 fs.unwatchFile。

當(dāng) fs.watchFile() 正在監(jiān)視的文件消失并重新出現(xiàn)時(shí),第二次回調(diào)事件(文件重新出現(xiàn))返回的 previousStat 會(huì)與第一次回調(diào)事件(文件消失)返回的 previousStat 相同。

這種情況發(fā)生在:

  • 文件被刪除,然后又恢復(fù)。
  • 文件被重命名兩次,且第二次重命名回其原來(lái)的名稱。

例子

fs.watchFile('message.text', (curr, prev) => {
 console.log(`當(dāng)前的最近修改時(shí)間是: ${curr.mtime}`);
 console.log(`之前的最近修改時(shí)間是: ${prev.mtime}`);
});

fs.open()

語(yǔ)法

fs.open(path[, flags[, mode]], callback)

參數(shù)解析

path <string> | <Buffer> | <URL> ——文件路徑
flags <string> | <number> 默認(rèn)值: 'r'?!募到y(tǒng)標(biāo)志
mode <integer> 默認(rèn)值: 0o666(可讀寫)?!O(shè)置文件模式(權(quán)限和粘滯位),但僅限于創(chuàng)建文件的情況
callback <Function>

 err <Error> ——錯(cuò)誤
 fd <integer>——文件系統(tǒng)流

fs.read()

語(yǔ)法

fs.read(fd, buffer, offset, length, position, callback)

參數(shù)解析

fd <integer> ——文件系統(tǒng)流
buffer <Buffer> | <TypedArray> | <DataView>——數(shù)據(jù)將寫入的緩沖區(qū)
offset <integer>—— buffer 中開(kāi)始寫入的偏移量
length <integer>——要讀取的字節(jié)數(shù)
position <integer>——從文件中開(kāi)始讀取的位置
callback <Function>

 err <Error>
 bytesRead <integer>
 buffer <Buffer>

fs.createReadStream()

語(yǔ)法

fs.createReadStream(path[, options])

參數(shù)解析

path <string> | <Buffer> | <URL>——文件路徑
options <string> | <Object>

 flags <string> 默認(rèn)值: 'r'?!募到y(tǒng)標(biāo)志
 encoding <string> 默認(rèn)值: null?!址幋a
 fd <integer> 默認(rèn)值: null?!募到y(tǒng)流
 mode <integer> 默認(rèn)值: 0o666?!O(shè)置文件模式(權(quán)限和粘滯位),但僅限于創(chuàng)建文件的情況
 autoClose <boolean> 默認(rèn)值: true?!欠褡詣?dòng)關(guān)閉文件描述符
 start <integer>——文件讀取的開(kāi)始位置
 end <integer> 默認(rèn)值: Infinity?!募x取的結(jié)束位置
 highWaterMark <integer> 默認(rèn)值: 64 * 1024。

返回: <fs.ReadStream> 參閱可讀流。

如果 autoClose 為 false,則即使出現(xiàn)錯(cuò)誤,也不會(huì)關(guān)閉文件描述符。 應(yīng)用程序負(fù)責(zé)關(guān)閉它并確保沒(méi)有文件描述符泄漏。 如果 autoClose 設(shè)為 true(默認(rèn)行為),則在 'error' 或 'end' 事件時(shí)將自動(dòng)關(guān)閉文件描述符。

mode 用于設(shè)置文件模式(權(quán)限和粘滯位),但僅限于創(chuàng)建文件的情況。

例子

讀取sample.txt文件的10個(gè)字符

fs.createReadStream('sample.txt', { start: 90, end: 99 });

readLine.createInterface

語(yǔ)法

readline.createInterface(options)

參數(shù)解析

options <Object>

  input <stream.Readable> 要監(jiān)聽(tīng)的可讀流。此選項(xiàng)是必需的。
  output <stream.Writable> 將逐行讀取數(shù)據(jù)寫入的可寫流。
  completer <Function> 用于 Tab 自動(dòng)補(bǔ)全的可選函數(shù)。
  terminal <boolean> 如果 input 和 output 應(yīng)該被視為 TTY,并且寫入 ANSI/VT100 轉(zhuǎn)義碼,則為 true。 默認(rèn)值: 實(shí)例化時(shí)在 output 流上檢查 isTTY。
  historySize <number> 保留的最大歷史記錄行數(shù)。 要禁用歷史記錄,請(qǐng)將此值設(shè)置為 0。 僅當(dāng)用戶或內(nèi)部 output 檢查將 terminal 設(shè)置為 true 時(shí),此選項(xiàng)才有意義,否則根本不會(huì)初始化歷史記錄緩存機(jī)制。 默認(rèn)值: 30。
  prompt - 要使用的提示字符串。默認(rèn)值: '> '。
  crlfDelay <number> 如果 \r 與 \n 之間的延遲超過(guò) crlfDelay 毫秒,則 \r 和 \n 將被視為單獨(dú)的行尾輸入。  crlfDelay 將被強(qiáng)制轉(zhuǎn)換為不小于 100 的數(shù)字。 可以設(shè)置為 Infinity, 這種情況下, \r 后跟 \n 將始終被視為單個(gè)換行符(對(duì)于使用 \r\n 行分隔符的文件讀取可能是合理的)。 默認(rèn)值: 100。
  removeHistoryDuplicates <boolean> 如果為 true, 則當(dāng)添加到歷史列表的新輸入行與舊的輸入行重復(fù)時(shí),將從列表中刪除舊行。 默認(rèn)值: false。
  escapeCodeTimeout <number> readline 將會(huì)等待一個(gè)字符的持續(xù)時(shí)間(當(dāng)以毫秒為單位讀取模糊鍵序列時(shí),可以使用輸入讀取到目前為止形成完整的鍵序列,并且可以采取額外的輸入來(lái)完成更長(zhǎng)的鍵序列)。 默認(rèn)值: 500。

文件系統(tǒng)標(biāo)志

這個(gè)不需要司機(jī),記住常見(jiàn)的即可,需要的時(shí)候查找。

當(dāng) flag 選項(xiàng)采用字符串時(shí),可用以下標(biāo)志:

'a' - 打開(kāi)文件用于追加。如果文件不存在,則創(chuàng)建該文件。

'ax' - 與 'a' 相似,但如果路徑已存在則失敗。

'a+' - 打開(kāi)文件用于讀取和追加。如果文件不存在,則創(chuàng)建該文件。

'ax+' - 與 'a+' 相似,但如果路徑已存在則失敗。

'as' - 以同步模式打開(kāi)文件用于追加。如果文件不存在,則創(chuàng)建該文件。

'as+' - 以同步模式打開(kāi)文件用于讀取和追加。如果文件不存在,則創(chuàng)建該文件。

'r' - 打開(kāi)文件用于讀取。如果文件不存在,則出現(xiàn)異常。

'r+' - 打開(kāi)文件用于讀取和寫入。如果文件不存在,則出現(xiàn)異常。

'rs+' - 以同步模式打開(kāi)文件用于讀取和寫入。指示操作系統(tǒng)繞過(guò)本地的文件系統(tǒng)緩存。

這對(duì)于在 NFS 掛載上打開(kāi)文件時(shí)非常有用,因?yàn)樗试S跳過(guò)可能過(guò)時(shí)的本地緩存。 它對(duì) I/O 性能有非常實(shí)際的影響,因此除非需要,否則不建議使用此標(biāo)志。

這不會(huì)將 fs.open() 或 fsPromises.open() 轉(zhuǎn)換為同步的阻塞調(diào)用。 如果需要同步的操作,則應(yīng)使用 fs.openSync() 之類的。

'w' - 打開(kāi)文件用于寫入。如果文件不存在則創(chuàng)建文件,如果文件已存在則截?cái)辔募?/p>

'wx' - 與 'w' 相似,但如果路徑已存在則失敗。

'w+' - 打開(kāi)文件用于讀取和寫入。如果文件不存在則創(chuàng)建文件,如果文件已存在則截?cái)辔募?/p>

'wx+' - 與 'w+' 相似,但如果路徑已存在則失敗。

fs.Stats 類

fs.Stats 對(duì)象提供有關(guān)文件的信息。

Stats {
 dev: 2114,
 ino: 48064969,
 mode: 33188,
 nlink: 1,
 uid: 85,
 gid: 100,
 rdev: 0,
 size: 527,
 blksize: 4096,
 blocks: 8,
 atimeMs: 1318289051000.1,
 mtimeMs: 1318289051000.1,
 ctimeMs: 1318289051000.1,
 birthtimeMs: 1318289051000.1,
 atime: Mon, 10 Oct 2011 23:24:11 GMT,
mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

 開(kāi)始監(jiān)聽(tīng)日志文件

前提,在app.js中調(diào)用watchFile方法,將需要監(jiān)聽(tīng)的文件路徑傳入該方法中。

function watchFile(filename) {
 console.log('Log monitoring...');
 // Open the file for reading and appending
 fs.open(filename, 'a+', function (err, fd) {
 if (err) {
  throw err;
 }
 var buffer;
 fs.watchFile(filename, {
  persistent: true,
  interval: 1000
 }, (curr, prev) => {
  // Compare the time before and after
  if (curr.mtime > prev.mtime) {
  // console.log(`The current latest revision time is: ${curr.mtime}`);
  // console.log(`The latest modification time is: ${prev.mtime}`);

  // Changes in the contents of documents
  buffer = new Buffer(curr.size - prev.size);
   // (curr.size - prev.size) this is the newly added length of the log file
  readFile(fd, buffer, (curr.size - prev.size), prev.size);
  }
 });
 });

}

讀取新增內(nèi)容

function readFile(fd, buffer, length, position) {
 // read file
 fs.read(fd, buffer, 0, length, position, function (err, bytesRead, buffer) {
 if (err) {
  log.error(err);
 }
 console.log('Additional Contents', buffer.toString());
 });
}

額外功能:讀取歷史內(nèi)容

function fetchHistoryLogs(filename) {
 const rl = readLine.createInterface({
 input: fs.createReadStream(filename, {
  enconding: 'utf8'
 }),
 output: null,
 terminal: false
 });

 rl.on('line', (line) => {
 if (line) {
  logsArr.push(line.toString());
 }
 }).on('close', () => {
 for (var i = 0; i < logsArr.length; i++) {
  // Print the data for each row
  console.log(`Original data: \n ${logsArr[i]}`);
 }
 });
}

總結(jié)

以上所述是小編給大家介紹的Nodejs監(jiān)聽(tīng)日志文件的變化的過(guò)程解析,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!

分享文章:Nodejs監(jiān)聽(tīng)日志文件的變化的過(guò)程解析
網(wǎng)站URL:http://www.rwnh.cn/article46/pgsihg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)靜態(tài)網(wǎng)站、微信公眾號(hào)品牌網(wǎng)站設(shè)計(jì)、定制開(kāi)發(fā)移動(dòng)網(wǎng)站建設(shè)

廣告

聲明:本網(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)

成都做網(wǎng)站
青浦区| 吴堡县| 江都市| 陕西省| 萨嘎县| 明水县| 扎兰屯市| 牟定县| 沙洋县| 舒兰市| 麻城市| 五大连池市| 西青区| 体育| 洞口县| 油尖旺区| 徐水县| 永修县| 阳城县| 德惠市| 隆化县| 忻城县| 全椒县| 灵璧县| 徐州市| 海城市| 囊谦县| 广宁县| 惠安县| 嵊泗县| 申扎县| 郴州市| 陇西县| 呼和浩特市| 台中县| 石柱| 南华县| 始兴县| 利辛县| 乌苏市| 宁夏|