最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

NodeJS讀取分析Nginx錯(cuò)誤日志的方法

 更新時(shí)間:2019年05月14日 14:35:06   作者:zpzxgcr  
這篇文章主要介紹了NodeJS讀取分析Nginx錯(cuò)誤日志的相關(guān)知識,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

網(wǎng)上很少看到有用NodeJS運(yùn)維系列文章,后續(xù)我會(huì)更新一些NodeJS運(yùn)維相關(guān)的內(nèi)容又或者說讓我們更加的深入了解一些服務(wù)器的知識以及自動(dòng)化運(yùn)維方面的基礎(chǔ)知識 為什么要做錯(cuò)誤日志分析,因?yàn)榫W(wǎng)上這方面的工具不多我找到一個(gè)goaccess但是都是分析成功日志以及用戶訪問趨勢,找了半天沒找著自己想要的索性就自己利用Node造一個(gè)

錯(cuò)誤日志分析

首先我們要讀取Nginx日志,我們可以看到Nginx的錯(cuò)誤日志格式一般都是這樣子,需要注意的是Nginx的錯(cuò)誤日志格式是差不多的因?yàn)闊o法設(shè)置日志格式只能設(shè)置日志錯(cuò)誤等級所以我們分析的時(shí)候很方便

 這里我們用到readline

逐行讀取,簡單來說可以做

  • 文件逐行讀取:比如說進(jìn)行日志分析。
  • 自動(dòng)完成:比如輸入npm,自動(dòng)提示"help init install"。
  • 命令行工具:比如npm init這種問答式的腳手架工具。 這里我們主要做日志分析其他的感興趣可以琢磨一下

實(shí)現(xiàn)方法

const readline = require('readline');
const fs = require('fs');
const path = require('path');
console.time('readline-time')
const rl = readline.createInterface({
 input: fs.createReadStream(path.join(__dirname, '../public/api.err.log'), {
  start: 0,
  end: Infinity
 }),

});
let count = 0; 
rl.on('line', (line) => {
 const arr = line.split(', ');
 const time = arr[0].split('*')[0].split('[')[0].replace(/\//g, '-');//獲取到時(shí)間
 const error = arr[0].split('*')[1].split(/\d\s/)[1];//錯(cuò)誤原因
 const client = arr[1].split(' ')[1];//請求的客戶端
 const server = arr[2].split(' ')[1];//請求的網(wǎng)址
 const url = arr[3].match(/\s\/(\S*)\s/)[0].trim()//獲取請求鏈接
 const upstream = arr[4].match(/(?<=").*?(?=")/g)[0];//獲取上游
 const host = arr[5].match(/(?<=").*?(?=")/g)[0];//獲取host
 const referrer = arr[6] ? arr[6].match(/(?<=").*?(?=")/g)[0] : '';//來源
 console.log(`時(shí)間:${time}-原因:${error}-客戶端:${client}-網(wǎng)址:${server}-地址:${url}-上游:${upstream}-主機(jī):${host}-來源:${referrer}`); 
 count++;
});
rl.on('close', () => {
 let size = fs.statSync(path.join(__dirname, '../public/api.err.log')).size;
 console.log(`讀取完畢:${count};文件位置:${size % 2 === 0}`);
 console.timeEnd('readline-time')
});

上面代碼有幾點(diǎn)需要注意的是會(huì)創(chuàng)建一個(gè)文件可讀流然后由于演示所以我是直接找的本地地址如果是生產(chǎn)環(huán)境的話大家可以直接填寫服務(wù)器上的錯(cuò)誤日志地址,如果沒有Nginx錯(cuò)誤日志分割的話每天會(huì)產(chǎn)生很多日志,createReadStream讀取幾十M的文件還好如果讀取幾百M(fèi)或者上G的容量日志這會(huì)造成性能問題,所以我們需要在每次createReadStream沒必要每次從0字節(jié)開始讀取,ceateReadStream提供了start和end

 

所以我們每次可以在讀取完之后記錄一下當(dāng)前文件字節(jié)大小下一次讀取文件就是可以用該文件上次的大小開始讀取

let size = fs.statSync(path.join(__dirname, '../public/api.err.log')).size;

我們可以對比一下每次從0字節(jié)開始讀取和從指定字節(jié)讀取

保存數(shù)據(jù)進(jìn)行分析

這里我是用node-schedule這個(gè)庫進(jìn)行定時(shí)保存錯(cuò)誤日志和linux的cron差不多,用的mongodb保存數(shù)據(jù),這里更推薦大家用elasticsearch來做日志分析

rl.on('close', async () => {
     let count = 0;
     for (let i of rlist) {
      count++;
      if (count % 500 === 0) {
       const res = await global.db.collection('logs').bulkWrite(rlist.slice(count, count + 500), { ordered: false, w: 1 }).catch(err => { console.error(`批量插入出錯(cuò)${err}`) }); 
      } else if (count === rlist.length - 1) {
      //批量插入 數(shù)據(jù)
       const res = await global.db.collection('logs').bulkWrite(rlist.slice(rlist - (rlist % 500), rlist.length), { ordered: false, w: 1 });
       let size = fs.statSync(addres).size;
       size = size % 2 === 0 ? size : size + 1;//保證字節(jié)大小是偶數(shù) 不然會(huì)出現(xiàn)讀取上行內(nèi)容不完整的情況
       count = 0;
       rlist.length = [];
       //更新數(shù)據(jù)庫里面文件的size
       global.db.collection('tasks').updateOne({ _id: addre }, { $set: { _id: addre, size, date: +new Date() } }, { upsert: true }); 
      }
     }
     resolve(true);
    })

上面主要是500條保存一次,因?yàn)槲矣玫氖桥坎迦肴缓髆ongodb有限制一次性最多插入16M數(shù)據(jù)的限制,所以大家看自己清空決定一次性插入多少條 猶豫對readline的實(shí)現(xiàn)比較感興趣,就去翻閱了一下源碼發(fā)現(xiàn)并不是我們想的那么復(fù)雜, readline源碼 ,下面貼一下line事件的源碼,想繼續(xù)深入的同學(xué)可以看看全部的源碼

if (typeof s === 'string' && s) {
     var lines = s.split(/\r\n|\n|\r/);
     for (var i = 0, len = lines.length; i < len; i++) {
      if (i > 0) {
       this._line();
      }
      this._insertString(lines[i]);
     }
    }
...
Interface.prototype._line = function() {
 const line = this._addHistory();
 this.clearLine();
 this._onLine(line);
};
...
Interface.prototype._onLine = function(line) {
 if (this._questionCallback) {
  var cb = this._questionCallback;
  this._questionCallback = null;
  this.setPrompt(this._oldPrompt);
  cb(line);
 } else {
  this.emit('line', line);
 }
};

保存的數(shù)據(jù)需要進(jìn)行分析比如哪個(gè)IP訪問最多哪條錯(cuò)誤最多可以用聚合來進(jìn)行分析貼出示例分析某個(gè)IP在某一天訪問出錯(cuò)最多的原因

db.logs.aggregate(
 // Pipeline
 [
 // Stage 1
 {
  $group: {
   '_id': { 'client': '114.112.163.28', 'server': '$server', 'error': '$error', 'url': '$url', 'upstream': '$upstream','date':'$date' ,'msg':'$msg' } ,
     
   'date':{'$addToSet':'$date'},
   count: { '$sum': 1 } 
  }
 },
 // Stage 2
 {
  $match: { 
     count: { $gte: 1 },
     date: ['2019-05-10']
    
  }
 },
 {
  $sort: {
    count: -1
  }
 },
 ],
 // Options
 {
 cursor: {
  batchSize: 50
 },
 allowDiskUse: true
 }
);

總結(jié)

以上所述是小編給大家介紹的NodeJS讀取分析Nginx錯(cuò)誤日志的方法,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!

相關(guān)文章

  • 安裝 node-Sass 報(bào)錯(cuò)的解決記錄(三步解決法)

    安裝 node-Sass 報(bào)錯(cuò)的解決記錄(三步解決法)

    本文主要介紹了安裝 node-Sass 報(bào)錯(cuò)的解決記錄(三步解決法),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • ajax+node+request爬取網(wǎng)絡(luò)圖片的實(shí)例(宅男福利)

    ajax+node+request爬取網(wǎng)絡(luò)圖片的實(shí)例(宅男福利)

    下面小編就為大家?guī)硪黄猘jax+node+request爬取網(wǎng)絡(luò)圖片的實(shí)例(宅男福利)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • node.js 使用ejs模板引擎時(shí)后綴換成.html

    node.js 使用ejs模板引擎時(shí)后綴換成.html

    本文給大家分享一個(gè)nodejs的小技巧,將ejs模板引擎的模板后綴改成.html的使用方法,非常的簡單實(shí)用,這里推薦給大家。
    2015-04-04
  • Node.js包管理工具

    Node.js包管理工具

    本文主要詳細(xì)介紹了node包管理工具,主要介紹了npm,cnpm及yarn,文中有詳細(xì)的代碼示例,對學(xué)習(xí)具有一定參考價(jià)值,需要的朋友可以參考一下
    2023-04-04
  • 從零學(xué)習(xí)node.js之mysql數(shù)據(jù)庫的操作(五)

    從零學(xué)習(xí)node.js之mysql數(shù)據(jù)庫的操作(五)

    因?yàn)榻佑|Node.JS已經(jīng)有一段時(shí)間了,最近粗略的研究了一下node.js操作數(shù)據(jù)庫的包,覺得node.js連接數(shù)據(jù)庫不錯(cuò)。下面這篇文章主要給大家介紹了node.js之mysql數(shù)據(jù)庫操作的相關(guān)資料,需要的朋友可以參考下。
    2017-02-02
  • Node.js中下包速度慢問題解決方法分析

    Node.js中下包速度慢問題解決方法分析

    這篇文章主要介紹了Node.js中下包速度慢問題解決方法,分析了npm切換鏡像源以及nrm工具鏡像源管理相關(guān)使用技巧,需要的朋友可以參考下
    2023-04-04
  • npm?i報(bào)錯(cuò)以及解決方案實(shí)戰(zhàn)案例

    npm?i報(bào)錯(cuò)以及解決方案實(shí)戰(zhàn)案例

    npm在前端開發(fā)流程中提供了非常完善的自動(dòng)化工具鏈,但是同樣由于其復(fù)雜性導(dǎo)致有很多奇奇怪怪的問題,下面這篇文章主要給大家介紹了關(guān)于npm?i報(bào)錯(cuò)以及解決方案的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • 詳解Node全局變量global模塊

    詳解Node全局變量global模塊

    這篇文章主要介紹了詳解Node全局變量global模塊,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • 詳解nodeJS之二進(jìn)制buffer對象

    詳解nodeJS之二進(jìn)制buffer對象

    本篇文章主要介紹了nodeJS之二進(jìn)制buffer對象,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • node.js+postman實(shí)現(xiàn)模擬HTTP服務(wù)器與客戶端交互

    node.js+postman實(shí)現(xiàn)模擬HTTP服務(wù)器與客戶端交互

    本文主要介紹了node.js+postman實(shí)現(xiàn)模擬HTTP服務(wù)器與客戶端交互,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評論

天祝| 米林县| 竹溪县| 漯河市| 双辽市| 宜阳县| 阳原县| 武穴市| 同仁县| 康马县| 凤凰县| 株洲县| 溆浦县| 永顺县| 上栗县| 德钦县| 潜江市| 犍为县| 濉溪县| 冀州市| 类乌齐县| 精河县| 梨树县| 栾城县| 永胜县| 蒙自县| 阳原县| 扎鲁特旗| 湘乡市| 鹤山市| 林西县| 岳阳县| 武安市| 昌邑市| 江阴市| 井研县| 镇沅| 阳信县| 枣强县| 高邮市| 邻水|