From 0ca6adac5f4d0fcca7dc9cfe081adfe0cd30f405 Mon Sep 17 00:00:00 2001 From: Darren Date: Sun, 27 Jul 2014 13:49:19 +0100 Subject: [PATCH] Server stats/events module --- server/client.js | 14 +++++++++++++- server/httphandler.js | 7 ++++++- server/irc/connection.js | 6 ++++++ server/irc/server.js | 4 +++- server/stats.js | 5 +++++ server/weblistener.js | 7 ++++++- server/websocketrpc.js | 1 + server_modules/stats.js | 30 ++++++++++++++++++++++++++++++ 8 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 server/stats.js create mode 100644 server_modules/stats.js diff --git a/server/client.js b/server/client.js index 5f4b665..73a0cb2 100755 --- a/server/client.js +++ b/server/client.js @@ -5,15 +5,25 @@ var util = require('util'), State = require('./irc/state.js'), IrcConnection = require('./irc/connection.js').IrcConnection, ClientCommands = require('./clientcommands.js'), - WebsocketRpc = require('./websocketrpc.js'); + WebsocketRpc = require('./websocketrpc.js'), + Stats = require('./stats.js'); var Client = function (websocket) { var that = this; + Stats.incr('client.created'); + events.EventEmitter.call(this); this.websocket = websocket; + this.rpc = new WebsocketRpc(this.websocket); + this.rpc.on('all', function(func_name, return_fn) { + if (typeof func_name === 'string' && typeof return_fn === 'function') { + Stats.incr('client.command'); + Stats.incr('client.command.' + func_name); + } + }); // Clients address this.real_address = this.websocket.meta.real_address; @@ -72,6 +82,8 @@ Client.prototype.sendKiwiCommand = function (command, data, callback) { }; Client.prototype.dispose = function () { + Stats.incr('client.disposed'); + this.disposed = true; this.rpc.dispose(); this.emit('dispose'); diff --git a/server/httphandler.js b/server/httphandler.js index 3049972..c3fc067 100644 --- a/server/httphandler.js +++ b/server/httphandler.js @@ -5,7 +5,8 @@ var url = require('url'), _ = require('lodash'), config = require('./configuration.js'), winston = require('winston'), - SettingsGenerator = require('./settingsgenerator.js'); + SettingsGenerator = require('./settingsgenerator.js'), + Stats = require('./stats.js'); @@ -39,6 +40,10 @@ HttpHandler.prototype.serve = function (request, response) { request.url = '/index.html'; } + if (request.url === '/index.html') { + Stats.incr('http.homepage'); + } + // If the 'magic' translation is requested, figure out the best language to use from // the Accept-Language HTTP header. If nothing is suitible, fallback to our en-gb default translation if (request.url.substr(0, 16) === '/assets/locales/') { diff --git a/server/irc/connection.js b/server/irc/connection.js index 8b8e197..3242452 100644 --- a/server/irc/connection.js +++ b/server/irc/connection.js @@ -12,6 +12,7 @@ var net = require('net'), EE = require('../ee.js'), iconv = require('iconv-lite'), Proxy = require('../proxy.js'), + Stats = require('../stats.js'), Socks; @@ -32,6 +33,8 @@ var IrcConnection = function (hostname, port, ssl, nick, user, options, state, c }); this.setMaxListeners(0); + Stats.incr('irc.connection.created'); + options = options || {}; // Socket state @@ -281,6 +284,7 @@ IrcConnection.prototype.connect = function () { rawSocketConnect.call(that, this); } + Stats.incr('irc.connection.connected'); that.connected = true; socketConnectHandler.call(that); @@ -321,9 +325,11 @@ IrcConnection.prototype.connect = function () { } if (should_reconnect) { + Stats.incr('irc.connection.reconnect'); that.reconnect_attempts++; that.emit('reconnecting'); } else { + Stats.incr('irc.connection.closed'); that.emit('close', had_error); that.reconnect_attempts = 0; } diff --git a/server/irc/server.js b/server/irc/server.js index 831e9bf..42e32df 100755 --- a/server/irc/server.js +++ b/server/irc/server.js @@ -1,6 +1,7 @@ var util = require('util'), EventBinder = require('./eventbinder.js'), - _ = require('lodash'); + _ = require('lodash'), + Stats = require('../stats.js'); var IrcServer = function (irc_connection) { this.irc_connection = irc_connection; @@ -61,6 +62,7 @@ IrcServer.prototype.reset = function() { function onConnect(event) { + Stats.incr('irc.connection.registered'); this.registered = new Date(); this.irc_connection.clientEvent('connect', { diff --git a/server/stats.js b/server/stats.js new file mode 100644 index 0000000..2898482 --- /dev/null +++ b/server/stats.js @@ -0,0 +1,5 @@ +module.exports = { + incr: function incr(stat_name) { + global.modules.emit('stat counter', {name: stat_name}); + } +}; \ No newline at end of file diff --git a/server/weblistener.js b/server/weblistener.js index fcaeb7c..475f017 100644 --- a/server/weblistener.js +++ b/server/weblistener.js @@ -13,7 +13,8 @@ var engine = require('engine.io'), winston = require('winston'), Client = require('./client.js').Client, HttpHandler = require('./httphandler.js').HttpHandler, - rehash = require('./rehash.js'); + rehash = require('./rehash.js'), + Stats = require('./stats.js'); @@ -86,6 +87,8 @@ var WebListener = module.exports = function (web_config) { hs.on('request', function(req, res){ var transport_url = (global.config.http_base_path || '') + '/transport'; + Stats.incr('http.request'); + // engine.io can sometimes "loose" the clients remote address. Keep note of it req.meta = { remote_address: req.connection.remoteAddress @@ -102,6 +105,8 @@ var WebListener = module.exports = function (web_config) { }); this.ws.on('connection', function(socket) { + Stats.incr('http.websocket'); + initialiseSocket(socket, function(err, authorised) { var client; diff --git a/server/websocketrpc.js b/server/websocketrpc.js index 1fa035a..5f7c56e 100644 --- a/server/websocketrpc.js +++ b/server/websocketrpc.js @@ -152,6 +152,7 @@ WebsocketRpc.prototype._onMessage = function(message_raw) { returnFn = this._noop; } + this.emit.apply(this, ['all', packet.method, returnFn].concat(packet.params)); this.emit.apply(this, [packet.method, returnFn].concat(packet.params)); } }; diff --git a/server_modules/stats.js b/server_modules/stats.js new file mode 100644 index 0000000..b91eb33 --- /dev/null +++ b/server_modules/stats.js @@ -0,0 +1,30 @@ +/** + * Stats counter + * + * Retreive stats for internal kiwi events. Handy for graphing + */ + +var kiwiModules = require('../server/modules'), + fs = require('fs'); + + + +var module = new kiwiModules.Module('stats_file'); + +module.on('stat counter', function (event, event_data) { + var stat_name = event_data.name, + stats_file, timestamp, + ignored_events = []; + + // Some events may want to be ignored + ignored_events.push('http.request'); + + if (ignored_events.indexOf(stat_name) > -1) { + return; + } + + timestamp = Math.floor((new Date()).getTime() / 1000); + + stats_file = fs.createWriteStream('kiwi_stats.log', {'flags': 'a'}); + stats_file.write(timestamp.toString() + ' ' + stat_name + '\n'); +}); \ No newline at end of file -- 2.25.1