手机版

Node.js和MongoDB实现简单日志分析系统

时间:2021-09-09 来源:互联网 编辑:宝哥软件园 浏览:

在最近的项目中,项目日志以JSON格式保存,以便于分析。以前日志直接存储在文件中,但是MongoDB及时闯入了我的视线,所以我把日志保存在了MongoDB中。只保存日志是没有意义的。最重要的是从日志中发现业务趋势和系统性能漏洞。之前有一个用Java写的分析模块,运行在Tomcat下。这是相当重量级的,添加新指数的过程很麻烦,而且由于NFS,分析失败。一直想重写,本来想用Ruby On Rails,但是一直没时间研究开发(找借口!)。2011杭州QCon我又遇到了Node.js。虽然之前听说过,但是没有深入研究过。听了淘宝苏千的演讲,有了用Node.js实现这个日志分析系统的想法。前端用JS,服务器用JS,甚至数据库的Shell也是JS。考虑到——已经够酷了,当然关键是代码量少。

1.用Node.js实现服务器端代码

为了拥有良好的风格和快速的代码编写,采用简单的框架是不可避免的。Express已经实现了大部分功能,但是需要一些时间去熟悉,对于这个项目来说似乎有点沉重。Node.js官网有一个聊天的Demo这个代码移动简单,封装了URL的处理,返回JSON。所以我直接用了fu.js,重写了server.js:复制代码如下:HOST=null//localhostPORT=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 . static handler(' index . html '));

是不是太简单了?但这是真的。已经设置了服务器。查看request_handler.js处理请求的代码:复制代码如下: var MongoDB=require(' MongoDB ');var fu=require('。/fu’);

//TOP 10用户Actionfu.get('/userActionTop10 ',函数(req,RES){ MongoDB . connect(' MongoDB ://localhost :27017/log '),函数(err,conn){ conn . collection(' action _ count '),函数(err,coll){ coll . find({ ' value . action ' : { $ in : user _ action } })。排序({'value.count':-1})。极限(10)。toArray(函数(err,docs){ if(!err){ var action=[];var count=[];for(var I=0;i docs.lengthI){//console . log(docs[I]);action . push(docs[I]. value . action);count . push(docs[I]. value . count);} res.simpleJSON(200,{action:action,count : count });//记得关闭数据库连接conn . close();} });});});});

第二,客户

日志系统最重要的是可视化显示。这里使用了JQuery的插件jqPlot Chart。首先,使用一个静态HTML页面作为图形显示的容器:复制代码如下:DOCTYPE html html head meta charset=' utf-8 ' title rendezvous Monitor System/title!-[if lt IE 9]脚本src='http:js/excanvas.js '![endif] -脚本src=' http : js/jquery . min . js '/脚本脚本src=' http : js/jquery . jqplot . min . js '/脚本脚本src=' http : js/plugins/jqplot . barrender . min . js '/脚本脚本脚本src=' http : js/plugins/jqplot . categoryaxirenderer . min . js '/脚本脚本src='

几乎是jqPlot的示例中的完整拷贝,好吧,我承认我太懒了。下面是看用来显示生成图形的chart.js:复制代码代码如下://存储所有图表绘制功能,如果我们想禁用一个图表,只需要//在数组中放入功能时注释推送线即可。图表绘制

/*************************前10名用户操作开始* * * * *文件。write(' div id=' User action to 10 chart '/div ');

var drawuser actionto 10 chart=function(){ if(!$('#userActionTop10Chart ').attr(' class '){ $(' # user action top 10 chart ').attr('class ',' small _ chart ');}

$.ajax({ async:false,url: '/userActionTop10 ',dataType:'json ',cache: false,success :函数(数据){ try { $(' # user action top10 chart ').html(" ");

$.jqplot('userActionTop10Chart ',[data.count],{ title: 'TOP 10 User Action ',系列默认值3360 { render : $。jqplot。barrender,rendererooptions 3360 { fill to zero : true },point labels : { show 3: true,ypadding:1 } },axes defaults 3360 { ticket render : $ .} catch(e){//alert(e . message);} } });}

平局。push(' drawusereactiontop10 chart ');

/**************************前10名用户操作结束* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

/* * * * * * * * * * * *图表开始* * * * * * * * * * * * * * * * * *

//把你的图表绘制功能放在这里//1。为图表//2插入div .实现绘制图表//3的功能。将函数名推入数组绘图

/* * * * * * * * * * * *图表结束* * * * * * * * * * * * * * * * * * * *

//绘制所有图表var绘制所有图表=函数(){ for(var I=0;我画。长度;I){ eval(draw[I]'()');}

//5分钟回忆自己。窗户。settimeout(绘制图表,5 * 60 * 1000);}

//$(function(){ drawl charts();});

服务器端和客户端的代码都有了,那就跑起来看效果吧:

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

三、使用MongoDB增量式MapReduce实现日志分析

在MongoDB的文档中有关于增量MapReduce的介绍。刚开始一直以为MongoDB实现流动处理,可以自动执行增量式的MapReduce。最后发现原来是我理解有误,文档里并没有写这一点,只是说明了如何设置才能增量执行MapReduce。

为了方便,我把MapReduce使用MongoDB的Java脚本语言写在了单独的射流研究…文件中,然后通过crontab定时执行stats.js。的代码:复制代码代码如下:/***********该文件由/etc/crontab每5分钟执行一次* * * * * * * * * * * */var action _ count _ map=function(){ emit(this。action,{action:this.action,count :1 });}

var action _ count _ reduce=function(key,values){ var count=0;价值观。foreach(函数(值){ count=value。计数;});返回{action:key,count : count };}

db。日志。MapReduce(action _ count _ map,action_count_reduce,{ query : { ' action _ count ' : { $ ne :1 } },out : { reduce 3360 ' action _ count ' });

db。日志。update({ ' action _ count ' : { $ ne :1 } },{ $ set : { ' action _ count ' :1 } },false,true);

思路很简单:1.在地图中将每个行为访问次数设为12.减少中,统计相同行为的访问次数3.执行mapReduce。指定了查询为操作计数不等于1,也就是没有执行过该统计;将结果存储在操作计数集合,并且使用减少选项表示该结果集作为下次减少的输入。4.在当前所有日志记录设置操作计数的值为1,表示已经执行过该统计。不知道这种是否会造成没有还没有统计过的记录也被更新?望有经验的大侠赐教!

定时执行stats.js的外壳:复制代码代码如下:*/5 * * * *根CD/根/日志;mongo localhost :27017/日志统计。射流研究…

好了,这是全部代码。没什么特别的,但是Node.js确实是个好东西。

版权声明:Node.js和MongoDB实现简单日志分析系统是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。