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

Node.js和MongoDB實(shí)現(xiàn)簡單日志分析系統(tǒng)

 更新時(shí)間:2015年04月25日 09:31:03   投稿:junjie  
這篇文章主要介紹了Node.js和MongoDB實(shí)現(xiàn)簡單日志分析系統(tǒng),本文給出了服務(wù)器端、客戶端、圖表生成、Shell自動(dòng)執(zhí)行等功能的實(shí)現(xiàn)代碼,需要的朋友可以參考下

在最近的項(xiàng)目中,為了便于分析把項(xiàng)目的日志都存成了JSON格式。之前日志直接存在了文件中,而MongoDB適時(shí)闖入了我的視線,于是就把log存進(jìn)了MongoDB中。log只存起來是沒有意義的,最關(guān)鍵的是要從日志中發(fā)現(xiàn)業(yè)務(wù)的趨勢、系統(tǒng)的性能漏洞等。之前有一個(gè)用Java寫的分析模塊,運(yùn)行在Tomcat下。實(shí)現(xiàn)相當(dāng)?shù)闹亓考?,添加一個(gè)新指標(biāo)的流程也比較繁瑣,而且由于NFS的原因還導(dǎo)致分析失敗。一直想改寫,最初想用Ruby On Rails,可是一直沒有時(shí)間學(xué)習(xí)和開發(fā)(在找借口?。。?。在杭州QCon 2011上又遇到了Node.js,雖然之前也聽說過,但是沒有深入研究,聽了淘寶蘇千 的演講后,當(dāng)時(shí)了就有要用Node.js實(shí)現(xiàn)這個(gè)日志分析系統(tǒng)的想法。前端用JS,服務(wù)器用JS,就連數(shù)據(jù)庫的Shell都是JS,想想就夠酷的——當(dāng)然最關(guān)鍵是代碼量小。

一、用Node.js實(shí)現(xiàn)服務(wù)器端代碼

為了有良好的風(fēng)格和快速的代碼編寫,不可避免地應(yīng)該采用一個(gè)簡單的框架。Express實(shí)現(xiàn)了大部分的功能,可是好需要花一定時(shí)間熟悉,并且看起來對這個(gè)項(xiàng)目來說有些重量級。在Node.js的官網(wǎng)上有一個(gè)聊天的Demo ,這個(gè)代碼簡單移動(dòng),封裝了對URL的處理和返回JSON。于是我就直接使用了fu.js,重寫了server.js:

復(fù)制代碼 代碼如下:

HOST = null; // localhost
PORT = 8001;

var fu = require("./fu"),
    sys = require("util"),
    url = require("url"),
    mongo = require("./request_handler");

fu.listen(Number(process.env.PORT || PORT), HOST);

fu.get("/", fu.staticHandler("index.html"));

太簡單了吧?!不過的確是這樣,一個(gè)服務(wù)器已經(jīng)建立起來了。
下面看處理請求的request_handler.js代碼:

復(fù)制代碼 代碼如下:

var mongodb = require("mongodb");
var fu = require("./fu");


// TOP 10 user Action
fu.get("/userActionTop10", function(req, res){
  mongodb.connect('mongodb://localhost:27017/log', function(err, conn){
    conn.collection('action_count', function(err, coll){
      coll.find({"value.action":{$in:user_action}}).sort({"value.count":-1}).limit(10).toArray(function(err, docs){
        if(!err){
          var action = [];
          var count = [];
          for(var i = 0; i < docs.length; i ++){
            //console.log(docs[i]);
            action.push(docs[i].value.action);
            count.push(docs[i].value.count);
          }
          res.simpleJSON(200, {action:action, count:count});
        
          // 一定要記得關(guān)閉數(shù)據(jù)庫連接
          conn.close();
        }
      });
    });
  });
});

二、客戶端

日志系統(tǒng)的最重要的是可視化顯示,這里使用了JQuery的一個(gè)插件jqPlot Chart 。首先使用一個(gè)靜態(tài)的HTML頁面,用來作為圖形顯示的容器:

復(fù)制代碼 代碼如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Rendezvous Monitor System</title>
    <!--[if lt IE 9]><script src="js/excanvas.js"><![endif]-->
    <script src="js/jquery.min.js"></script>
    <script src="js/jquery.jqplot.min.js"></script>
    <script src="js/plugins/jqplot.barRenderer.min.js"></script>
    <script src="js/plugins/jqplot.categoryAxisRenderer.min.js"></script>
    <script src="js/plugins/jqplot.canvasTextRenderer.min.js"></script>
    <script src="js/plugins/jqplot.canvasAxisTickRenderer.min.js"></script>
    <script src="js/plugins/jqplot.canvasAxisLabelRenderer.min.js"></script>
    <script src="js/plugins/jqplot.pointLabels.min.js"></script>
    <script src="js/plugins/jqplot.dateAxisRenderer.min.js"></script>
    <script src="js/plugins/jqplot.json2.min.js"></script>
    <link rel="stylesheet" href="js/jquery.jqplot.min.css">
    <link rel="stylesheet" href="style/base.css">
    <script src="js/charts.js"></script>
  </head>
  <body>
  </body>
</html>

幾乎是jqPlot的示例中的完整拷貝,好吧,我承認(rèn)我太懶了。
下面是看用來顯示生成圖形的chart.js:

復(fù)制代碼 代碼如下:

// Store all chart drawing function, if we want to disable one chart, only need
// comment the push line when putting fucntion into the array.
var draws = [];

/****************************** TOP 10 User Action Start *********************************/
document.write('<div id="userActionTop10Chart"></div>');


var drawUserActionTop10Chart = function(){
  if(!$("#userActionTop10Chart").attr('class')){
    $("#userActionTop10Chart").attr('class', 'small_chart');
  }


  $.ajax({
    async:false,
    url: '/userActionTop10',
    dataType:'json',
    cache: false,
    success:function(data){
      try{
        $('#userActionTop10Chart').html('');


        $.jqplot('userActionTop10Chart', [data.count], {
          title: "TOP 10 User Action",
          seriesDefaults:{
            renderer:$.jqplot.BarRenderer,
            rendererOptions: {fillToZero: true},
            pointLabels: {
              show:true,
              ypadding:1
            }
          },
          axesDefaults:{
            tickRenderer:$.jqplot.CanvasAxisTickRenderer,
            tickOptions: {
              angle: -30,
              fontSize: '12px'
            }
          },
          axes: {
            xaxis: {
              renderer: $.jqplot.CategoryAxisRenderer,
              ticks: data.action
            },
            yaxis: {
              pad: 1.05
            }
          }
        });
      }catch(e){
        //alert(e.message);
      }
    }
  });
}


draws.push('drawUserActionTop10Chart');


/******************************* TOP 10 User Action End ************************************/

/*********** Chart Start *****************/


//Put your chart drawing function here
//1. insert a div for the chart
//2. implement the function drawing chart
//3. push the function name into the array draws


/*********** Chart End *******************/

// Draw all charts
var drawAllCharts = function(){
  for(var i = 0; i < draws.length; i ++){
    eval(draws[i] + "()");
  }


 //Recall itself in 5 minute.
 window.setTimeout(drawAllCharts, 5 * 60 * 1000);
}


//
$(function(){
  drawAllCharts();
});

服務(wù)器端和客戶端的代碼都有了,那就跑起來看效果吧:

好像忘了什么?日志的分析代碼。

三、使用MongoDB 增量式MapReduce實(shí)現(xiàn)日志分析

在MongoDB的文檔中有關(guān)于Incremental MapReduce的介紹。剛開始一直以為MongoDB實(shí)現(xiàn)Streaming處理,可以自動(dòng)執(zhí)行增量式的MapReduce。最后發(fā)現(xiàn)原來是我理解有誤,文檔里并沒有寫這一點(diǎn),只是說明了如何設(shè)置才能增量執(zhí)行MapReduce。

為了方便,我把MapReduce使用MongoDB的JavaScript寫在了單獨(dú)的js文件中,然后通過crontab定時(shí)執(zhí)行。stats.js的代碼:

復(fù)制代碼 代碼如下:

/************** The file is executed per 5 minutes by /etc/crontab.*****************/
var action_count_map = function(){
  emit(this.action, {action:this.action, count:1});
}

var action_count_reduce = function(key, values){
  var count = 0;
  values.forEach(function(value){
    count += value.count;
  });
  return {action:key, count : count};
}


db.log.mapReduce(action_count_map, action_count_reduce, {query : {'action_count' : {$ne:1}},out: {reduce:'action_count'}});

db.log.update({'action_count':{$ne:1}}, {$set:{'action_count':1}}, false, true);

 思路很簡單:
1. 在map中將每個(gè)action訪問次數(shù)設(shè)為1
2. reduce中,統(tǒng)計(jì)相同action的訪問次數(shù)
3. 執(zhí)行mapReduce。指定了查詢?yōu)椤產(chǎn)ction_count'不等于1,也就是沒有執(zhí)行過該統(tǒng)計(jì);將結(jié)果存儲在‘a(chǎn)ction_count'集合,并且使用reduce選項(xiàng)表示該結(jié)果集作為下次reduce的輸入。
4. 在當(dāng)前所有日志記錄設(shè)置'action_count'的值為1,表示已經(jīng)執(zhí)行過該統(tǒng)計(jì)。不知道這種是否會(huì)造成沒有還沒有統(tǒng)計(jì)過的記錄也被更新??望有經(jīng)驗(yàn)的大俠賜教!

定時(shí)執(zhí)行stats.js的shell:

復(fù)制代碼 代碼如下:

*/5 * * * * root cd /root/log; mongo localhost:27017/log stats.js

好了,這就是全部的代碼,沒有什么特別玄妙的地方,不過Node.js真的是個(gè)好東西。

相關(guān)文章

  • Node.js靜態(tài)服務(wù)器的實(shí)現(xiàn)方法

    Node.js靜態(tài)服務(wù)器的實(shí)現(xiàn)方法

    這篇文章主要介紹了Node.js靜態(tài)服務(wù)器的實(shí)現(xiàn)方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • nodejs+mongodb aggregate級聯(lián)查詢操作示例

    nodejs+mongodb aggregate級聯(lián)查詢操作示例

    這篇文章主要介紹了nodejs+mongodb aggregate級聯(lián)查詢操作,結(jié)合實(shí)例形式分析了基于nodejs的mongodb數(shù)據(jù)庫級聯(lián)查詢相關(guān)操作技巧,需要的朋友可以參考下
    2018-03-03
  • Express使用multer實(shí)現(xiàn)文件上傳的示例代碼

    Express使用multer實(shí)現(xiàn)文件上傳的示例代碼

    這篇文章主要介紹了Express 使用 multer 實(shí)現(xiàn)文件上傳的操作步驟,文中通過代碼示例和圖文結(jié)合的方式講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • Node中使用ES6語法的基礎(chǔ)教程

    Node中使用ES6語法的基礎(chǔ)教程

    隨著google和firfox以及node6.0對es6的支持,es6語法的定稿使它越來越受到關(guān)注,尤其是react項(xiàng)目基本上都是用es6來寫的。下面這篇文章主要給大家介紹了關(guān)于Node中使用ES6語法的基礎(chǔ)教程,需要的朋友可以參考下。
    2018-01-01
  • 一文詳解NPM如何換源

    一文詳解NPM如何換源

    在每一次的實(shí)際開發(fā)過程中我們都會(huì)下載相關(guān)的依賴包,最官方的是 npm,但是該服務(wù)器對于國內(nèi)開發(fā)者來說,下載起來是比較慢的,所以我們需要換源,下面這篇文章主要給大家介紹了關(guān)于NPM如何換源的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Node.js 中 cors 依賴示例詳解

    Node.js 中 cors 依賴示例詳解

    cors是一個(gè)用于處理跨域資源共享(CORS)問題的Node.js中間件,可以幫助開發(fā)人員解決前后端分離項(xiàng)目中的跨域問題,該中間件提供了多種配置選項(xiàng),以滿足不同的跨域需求,如指定允許跨域請求的源、請求方法、請求頭等,本文介紹Node.js  cors 依賴相關(guān)知識,感興趣的朋友一起看看吧
    2025-02-02
  • Node.js的Koa實(shí)現(xiàn)JWT用戶認(rèn)證方法

    Node.js的Koa實(shí)現(xiàn)JWT用戶認(rèn)證方法

    本篇文章主要介紹了Node.js的Koa實(shí)現(xiàn)JWT用戶認(rèn)證方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • Mac下通過brew安裝指定版本的nodejs教程

    Mac下通過brew安裝指定版本的nodejs教程

    今天小編就為大家分享一篇Mac下通過brew安裝指定版本的nodejs教程,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Node.js進(jìn)程退出的深入理解

    Node.js進(jìn)程退出的深入理解

    NodeJS可以感知和控制自身進(jìn)程的運(yùn)行環(huán)境和狀態(tài),也可以創(chuàng)建子進(jìn)程并與其協(xié)同工作,這使得NodeJS可以把多個(gè)程序組合在一起共同完成某項(xiàng)工作,下面這篇文章主要給大家介紹了關(guān)于Node.js進(jìn)程退出的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • node.js增刪改查保姆級教程方法

    node.js增刪改查保姆級教程方法

    這篇文章主要給大家介紹了關(guān)于node.js增刪改查保姆級教程的相關(guān)資料,node.js接口可以實(shí)現(xiàn)增加、刪除、修改和查詢操作,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07

最新評論

虹口区| 丰都县| 安西县| 太白县| 逊克县| 芜湖市| 东至县| 岳西县| 宜章县| 郴州市| 汝州市| 政和县| 彭山县| 马龙县| 昭觉县| 宁远县| 莲花县| 南宫市| 东光县| 察雅县| 永寿县| 松潘县| 嘉兴市| 和顺县| 镇远县| 岳池县| 二连浩特市| 浦东新区| 女性| 庆阳市| 资兴市| 繁峙县| 屯昌县| 新泰市| 五寨县| 茶陵县| 时尚| 合作市| 武鸣县| 武安市| 茌平县|