在最近的项目中,为了便于分析把项目的日志都存成了JSON格式。之前日志直接存在了文件中,而MongoDB适时闯入了我的视线,于是就把log存进了MongoDB中。log只存起来是没有意义的,最关键的是要从日志中发现业务的趋势、系统的性能漏洞等。之前有一个用Java写的分析模块,运行在Tomcat下。实现相当的重量级,添加一个新指标的流程也比较繁琐,而且由于NFS的原因还导致分析失败。一直想改写,最初想用Ruby On Rails,可是一直没有时间学习和开发(在找借口啊!)。在杭州QCon 2011上又遇到了Node.js,虽然之前也听说过,但是没有深入研究,听了淘宝苏千 的演讲后,当时了就有要用Node.js实现这个日志分析系统的想法。前端用JS,服务器用JS,就连数据库的Shell都是JS,想想就够酷的——当然最关键是代码量小。
一、用Node.js实现服务器端代码
为了有良好的风格和快速的代码编写,不可避免地应该采用一个简单的框架。Express实现了大部分的功能,可是好需要花一定时间熟悉,并且看起来对这个项目来说有些重量级。在Node.js的官网上有一个聊天的Demo,这个代码简单移动,封装了对URL的处理和返回JSON。
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /pub/2011/12/19/使用Node.js + MongoDB实现一个简单的日志分析系统/
于是我就直接使用了fu.js,重写了server.js:
- HOST = null;
- 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"));
|
太简单了吧?!不过的确是这样,一个服务器已经建立起来了。
下面看处理请求的request_handler.js代码:
- var mongodb = require("mongodb");
- var fu = require("./fu");
-
-
-
- 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 ++){
-
- 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>
-
- <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的示例中的完整拷贝,好吧,我承认我太懒了。
下面是看用来显示生成图形的chart.js:
-
-
- var draws = [];
-
-
- 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){
-
- }
- }
- });
- }
-
-
- draws.push('drawUserActionTop10Chart');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var drawAllCharts = function(){
- for(var i = 0; i < draws.length; i ++){
- eval(draws[i] + "()");
- }
-
-
-
- window.setTimeout(drawAllCharts, 5 * 60 * 1000);
- }
-
-
-
- $(function(){
- drawAllCharts();
- });
|

好像忘了什么?日志的分析代码。
在最近的项目中,为了便于分析把项目的日志都存成了JSON格式。之前日志直接存在了文件中,而MongoDB适时闯入了我的视线,于是就把log存进了MongoDB中。log只存起来是没有意义的,最关键的是要从日志中发现业务的趋势、系统的性能漏洞等。之前有一个用Java写的分析模块,运行在Tomcat下。实现相当的重量级,添加一个新指标的流程也比较繁琐,而且由于NFS的原因还导致分析失败。一直想改写,最初想用Ruby On Rails,可是一直没有时间学习和开发(在找借口啊!)。在杭州QCon 2011上又遇到了Node.js,虽然之前也听说过,但是没有深入研究,听了淘宝苏千 的演讲后,当时了就有要用Node.js实现这个日志分析系统的想法。前端用JS,服务器用JS,就连数据库的Shell都是JS,想想就够酷的——当然最关键是代码量小。
一、用Node.js实现服务器端代码
为了有良好的风格和快速的代码编写,不可避免地应该采用一个简单的框架。Express实现了大部分的功能,可是好需要花一定时间熟悉,并且看起来对这个项目来说有些重量级。在Node.js的官网上有一个聊天的Demo,这个代码简单移动,封装了对URL的处理和返回JSON。
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /pub/2011/12/19/使用Node.js + MongoDB实现一个简单的日志分析系统/
于是我就直接使用了fu.js,重写了server.js:
- HOST = null;
- 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"));
|
太简单了吧?!不过的确是这样,一个服务器已经建立起来了。
下面看处理请求的request_handler.js代码:
- var mongodb = require("mongodb");
- var fu = require("./fu");
-
-
-
- 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 ++){
-
- 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>
-
- <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的示例中的完整拷贝,好吧,我承认我太懒了。
下面是看用来显示生成图形的chart.js:
-
-
- var draws = [];
-
-
- 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){
-
- }
- }
- });
- }
-
-
- draws.push('drawUserActionTop10Chart');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var drawAllCharts = function(){
- for(var i = 0; i < draws.length; i ++){
- eval(draws[i] + "()");
- }
-
-
-
- window.setTimeout(drawAllCharts, 5 * 60 * 1000);
- }
-
-
-
- $(function(){
- drawAllCharts();
- });
|

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