Browse Source

Initial commit

master
Muthu Kumar 7 years ago
commit
7693dfda07
  1. 2
      .gitignore
  2. 4
      config.js
  3. 25
      package.json
  4. 106
      server.js
  5. 80
      views/dashboard.html
  6. 2
      views/index.html
  7. 17
      views/js/dashboard.js

2
.gitignore

@ -0,0 +1,2 @@
node_modules
client.html

4
config.js

@ -0,0 +1,4 @@
module.exports = {
host: "localhost:5000",
dashboardEndpoint: "/dashboard"
}

25
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"
}

106
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'));
});

80
views/dashboard.html

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Breeze Analytics Dashboard</title>
<link rel="stylesheet" href="css/dashboard.css">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Breeze Analytics</a>
</div>
</div>
</nav>
<div class="container">
<div id="app">
<div class="row">
<div class="col-xs-3">
<div class="well">
<h1 class="dash-red">{{ activeUsers }}
<i class="glyphicon glyphicon-user"></i>
</h1>
<h3 class="text-muted">Active Users</h3>
</div>
</div>
<div class="col-xs-9">
<h2 class="sub-header">Active Pages</h2>
<div class="table-responsive">
<table class="table">
<thead>
<td>Page URL</td>
<td>Active Users</td>
</thead>
<tbody>
<tr v-for="(page, count) in pages">
<td>{{ page }}</td>
<td>{{ count }}</td>
</tr>
</tbody>
</table>
</div>
<h2 class="sub-header">Referrals</h2>
<div class="table-responsive">
<table class="table">
<thead>
<td>Referring Site</td>
<td>Active Users</td>
</thead>
<tbody>
<tr v-for="(referringSite, count) in referrers">
<td>{{ referringSite }}</td>
<td>{{ count }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.17/vue.js"></script>
<script src="/socket.io/socket.io.js"></script>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>-->
<script src="js/dashboard.js"></script>
</body>
</html>

2
views/index.html

@ -0,0 +1,2 @@
<h1>Breeze Analytics Server</h1>
<a href='https://github.com/codefeathers/breeze-analytics'>Github</a>

17
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));
}
});
Loading…
Cancel
Save