commit 7693dfda07406a0f16b0525bbc216dcedec7eb7b Author: Muthu Kumar Date: Wed Feb 21 09:52:39 2018 +0530 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c4d74b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +client.html \ No newline at end of file diff --git a/config.js b/config.js new file mode 100644 index 0000000..bf09972 --- /dev/null +++ b/config.js @@ -0,0 +1,4 @@ +module.exports = { + host: "localhost:5000", + dashboardEndpoint: "/dashboard" +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..145239f --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "breeze-analytics", + "version": "0.0.1", + "description": "Web analytics like a breeze", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/codefeathers/breeze-analytics.git" + }, + "keywords": [ + "breeze", + "analytics", + "website", + "monitoring" + ], + "author": "Muthu Kumar (https://mkr.pw)", + "license": "MIT", + "bugs": { + "url": "https://github.com/codefeathers/breeze-analytics/issues" + }, + "homepage": "https://github.com/codefeathers/breeze-analytics#readme" +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..a6c7839 --- /dev/null +++ b/server.js @@ -0,0 +1,106 @@ +// require Express and Socket.io +var express = require('express'); +var app = express(); +var http = require('http').Server(app); +var io = require('socket.io')(http); +var path = require('path'); +var config = require('./config.js'); + +// the object that will hold information about the active users currently +// on the site +var visitorsData = {}; + +app.set('port', (process.env.PORT || 5000)); + +// serve the static assets (js/dashboard.js and css/dashboard.css) +// from the public/ directory +app.use(express.static(path.join(__dirname, 'public/'))); + +// serve the index.html page when someone visits any of the following endpoints: +// 1. / +// 2. /about +// 3. /contact +app.get(/\/(about|contact)?$/, function (req, res) { + res.sendFile(path.join(__dirname, 'views/index.html')); +}); + +// serve up the dashboard when someone visits /dashboard +app.get('/dashboard', function (req, res) { + res.sendFile(path.join(__dirname, 'views/dashboard.html')); +}); + +io.on('connection', function (socket) { + if (socket.handshake.headers.host === config.host && + socket.handshake.headers.referer.indexOf(config.host + config.dashboardEndpoint) > -1) { + + // if someone visits '/dashboard' send them the computed visitor data + io.emit('updated-stats', computeStats()); + + } + + // a user has visited our page - add them to the visitorsData object + socket.on('visitor-data', function (data) { + visitorsData[socket.id] = data; + + // compute and send visitor data to the dashboard when a new user visits our page + io.emit('updated-stats', computeStats()); + }); + + socket.on('disconnect', function () { + // a user has left our page - remove them from the visitorsData object + delete visitorsData[socket.id]; + + // compute and send visitor data to the dashboard when a user leaves our page + io.emit('updated-stats', computeStats()); + }); +}); + +// wrapper function to compute the stats and return a object with the updated stats +function computeStats() { + return { + pages: computePageCounts(), + referrers: computeRefererCounts(), + activeUsers: getActiveUsers() + }; +} + +// get the total number of users on each page of our site +function computePageCounts() { + // sample data in pageCounts object: + // { "/": 13, "/about": 5 } + var pageCounts = {}; + for (var key in visitorsData) { + var page = visitorsData[key].page; + if (page in pageCounts) { + pageCounts[page]++; + } else { + pageCounts[page] = 1; + } + } + return pageCounts; +} + +// get the total number of users per referring site +function computeRefererCounts() { + // sample data in referrerCounts object: + // { "http://twitter.com/": 3, "http://stackoverflow.com/": 6 } + var referrerCounts = {}; + for (var key in visitorsData) { + var referringSite = visitorsData[key].referringSite || '(direct)'; + if (referringSite in referrerCounts) { + referrerCounts[referringSite]++; + } else { + referrerCounts[referringSite] = 1; + } + } + return referrerCounts; +} + +// get the total active users on our site +function getActiveUsers() { + return Object.keys(visitorsData).length; +} + +http.listen(app.get('port'), function () { + console.log('listening on *:' + app.get('port')); +}); \ No newline at end of file diff --git a/views/dashboard.html b/views/dashboard.html new file mode 100644 index 0000000..176cf6c --- /dev/null +++ b/views/dashboard.html @@ -0,0 +1,80 @@ + + + + + + + + Breeze Analytics Dashboard + + + + + + + +
+
+
+
+
+

{{ activeUsers }} + +

+

Active Users

+
+
+ +
+

Active Pages

+
+ + + + + + + + + + + +
Page URLActive Users
{{ page }}{{ count }}
+
+ +

Referrals

+
+ + + + + + + + + + + +
Referring SiteActive Users
{{ referringSite }}{{ count }}
+
+ +
+ +
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/views/index.html b/views/index.html new file mode 100644 index 0000000..b552dd1 --- /dev/null +++ b/views/index.html @@ -0,0 +1,2 @@ +

Breeze Analytics Server

+Github \ No newline at end of file diff --git a/views/js/dashboard.js b/views/js/dashboard.js new file mode 100644 index 0000000..6dc3899 --- /dev/null +++ b/views/js/dashboard.js @@ -0,0 +1,17 @@ +var socket = io(); + +var vm = new Vue({ + el: '#app', + data: { + pages: {}, + referrers: {}, + activeUsers: 0 + }, + created: function () { + socket.on('updated-stats', function (data) { + this.pages = data.pages; + this.referrers = data.referrers; + this.activeUsers = data.activeUsers; + }.bind(this)); + } +}); \ No newline at end of file