Skip to content

Commit

Permalink
Update sample config; add customization notes to the readme, simplify…
Browse files Browse the repository at this point in the history
… sales view
  • Loading branch information
mnutt committed Oct 27, 2010
1 parent ac8a6eb commit 21876e3
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 42 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,37 @@ config/app.json. The dashboard is just html served out of public/; you can serv
any webserver.


Architecture Overview
---------------------

Hummingbird is organized into two parts: a node.js-based tracking server that records user
activity via a tracking pixel, and a collection of javascript-based widgets that display that
activity. The server records all activity in MongoDB and broadcasts it to the clients using
WebSockets if possible, and falling back to Flash sockets if necessary.

The Hummingbird.WebSocket object receives websocket events from the server in the form of JSON
objects. Individual widgets subscribe to a property in the JSON tree and register handler
functions to be called whenever that property is present.


Logging Customization
---------------------

Metrics are stored in lib/metrics and auto-loaded.. Each metric contains a handler function that is
called every time a new user event occurs. Metrics store data in the `data` object property which
gets emitted to clients in intervals specified by the metric. A basic example can be found in
lib/metrics/all.js. An example of how a metric can filter based on urls is in lib/metric/sales.js.


Display Customization
---------------------

Hummingbird comes with some stock widgets (Counter, Logger, Graph) that demonstrate how to hook into
the data provided by the node.js server. For the minimum amount required to create a widget, see
public/js/widgets/logger.js. A widget is an object whose prototype extends Hummingbird.Base and
implements onMessage.


Specs
--------

Expand Down
5 changes: 2 additions & 3 deletions config/app.json.sample
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
{
"name" : "Hummingbird",

"monitor_port" : 8888,
"tracking_port" : 8000,
"dashboard_port" : 8080,

"username" : "admin",
"password" : "change_this",
"enable_dashboard" : true,

"capistrano" : {
"repository" : "git://github.com/mnutt/hummingbird.git",
Expand Down
4 changes: 2 additions & 2 deletions lib/hummingbird.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ Hummingbird.prototype = {

var view = new View(env);

env.url_key = view.urlKey();
env.product_id = view.productId();
env.url_key = view.urlKey;
env.product_id = view.productId;

this.collection.insertAll([env]);

Expand Down
34 changes: 10 additions & 24 deletions lib/metrics/sales.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,19 @@ var SalesMetric = {
interval: 500, // ms

incrementCallback: function(view) {
if(view.urlKey()) {
this.data.sales[view.urlKey()] = (this.data.sales[view.urlKey()] || 0) + 1;
this.minuteData["sales."+view.urlKey()] = (this.minuteData["sales."+view.urlKey()] || 0) + 1;
}
},

aggregateCallback: function(item) {
item.tmpSales = item.sales;
item.sales = [];
for(sale in item.tmpSales) {
if(item.tmpSales[sale] > 10) {
item.sales.push({ url_key: sale,
views: item.tmpSales[sale] });
if(view.env.u) {
var match = view.env.u.match(/^http:\/\/[^\/]+(\/s\/|\/sale\/splash\/|\/city\/offers?\/)([^\/\?\#]+)\/?(product\/)?(\d+)?/);
if(match && match.length > 2) {
view.urlKey = match[2];
view.productId = match[4];
}
}
delete item.tmpSales;

// Sort by sale numbers descending
item.sales = item.sales.sort(function(a, b) {
if(a.views == b.views) {
return 0;
} else if(a.views > b.views) {
return -1;
} else { return 1; }
});
}

if(view.urlKey) {
this.data.sales[view.urlKey] = (this.data.sales[view.urlKey] || 0) + 1;
this.minuteData["sales."+view.urlKey] = (this.minuteData["sales."+view.urlKey] || 0) + 1;
}
},
};

for (var i in SalesMetric)
Expand Down
13 changes: 0 additions & 13 deletions lib/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,9 @@ var View = function(env) {

this.env = env;

if(this.env.u) {
var match = View.urlKeyRegexp.exec(this.env.u);
if(match && match.length > 2) {
this._urlKey = match[2];
this._productId = match[4];
}
}
}

View.prototype = {
urlKey: function() {
return this._urlKey;
},

productId: function() {
return this._productId;
},
Expand All @@ -39,6 +28,4 @@ View.prototype = {
}
};

View.urlKeyRegexp = new RegExp(/^http:\/\/[^\/]+(\/s\/|\/sale\/splash\/|\/city\/offers?\/)([^\/\?\#]+)\/?(product\/)?(\d+)?/);

exports.View = View;

0 comments on commit 21876e3

Please sign in to comment.