diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..7b142a0 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,15 @@ +{ + "extends": "airbnb/base", + + "rules": { + "no-console": 0 + }, + "globals": { + "describe", + "it", + "before", + "beforeEach", + "after", + "afterEach" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b38db2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +build/ diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..0f61653 --- /dev/null +++ b/README.rst @@ -0,0 +1,19 @@ +===== +About +===== + +SeeStats RTM (Real Time Messaging) API provides facilities to receive +new stats data as soon as it's available. +It's powered by socket.io. + +Dependencies +============ + +* nodejs 5.7.1 + +Setup +===== + +:: + + $ nodejs src/main.js diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..7bfe221 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,26 @@ +var gulp = require('gulp'); +var eslint = require('gulp-eslint'); +var babel = require('gulp-babel'); + +var allSources = ['**/*.js', '!node_modules/**', '!gulpfile.js', '!build/**']; + +gulp.task('default', function lint() { + console.log('Possible commands:'); + console.log('\tgulp lint - checks code with eslint'); + console.log('\tgulp build - compiles es6 JavaScript code to es5 standard,'); +}); + +gulp.task('build', function build() { + return gulp.src(allSources) + .pipe(babel({ + presets: ['es2015'], + })) + .pipe(gulp.dest('build')); +}); + +gulp.task('lint', function lint() { + return gulp.src(allSources) + .pipe(eslint()) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..2cc0f0b --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "see-stats-rtm-api", + "version": "0.1.0", + "description": "SeeStats Real Time Messaging API", + "main": "src/main.js", + "dependencies": { + "elasticsearch": "^10.1.3", + "gulp": "^3.9.1", + "moment": "^2.11.2", + "socket.io": "^1.4.5" + }, + "devDependencies": { + "gulp-babel": "^6.1.2", + "gulp-eslint": "^2.0.0", + "babel": "^6.5.1", + "babel-preset-es2015": "^6.5.0", + "eslint": "1.10.3", + "eslint-config-airbnb": "5.0.0" + } +} diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..f318611 --- /dev/null +++ b/src/main.js @@ -0,0 +1,21 @@ +const rtm = require('./rtm.js'); +const stats = require('./stats.js'); + +const io = require('socket.io')(); + +/** + * Main entry point. + */ +function main () { + var statsClient = new stats.Client(); + statsClient.connect('https://es.seestats.org'); + + io.on('connection', (socket) => { + socket.on('get_event_count', (data) => { + statsClient.startFetchingStats(socket); + }); + }); + io.listen(3000); +} + +main() diff --git a/src/stats.js b/src/stats.js new file mode 100644 index 0000000..204eee1 --- /dev/null +++ b/src/stats.js @@ -0,0 +1,72 @@ +/** + * Facilities to fetch stats data from Elasticsearch. + */ + +'use strict'; + +const es = require('elasticsearch'); +const moment = require('moment'); + +function makeIndexName() { + const today = moment(Date.now()).format('YYYY.MM.DD'); + + return 'see-stats-' + today; +} + +function makeCountFilters() { + return { + index: makeIndexName(), + body: { + 'query': { + 'bool': { + 'must': [{ + 'range': { + '@timestamp': { + 'from': 'now-1s/s', + 'to': 'now' + } + } + }] + } + } + } + } +} + +class Client { + + constructor() { + this.esConn = null; + } + + connect(host) { + this.esConn = new es.Client({host: host}); + } + + /** + * Fetches for new stats data every second. + */ + startFetchingStats(socket) { + console.log('Start fetching'); + + setInterval(() => {this.fetchCount(socket);}, 1000); + } + + fetchCount(socket) { + this.esConn.count(makeCountFilters(), (err, resp) => { + if (err) { + console.log('Failed to fetch count:', err); + return; + }; + + socket.emit('event_count', resp.count); + }); + } +}; + +exports.Client = Client; + + +exports.fetch = function () { + console.log('fetch stats'); +};