Переглянути джерело

Fix jsonendpoint mysql. Endpoint mongodb

Guillermo Espinoza 8 роки тому
батько
коміт
ffdd64215c

+ 14 - 0
docker-compose.yml

@@ -149,6 +149,7 @@ services:
     image: grafana/grafana
     links:
      - jsonendpoint:endpoint
+     - mongodb_jsonendpoint:endpoint
      - mysql:mysql
     ports:
      - 3000:3000
@@ -181,6 +182,19 @@ services:
       - ./statsd/endpoint/mysql:/opt/datasource
 
 
+  mongodb_jsonendpoint:
+    restart: always
+    image: fd3_simple_json_endpoint_mongo
+    links:
+      - mongodb:mongodb
+    ports:
+      - 9002:8000
+    build: 
+      context: ./statsd/endpoint/mongodb
+    volumes:
+      - ./statsd/endpoint/mongodb:/opt/datasource
+
+
   mongo_express:
     image: mongo-express
     ports:

+ 17 - 0
statsd/endpoint/mongodb/Dockerfile

@@ -0,0 +1,17 @@
+FROM debian:8
+RUN apt-get update && apt-get install -yq git wget tmux vim nodejs npm
+
+RUN npm install -g n
+
+RUN n stable
+
+WORKDIR /opt/datasource
+COPY index.js /opt/datasource/index.js
+COPY package.json /opt/datasource/package.json
+
+EXPOSE 8000
+
+RUN npm install -g nodemon
+
+CMD npm install && nodejs index.js
+

+ 118 - 0
statsd/endpoint/mongodb/index.js

@@ -0,0 +1,118 @@
+'use strict';
+
+var express = require('express');
+var morgan = require('morgan');
+var bodyParser = require('body-parser');
+var _ = require('lodash');
+var app = express();
+
+var mongo = require('mongodb'),
+    MongoClient = mongo.MongoClient,
+    async = require('async'),
+    util = require('util'),
+    dbs = {},
+    options = {
+            debug: false,
+            prefix: true,
+            size: 100,
+            max: 2610,
+            name: 'statsd',
+            host: 'mongodb',
+            port: 27017
+    };
+
+app.use(morgan('combined'));
+app.use(bodyParser.json());
+
+function setCORSHeaders(res) {
+  res.setHeader("Access-Control-Allow-Origin", "*");
+  res.setHeader("Access-Control-Allow-Methods", "POST");
+  res.setHeader("Access-Control-Allow-Headers", "accept, content-type");  
+}
+
+app.all('/', function(req, res) {
+  setCORSHeaders(res);
+  res.send('https://grafana.com/plugins/grafana-simple-json-datasource\n');
+  res.end();
+});
+
+var result = [];
+app.all('/search', function (req, res) {
+    setCORSHeaders(res);
+    mongo.connect("mongodb://" + options.host + "/" + options.name, function (err, db) {
+        if (err) {
+            console.log(err);
+        }
+        if (options.debug) {
+            console.log("Connected successfully to server");
+        }
+        db.listCollections().toArray(function(err, collInfos) {
+            result = [];
+            for (i = 0; i <= collInfos.length -1; i++) {
+                if (collInfos[i]) {
+                    result.push(collInfos[i].name);
+                }
+            } 
+        });
+        res.json(result);
+        res.end();
+    });
+});
+
+var tsResult = [];
+app.all('/query', function (req, res) {
+    var from = new Date(req.body.range.from);
+    var to = new Date(req.body.range.to);
+    var from_str = Math.floor(from.getTime() / 1000);
+    var to_str = Math.floor(to.getTime() / 1000);
+    var names = _.map(req.body.targets, function (t) {
+        return t.target;
+    });
+    var name = names.join('", "');
+    var interval = req.body.intervalMs / 1000;
+    var maxDataPoints = req.body.maxDataPoints;
+
+    mongo.connect("mongodb://" + options.host + "/" + options.name, function (err, db) {
+        if (err) {
+            console.log(err);
+        }
+//        https://docs.mongodb.com/manual/reference/method/db.collection.find/#db.collection.find
+        db.collection(name).find({ time: { $gte: from_str, $lte: to_str } }, { time: 1, count:1, durations: 1, gauge: 1, set: 1,  $slice: maxDataPoints }).sort({ time: 1 }).toArray(function (err, docs) {
+            if (err) {
+                console.log(err);
+            }
+            var result = {};
+            result[name] = new Array();
+            _.each(docs, function (d) {
+                var value = 0;
+                if (name.indexOf('counters')>= 0) {
+                    value = d.count;
+                } else if (name.indexOf('timers')>= 0) {
+                    value = d.durations;
+                } else if (name.indexOf('gauges')>= 0) {
+                    value = d.gauge;
+                } else if (name.indexOf('sets')>= 0) {
+                    value = d.set;
+                }
+                (result[name]).push([value, 1000 * d.time]);
+            });
+
+            tsResult = [];
+            _.each(_.keys(result), function (d) {
+                var data = {
+                    target: d,
+                    datapoints: result[d]
+                };
+                tsResult.push(data);
+            });
+            
+            setCORSHeaders(res);
+            res.json(tsResult);
+            res.end();
+        });
+    });
+});
+
+app.listen(8000);
+
+console.log("Server is listening to port 8000");

+ 21 - 0
statsd/endpoint/mongodb/package.json

@@ -0,0 +1,21 @@
+{
+  "name": "statsd_mongo_grafana_datasource",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "dependencies": {
+    "body-parser": "^1.15.1",
+    "express": "^4.15.3",
+    "lodash": "^4.13.1",
+    "mongodb": "^2.2.29",
+    "morgan": "^1.8.1",
+    "mysql": "^2.13.0",
+    "nodemon": "^1.11.0"
+  },
+  "devDependencies": {},
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC"
+}

+ 35 - 47
statsd/endpoint/mysql/index.js

@@ -10,7 +10,8 @@ var connection =  mysql.createConnection({
   host     : 'mysql',
   user     : 'root',
   password : '235r2342gtfsw',
-  database : 'statsd_db'
+  database : 'statsd_db',
+  multipleStatements: true
 });
 
 app.use(morgan('combined'))
@@ -116,76 +117,63 @@ app.all('/search', function (req, res) {
     res.end();
 });
 
-/**
- * Este metodo no esta implementado.
- */
-//app.all('/annotations', function(req, res) {
-//  setCORSHeaders(res);
-//  console.log(req.url);
-//  console.log(req.body);
-//
-//  res.json(annotations);
-//  res.end();
-//})
-
-/**
- * @todo :  intervalMs: 500,
- *          targets: [ { 
- * 		type: 'timeserie' 
- * 	    }]
- * 	    maxDataPoints: 1920,
- * 
- */
 var tsResult = [];
-function query(table, req)
+function query(table, req, res)
 {
     var from = new Date(req.body.range.from);
     var to = new Date(req.body.range.to);
     var from_str = Math.floor(from.getTime() / 1000);
     var to_str = Math.floor(to.getTime() / 1000);
     var names = _.map(req.body.targets, function (t) {
-        return t.target
-        console.log(t);
+        return t.target;
     });
-    var sql = 'SELECT timestamp, name, AVG(value) as value FROM `' + table + '` WHERE (timestamp BETWEEN ' + from_str + ' AND ' + to_str + ') AND (`name` IN ("' + names.join('", "') + '")) ORDER BY timestamp ASC';
-
+    
+    //var sql = mode + 'SELECT `timestamp`, `name`, AVG(`value`) AS `value` FROM `' + table + '` WHERE (`timestamp` BETWEEN ' + from_str + ' AND ' + to_str + ') AND (`name` IN ("' + names.join('", "') + '"))';
+    //var group_by = ' GROUP BY UNIX_TIMESTAMP(`timestamp`) DIV ' + interval;
+    
     var interval = req.body.intervalMs / 1000;
-    var group_by = ' GROUP BY UNIX_TIMESTAMP(timestamp) DIV ' + interval;
-
+    var mode = "SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); ";
+    var sql = mode + 'SELECT `timestamp`, `name`, `value` FROM `' + table + '` WHERE (`timestamp` BETWEEN ' + from_str + ' AND ' + to_str + ') AND (`name` IN ("' + names.join('", "') + '"))';
+    var group_by = '';
+    var order_by = ' ORDER BY `timestamp` ASC';
     var maxDataPoints = req.body.maxDataPoints;
-    var limit = ' LIMIT ' + maxDataPoints;
-
-    sql += group_by + limit;
-    console.log(sql);
+    var limit = ' LIMIT ' + maxDataPoints + ';';
+    sql += group_by + order_by + limit;  
+    
     connection.query(sql, function (err, rows, fields) {
         var result = {};
-        _.each(rows, function (d) {
-            if (!(d.name in result)) {
-                result[d.name] = new Array();
+        if (err) {
+            console.log(err);
+        }
+        _.each(rows[1], function (d) {
+            if (d.name) {
+                if (!(d.name in result)) {
+                    result[d.name] = new Array();
+                }
+                (result[d.name]).push([d.value, 1000 * d.timestamp]);
             }
-            (result[d.name]).push([d.value, 1000 * d.timestamp]);
         });
-
         _.each(_.keys(result), function (d) {
-            var data = {target: d};
-            data['datapoints'] = result[d];
+            var data = {
+                target: d,
+                datapoints: result[d]
+            };
             tsResult.push(data);
         });
+        if (res) {
+            setCORSHeaders(res);
+            res.json(tsResult);
+            res.end();
+        }
     });
 }
 
 app.all('/query', function (req, res) {
-    setCORSHeaders(res);
-    console.log(req.url);
-    console.log(req.body);
-
+    tsResult = [];
     query('gauges_statistics', req);
     query('counters_statistics', req);
     query('timers_statistics', req);
-    query('sets_statistics', req);
-
-    res.json(tsResult);
-    res.end();
+    query('sets_statistics', req, res);
 });
 
 app.listen(8000);