bp-fnordmetric 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/Rakefile +6 -0
- data/fnordmetric.gemspec +41 -0
- data/lib/fnordmetric.rb +149 -0
- data/lib/fnordmetric/acceptors/acceptor.rb +42 -0
- data/lib/fnordmetric/acceptors/amqp_acceptor.rb +56 -0
- data/lib/fnordmetric/acceptors/fyrehose_acceptor.rb +43 -0
- data/lib/fnordmetric/acceptors/stomp_acceptor.rb +71 -0
- data/lib/fnordmetric/acceptors/tcp_acceptor.rb +58 -0
- data/lib/fnordmetric/acceptors/udp_acceptor.rb +37 -0
- data/lib/fnordmetric/api.rb +46 -0
- data/lib/fnordmetric/cache.rb +20 -0
- data/lib/fnordmetric/context.rb +96 -0
- data/lib/fnordmetric/defaults.rb +22 -0
- data/lib/fnordmetric/enterprise/compatibility_handler.rb +42 -0
- data/lib/fnordmetric/ext.rb +75 -0
- data/lib/fnordmetric/gauge.rb +98 -0
- data/lib/fnordmetric/gauge_calculations.rb +106 -0
- data/lib/fnordmetric/gauge_modifiers.rb +144 -0
- data/lib/fnordmetric/gauge_rendering.rb +40 -0
- data/lib/fnordmetric/gauge_validations.rb +15 -0
- data/lib/fnordmetric/gauges/distribution_gauge.rb +87 -0
- data/lib/fnordmetric/gauges/server_health_gauge.rb +13 -0
- data/lib/fnordmetric/gauges/timeseries_gauge.rb +138 -0
- data/lib/fnordmetric/gauges/toplist_gauge.rb +44 -0
- data/lib/fnordmetric/histogram.rb +64 -0
- data/lib/fnordmetric/logger.rb +63 -0
- data/lib/fnordmetric/namespace.rb +208 -0
- data/lib/fnordmetric/session.rb +139 -0
- data/lib/fnordmetric/standalone.rb +20 -0
- data/lib/fnordmetric/timeseries.rb +79 -0
- data/lib/fnordmetric/toplist.rb +61 -0
- data/lib/fnordmetric/udp_client.rb +22 -0
- data/lib/fnordmetric/util.rb +25 -0
- data/lib/fnordmetric/version.rb +3 -0
- data/lib/fnordmetric/web/app.rb +63 -0
- data/lib/fnordmetric/web/app_helpers.rb +42 -0
- data/lib/fnordmetric/web/dashboard.rb +40 -0
- data/lib/fnordmetric/web/event.rb +99 -0
- data/lib/fnordmetric/web/reactor.rb +127 -0
- data/lib/fnordmetric/web/web.rb +59 -0
- data/lib/fnordmetric/web/websocket.rb +41 -0
- data/lib/fnordmetric/widget.rb +82 -0
- data/lib/fnordmetric/widgets/bars_widget.rb +44 -0
- data/lib/fnordmetric/widgets/html_widget.rb +28 -0
- data/lib/fnordmetric/widgets/numbers_widget.rb +80 -0
- data/lib/fnordmetric/widgets/pie_widget.rb +23 -0
- data/lib/fnordmetric/widgets/timeseries_widget.rb +65 -0
- data/lib/fnordmetric/widgets/toplist_widget.rb +68 -0
- data/lib/fnordmetric/worker.rb +89 -0
- data/lib/fnordmetric/zero_config_gauge.rb +138 -0
- data/run_specs.sh +11 -0
- data/spec/api_spec.rb +49 -0
- data/spec/context_spec.rb +42 -0
- data/spec/dashboard_spec.rb +38 -0
- data/spec/event_spec.rb +170 -0
- data/spec/ext_spec.rb +14 -0
- data/spec/fnordmetric_spec.rb +56 -0
- data/spec/gauge_like_shared.rb +56 -0
- data/spec/gauge_modifiers_spec.rb +583 -0
- data/spec/gauge_spec.rb +230 -0
- data/spec/namespace_spec.rb +114 -0
- data/spec/session_spec.rb +231 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/tcp_acceptor_spec.rb +35 -0
- data/spec/timeseries_gauge_spec.rb +56 -0
- data/spec/udp_acceptor_spec.rb +35 -0
- data/spec/util_spec.rb +46 -0
- data/spec/widget_spec.rb +113 -0
- data/spec/worker_spec.rb +40 -0
- data/web/.gitignore +4 -0
- data/web/build.sh +34 -0
- data/web/css/fnordmetric.core.css +868 -0
- data/web/haml/app.haml +20 -0
- data/web/haml/distribution_gauge.haml +118 -0
- data/web/haml/timeseries_gauge.haml +80 -0
- data/web/haml/toplist_gauge.haml +194 -0
- data/web/img/head.png +0 -0
- data/web/img/list.png +0 -0
- data/web/img/list_active.png +0 -0
- data/web/img/list_hover.png +0 -0
- data/web/img/loader.gif +0 -0
- data/web/img/loader_white.gif +0 -0
- data/web/img/navbar.png +0 -0
- data/web/img/navbar_btn.png +0 -0
- data/web/img/picto_gauge.png +0 -0
- data/web/js/fnordmetric.bars_widget.js +178 -0
- data/web/js/fnordmetric.dashboard_view.js +99 -0
- data/web/js/fnordmetric.gauge_explorer.js +173 -0
- data/web/js/fnordmetric.gauge_view.js +260 -0
- data/web/js/fnordmetric.html_widget.js +21 -0
- data/web/js/fnordmetric.js +315 -0
- data/web/js/fnordmetric.numbers_widget.js +122 -0
- data/web/js/fnordmetric.overview_view.js +35 -0
- data/web/js/fnordmetric.pie_widget.js +118 -0
- data/web/js/fnordmetric.realtime_timeline_widget.js +175 -0
- data/web/js/fnordmetric.session_view.js +342 -0
- data/web/js/fnordmetric.timeline_widget.js +333 -0
- data/web/js/fnordmetric.timeseries_widget.js +405 -0
- data/web/js/fnordmetric.toplist_widget.js +119 -0
- data/web/js/fnordmetric.ui.js +91 -0
- data/web/js/fnordmetric.util.js +248 -0
- data/web/vendor/font-awesome/css/font-awesome-ie7.min.css +22 -0
- data/web/vendor/font-awesome/css/font-awesome.css +540 -0
- data/web/vendor/font-awesome/css/font-awesome.min.css +33 -0
- data/web/vendor/font-awesome/font/FontAwesome.otf +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.eot +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.svg +284 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.ttf +0 -0
- data/web/vendor/font-awesome/font/fontawesome-webfont.woff +0 -0
- data/web/vendor/jquery-1.6.2.min.js +18 -0
- data/web/vendor/jquery-ui.min.js +6 -0
- data/web/vendor/jquery.combobox.js +129 -0
- data/web/vendor/jquery.maskedinput.js +252 -0
- metadata +438 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
FnordMetric.views.overviewView = function(){
|
2
|
+
var widgets = [];
|
3
|
+
var viewport = null;
|
4
|
+
|
5
|
+
function load(_viewport){
|
6
|
+
viewport = _viewport.html('');
|
7
|
+
|
8
|
+
viewport.append('<div class="navbar"></div>');
|
9
|
+
viewport.append('<h1>Application Overview</h1>');
|
10
|
+
viewport.append('<h3>Welcome to FnordMetric :)</h3>');
|
11
|
+
|
12
|
+
// $.ajax({
|
13
|
+
// url: FnordMetric.p + '/' + FnordMetric.currentNamespace+'/dashboard/'+dashboard_name,
|
14
|
+
// success: function(resp, status){
|
15
|
+
// var conf = JSON.parse(resp);
|
16
|
+
// renderWidgets(conf.widgets);
|
17
|
+
// }
|
18
|
+
// });
|
19
|
+
};
|
20
|
+
|
21
|
+
function resize(){
|
22
|
+
// here be dragons
|
23
|
+
}
|
24
|
+
|
25
|
+
function close(){
|
26
|
+
// here be dragons
|
27
|
+
}
|
28
|
+
|
29
|
+
return {
|
30
|
+
load: load,
|
31
|
+
resize: resize,
|
32
|
+
close: close
|
33
|
+
};
|
34
|
+
|
35
|
+
};
|
@@ -0,0 +1,118 @@
|
|
1
|
+
FnordMetric.widgets.pieWidget = function(){
|
2
|
+
|
3
|
+
function render(opts){
|
4
|
+
|
5
|
+
return drawLayout();
|
6
|
+
|
7
|
+
var widget_uid = FnordMetric.util.getNextWidgetUID();
|
8
|
+
var chart=false;
|
9
|
+
|
10
|
+
function redraw(first_time, silent){
|
11
|
+
if(!silent){ $(opts.elem).css('opacity', 0.5); }
|
12
|
+
var gauge_values = {};
|
13
|
+
var gauges_left = opts.gauges.length;
|
14
|
+
var at = parseInt(new Date().getTime()/1000);
|
15
|
+
$(opts.gauges).each(function(i,gauge){
|
16
|
+
$.ajax({
|
17
|
+
url: FnordMetric.p + '/' + FnordMetric.currentNamespace+'/gauge/'+gauge+'?at='+at,
|
18
|
+
success: function(_resp){
|
19
|
+
var resp = JSON.parse(_resp);
|
20
|
+
gauges_left -= 1;
|
21
|
+
for(_tk in resp){
|
22
|
+
gauge_values[gauge] = parseInt(resp[_tk]||0);
|
23
|
+
}
|
24
|
+
if(gauges_left==0){
|
25
|
+
redrawChart(first_time, gauge_values);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
});
|
29
|
+
});
|
30
|
+
}
|
31
|
+
|
32
|
+
function redrawChart(first_time, gauge_values){
|
33
|
+
|
34
|
+
var series_data = [];
|
35
|
+
|
36
|
+
for(_gkey in gauge_values){
|
37
|
+
series_data.push([
|
38
|
+
opts.gauge_titles[_gkey],
|
39
|
+
gauge_values[_gkey]
|
40
|
+
]);
|
41
|
+
}
|
42
|
+
|
43
|
+
/*chart = new Highcharts.Chart({
|
44
|
+
chart: {
|
45
|
+
renderTo: 'container-'+widget_uid,
|
46
|
+
defaultSeriesType: 'pie',
|
47
|
+
height: 270,
|
48
|
+
spacingTop: 5,
|
49
|
+
spacingBottom: 30
|
50
|
+
},
|
51
|
+
credits: {
|
52
|
+
enabled: false
|
53
|
+
},
|
54
|
+
title: { text: '' },
|
55
|
+
legend: {
|
56
|
+
layout: 'horizontal',
|
57
|
+
align: 'top',
|
58
|
+
verticalAlign: 'top',
|
59
|
+
margin: 25,
|
60
|
+
borderWidth: 0
|
61
|
+
},
|
62
|
+
tooltip: {
|
63
|
+
formatter: function() {
|
64
|
+
return '<b>'+ this.point.name +'</b>: '+ this.y + ' (' + this.percentage.toFixed(1) + '%)';
|
65
|
+
}
|
66
|
+
},
|
67
|
+
plotOptions: {
|
68
|
+
pie: {
|
69
|
+
animation: first_time,
|
70
|
+
dataLabels: {
|
71
|
+
formatter: function() {
|
72
|
+
return '<b>'+ this.point.name +'</b><br />'+ this.percentage.toFixed(1) +' %';
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
},
|
77
|
+
series: [
|
78
|
+
{
|
79
|
+
name: opts.title,
|
80
|
+
data: series_data
|
81
|
+
}
|
82
|
+
]
|
83
|
+
});*/
|
84
|
+
|
85
|
+
//chart.redraw();
|
86
|
+
$(opts.elem).css('opacity', 1);
|
87
|
+
}
|
88
|
+
|
89
|
+
function drawLayout(){
|
90
|
+
$(opts.elem).append( $('<div></div>').attr('class', 'headbar small').append(
|
91
|
+
$('<span></span>').html(opts.title)
|
92
|
+
) ).append(
|
93
|
+
$('<div></div>').attr('id', 'container-'+widget_uid).css({
|
94
|
+
height: 270
|
95
|
+
})
|
96
|
+
);
|
97
|
+
}
|
98
|
+
|
99
|
+
drawLayout();
|
100
|
+
redraw(true);
|
101
|
+
|
102
|
+
if(opts.autoupdate){
|
103
|
+
var autoupdate_interval = window.setInterval(function(){
|
104
|
+
redraw(false, true);
|
105
|
+
}, opts.autoupdate*1000);
|
106
|
+
|
107
|
+
$('body').bind('fm_dashboard_close', function(){
|
108
|
+
window.clearInterval(autoupdate_interval);
|
109
|
+
});
|
110
|
+
}
|
111
|
+
|
112
|
+
}
|
113
|
+
|
114
|
+
return {
|
115
|
+
render: render
|
116
|
+
};
|
117
|
+
|
118
|
+
};
|
@@ -0,0 +1,175 @@
|
|
1
|
+
FnordMetric.widgets.realtimeValueWidget = function(){
|
2
|
+
|
3
|
+
var xpadding = 20;
|
4
|
+
var ypadding = 10;
|
5
|
+
var bmargin = 6;
|
6
|
+
var bwidth = 5;
|
7
|
+
var bcolor = '#06C';
|
8
|
+
var zero_height = 5;
|
9
|
+
|
10
|
+
|
11
|
+
var widget_uid = FnordMetric.util.getNextWidgetUID();
|
12
|
+
var width, height, canvas, opts, max;
|
13
|
+
var bars = [];
|
14
|
+
var tick = false;
|
15
|
+
var next_values = [];
|
16
|
+
var next_value_interval = false;
|
17
|
+
|
18
|
+
|
19
|
+
function render(_opts){
|
20
|
+
opts = _opts;
|
21
|
+
|
22
|
+
drawLayout();
|
23
|
+
|
24
|
+
width = opts.elem.width() - (xpadding * 2) - 15 - 250;
|
25
|
+
height = opts.height || 210;
|
26
|
+
//xtick = width / (xticks - 1);
|
27
|
+
|
28
|
+
canvas = d3.select('#container-'+widget_uid)
|
29
|
+
.append("svg:svg")
|
30
|
+
.attr("width", width+(2*xpadding))
|
31
|
+
.attr("height", height);
|
32
|
+
|
33
|
+
canvas.selectAll("*").remove();
|
34
|
+
|
35
|
+
changeTick(opts.ticks[0]);
|
36
|
+
}
|
37
|
+
|
38
|
+
function changeTick(_tick){
|
39
|
+
tick = _tick;
|
40
|
+
canvas.selectAll('.valuebar').remove();
|
41
|
+
next_values = [];
|
42
|
+
max = 1;
|
43
|
+
|
44
|
+
for(var n=parseInt(width / bmargin); n > 0; n--){
|
45
|
+
drawValue(0, n-1);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
function nextValue(value){
|
50
|
+
if (value > max){
|
51
|
+
var old_max = max;
|
52
|
+
max = value * 1.2;
|
53
|
+
canvas.selectAll('.valuebar').each(function(){
|
54
|
+
var theight = parseInt($(this).attr('height'))*(old_max/max);
|
55
|
+
if(theight < zero_height){ theight = zero_height; }
|
56
|
+
$(this).attr("y", height-(ypadding*2)-theight)
|
57
|
+
$(this).attr("height", theight);
|
58
|
+
});
|
59
|
+
}
|
60
|
+
|
61
|
+
drawValue(value);
|
62
|
+
|
63
|
+
canvas.selectAll('.valuebar').each(function(){
|
64
|
+
var new_x = parseInt($(this).attr('x'))-bmargin;
|
65
|
+
if(new_x < 5){ new_x = 5; }
|
66
|
+
$(this).attr("x", new_x);
|
67
|
+
});
|
68
|
+
|
69
|
+
pruneValues();
|
70
|
+
next_value_interval = false;
|
71
|
+
nextValueAsync();
|
72
|
+
}
|
73
|
+
|
74
|
+
function nextValueAsync(value){
|
75
|
+
if(value != undefined){
|
76
|
+
next_values.unshift(value);
|
77
|
+
$('.big_number .value', opts.elem).html(FnordMetric.util.formatValue(value));
|
78
|
+
}
|
79
|
+
if(next_values.length > 0){
|
80
|
+
if(!next_value_interval){
|
81
|
+
next_value_interval = window.setInterval(function(){
|
82
|
+
var _v = next_values.pop();
|
83
|
+
if(_v != undefined){ nextValue(_v); }
|
84
|
+
}, 20);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
function pruneValues(){
|
90
|
+
while(bars.length > (width / bmargin)){
|
91
|
+
bars.pop().remove();
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
function drawValue(value, offset){
|
96
|
+
if(!offset){ offset = 0; }
|
97
|
+
if(!value){ value = 0; }
|
98
|
+
|
99
|
+
if(value > 0){
|
100
|
+
var theight = (height-(ypadding*4)) * (value/max);
|
101
|
+
var fillc = bcolor;
|
102
|
+
} else {
|
103
|
+
var theight = zero_height;
|
104
|
+
var fillc = '#ddd';
|
105
|
+
}
|
106
|
+
|
107
|
+
if(theight < zero_height){
|
108
|
+
theight = zero_height;
|
109
|
+
}
|
110
|
+
|
111
|
+
bars.unshift(canvas
|
112
|
+
.append("svg:rect")
|
113
|
+
.attr("class", "valuebar")
|
114
|
+
.attr("x", width+xpadding-(offset*bmargin))
|
115
|
+
.attr("y", height-(ypadding*2)-theight)
|
116
|
+
.attr("fill", fillc)
|
117
|
+
.attr("width", bwidth)
|
118
|
+
.attr("height", theight));
|
119
|
+
|
120
|
+
}
|
121
|
+
|
122
|
+
function announce(evt){
|
123
|
+
if((evt._class == "widget_push") && (evt.cmd == "value")){
|
124
|
+
if(evt.values[tick]){
|
125
|
+
nextValueAsync(parseFloat(evt.values[tick]));
|
126
|
+
} else {
|
127
|
+
nextValueAsync(0);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
function drawLayout(){
|
133
|
+
if(!opts.no_headbar){
|
134
|
+
$(opts.elem).append( $('<div></div>').attr('class', 'headbar').append(
|
135
|
+
$('<h2></h2>').html(opts.title)
|
136
|
+
));
|
137
|
+
}
|
138
|
+
|
139
|
+
$(opts.elem).append(
|
140
|
+
$('<div></div>').attr('id', 'container-'+widget_uid).css({
|
141
|
+
height: opts.height + 6,
|
142
|
+
marginBottom: 20,
|
143
|
+
overflow: 'hidden'
|
144
|
+
}).append(
|
145
|
+
$('<div></div>')
|
146
|
+
.addClass('big_number number')
|
147
|
+
.attr('data-current', 0)
|
148
|
+
.attr('data', 0)
|
149
|
+
.append($('<span class="desc">').html(opts.desc))
|
150
|
+
.append($('<span class="value">'))
|
151
|
+
)
|
152
|
+
);
|
153
|
+
|
154
|
+
if(opts.ticks){
|
155
|
+
$('.headbar', opts.elem).append('<div class="tick_btns btn_group" style="margin-right:17px;"></div>');
|
156
|
+
for(__tick in opts.ticks){
|
157
|
+
var _tick = opts.ticks[__tick];
|
158
|
+
$('.tick_btns', opts.elem).append(
|
159
|
+
$('<div></div>').attr('class', 'button tick').append($('<span></span>')
|
160
|
+
.html(FnordMetric.util.formatTimeRange(_tick)))
|
161
|
+
.attr('data-tick', _tick)
|
162
|
+
.click(function(){
|
163
|
+
changeTick($(this).attr('data-tick'));
|
164
|
+
})
|
165
|
+
);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
return {
|
171
|
+
render: render,
|
172
|
+
announce: announce
|
173
|
+
}
|
174
|
+
|
175
|
+
};
|
@@ -0,0 +1,342 @@
|
|
1
|
+
FnordMetric.views.sessionView = (function(){
|
2
|
+
|
3
|
+
var listElem = $('<ul class="session_list"></ul>');
|
4
|
+
var feedInnerElem = $('<ul class="feed_inner"></ul>');
|
5
|
+
var typeListElem = $('<ul class="event_type_list"></ul>');
|
6
|
+
|
7
|
+
var filterElem = $('<div class="events_sidebar"></div>')
|
8
|
+
.append("<div class='headbar small'>Event Types</div>")
|
9
|
+
.append(typeListElem);
|
10
|
+
|
11
|
+
var feedElem = $('<div class="sessions_feed"></div>').append(feedInnerElem);
|
12
|
+
var sideElem = $('<div class="sessions_sidebar"></div>').append(listElem);
|
13
|
+
|
14
|
+
var eventsPolledUntil = false;
|
15
|
+
var eventsFilter = {uncheckedTypes: [], checkedSessions: []};
|
16
|
+
var sessionData = {};
|
17
|
+
var pollRunning = true;
|
18
|
+
var first_poll = true;
|
19
|
+
|
20
|
+
function load(elem){
|
21
|
+
eventsPolledUntil = parseInt(new Date().getTime()/10000);
|
22
|
+
|
23
|
+
elem.html('')
|
24
|
+
.append('<div class="navbar"></div>');
|
25
|
+
|
26
|
+
FnordMetric.ui.navbar($('.navbar', viewport), {
|
27
|
+
breadcrumb: [
|
28
|
+
["Fnord", "/group/fnord"],
|
29
|
+
["Active Users", "/active_users"]
|
30
|
+
],
|
31
|
+
buttons: [
|
32
|
+
["<i class='icon-refresh'></i>Refresh", function(){ }]
|
33
|
+
]
|
34
|
+
});
|
35
|
+
|
36
|
+
elem
|
37
|
+
.append(filterElem.css('marginTop', '47px'))
|
38
|
+
.append(feedElem)
|
39
|
+
.append(sideElem);
|
40
|
+
|
41
|
+
startPoll();
|
42
|
+
loadEventTypes();
|
43
|
+
};
|
44
|
+
|
45
|
+
function resize(_width, _height){
|
46
|
+
$('.sessions_feed').width(_width-452);
|
47
|
+
};
|
48
|
+
|
49
|
+
function startPoll(){
|
50
|
+
(doSessionPoll())();
|
51
|
+
(doEventsPoll())();
|
52
|
+
FnordMetric.views.sessionView.session_poll = window.setInterval(doSessionPoll(), 1000);
|
53
|
+
};
|
54
|
+
|
55
|
+
function stopPoll(){
|
56
|
+
pollRunning = false;
|
57
|
+
window.clearInterval(FnordMetric.views.sessionView.session_poll);
|
58
|
+
}
|
59
|
+
|
60
|
+
function doSessionPoll(){
|
61
|
+
return (function(){
|
62
|
+
/*$.ajax({
|
63
|
+
url: FnordMetric.p + '/' + FnordMetric.currentNamespace+'/sessions',
|
64
|
+
success: callbackSessionPoll()
|
65
|
+
});*/
|
66
|
+
sortSessions();
|
67
|
+
});
|
68
|
+
};
|
69
|
+
|
70
|
+
function loadEventHistory(params){
|
71
|
+
feedInnerElem.html('');
|
72
|
+
/*$.ajax({
|
73
|
+
url: FnordMetric.p + '/' + FnordMetric.currentNamespace+'/events',
|
74
|
+
data: params,
|
75
|
+
success: function(_data, _status){
|
76
|
+
var data = JSON.parse(_data).events;
|
77
|
+
for(var n=data.length; n >= 0; n--){
|
78
|
+
if(data[n]){ renderEvent(data[n]); }
|
79
|
+
}
|
80
|
+
}
|
81
|
+
});*/
|
82
|
+
}
|
83
|
+
|
84
|
+
function callbackSessionPoll(){
|
85
|
+
return (function(_data, _status){
|
86
|
+
$.each(JSON.parse(_data).sessions, function(i,v){
|
87
|
+
updateSession(v);
|
88
|
+
});
|
89
|
+
sortSessions();
|
90
|
+
});
|
91
|
+
};
|
92
|
+
|
93
|
+
function loadEventTypes(data){
|
94
|
+
typeListElem.html('');
|
95
|
+
$(data).each(function(i,v){
|
96
|
+
if((v.length > 0) && (v.slice(0,5)!='_set_')){
|
97
|
+
addEventType(v,v);
|
98
|
+
}
|
99
|
+
});
|
100
|
+
};
|
101
|
+
|
102
|
+
function setCheckboxesCheckedState(types_state, sessions_state) {
|
103
|
+
$('.event_type_list .event_type input').attr('checked', types_state);
|
104
|
+
$('.session_list .session input').attr('checked', sessions_state);
|
105
|
+
}
|
106
|
+
|
107
|
+
function addEventType(type, display){
|
108
|
+
typeListElem.append(
|
109
|
+
$('<li class="event_type"></li>').append(
|
110
|
+
$('<span class="history"></span>').html('history')
|
111
|
+
.click(function(){
|
112
|
+
setCheckboxesCheckedState(true, true);
|
113
|
+
$('input', $(this).parent()).attr('checked', true);
|
114
|
+
updateEventFilter(); loadEventHistory({type: type});
|
115
|
+
})
|
116
|
+
).append(
|
117
|
+
$('<input type="checkbox" />').attr('checked', true)
|
118
|
+
.click(function(){ updateEventFilter(); })
|
119
|
+
).append(
|
120
|
+
$('<span></span>').html(display)
|
121
|
+
).attr('rel', type)
|
122
|
+
);
|
123
|
+
}
|
124
|
+
|
125
|
+
function updateEventFilter(){
|
126
|
+
var _unchecked_types = [];
|
127
|
+
$('ul.event_type_list li.event_type').each(function(i,v){
|
128
|
+
if(!$('input', v).attr('checked')){
|
129
|
+
_unchecked_types.push($(v).attr('rel'));
|
130
|
+
}
|
131
|
+
});
|
132
|
+
eventsFilter.uncheckedTypes = _unchecked_types;
|
133
|
+
|
134
|
+
var _checked_sessions = [];
|
135
|
+
$('ul.session_list li.session').each(function(i,v){
|
136
|
+
if($('input', v).attr('checked')){
|
137
|
+
_checked_sessions.push($(v).data().session);
|
138
|
+
}
|
139
|
+
});
|
140
|
+
eventsFilter.checkedSessions = _checked_sessions;
|
141
|
+
}
|
142
|
+
|
143
|
+
function doEventsPoll(){
|
144
|
+
return (function(){
|
145
|
+
|
146
|
+
/*$.ajax({
|
147
|
+
url: FnordMetric.p + '/' + FnordMetric.currentNamespace+'/events?since='+eventsPolledUntil,
|
148
|
+
success: callbackEventsPoll()
|
149
|
+
});*/
|
150
|
+
|
151
|
+
FnordMetric.publish({
|
152
|
+
"type": "active_users_request",
|
153
|
+
"first_poll": first_poll,
|
154
|
+
"since": eventsPolledUntil
|
155
|
+
});
|
156
|
+
|
157
|
+
first_poll = false;
|
158
|
+
|
159
|
+
});
|
160
|
+
};
|
161
|
+
|
162
|
+
function announce(evt){
|
163
|
+
if (evt.type == "active_users_response"){
|
164
|
+
callbackEventsPoll(evt);
|
165
|
+
$(evt.sessions).each(function(){ updateSession(this); });
|
166
|
+
if(evt.types.length > 0){ loadEventTypes(evt.types); }
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
function callbackEventsPoll(data){
|
171
|
+
var events = data.events;
|
172
|
+
var timeout = 1000;
|
173
|
+
var maxevents = 200;
|
174
|
+
var passesFiltering = function(event_data) {
|
175
|
+
var passes_type_filtering = false;
|
176
|
+
var passes_session_filtering = false;
|
177
|
+
if(eventsFilter.uncheckedTypes.indexOf(event_data._type) == -1) {
|
178
|
+
if(parseInt(v._time)<=eventsPolledUntil) {
|
179
|
+
passes_type_filtering = true;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
if(!passes_type_filtering) return false;
|
183
|
+
|
184
|
+
if(eventsFilter.checkedSessions.length == 0){
|
185
|
+
return true; // No filter set - show all events
|
186
|
+
} else {
|
187
|
+
if(event_data._session_key){
|
188
|
+
if(eventsFilter.checkedSessions.indexOf(event_data._session_key) >= 0){
|
189
|
+
return true; // Filter set and match
|
190
|
+
} else {
|
191
|
+
return false; // Filter set but no match
|
192
|
+
}
|
193
|
+
} else {
|
194
|
+
return false; // Filter set but event is not associated with session
|
195
|
+
}
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
if(events.length > 0){
|
200
|
+
eventsPolledUntil = parseInt(events[0]._time)-1;
|
201
|
+
}
|
202
|
+
for(var n=events.length-1; n >= 0; n--){
|
203
|
+
var v = events[n];
|
204
|
+
if(passesFiltering(v)) {
|
205
|
+
renderEvent(v);
|
206
|
+
}
|
207
|
+
};
|
208
|
+
var elems = $("p", feedInnerElem);
|
209
|
+
for(var n=maxevents; n < elems.length; n++){
|
210
|
+
$(elems[n]).remove();
|
211
|
+
}
|
212
|
+
if(pollRunning){
|
213
|
+
window.setTimeout(doEventsPoll(), timeout);
|
214
|
+
}
|
215
|
+
};
|
216
|
+
|
217
|
+
function updateSession(session_data){
|
218
|
+
var session_key = session_data.session_key;
|
219
|
+
if(!sessionData[session_key]){
|
220
|
+
updateEventFilter()
|
221
|
+
}
|
222
|
+
sessionData[session_key] = session_data;
|
223
|
+
renderSession(session_data);
|
224
|
+
}
|
225
|
+
|
226
|
+
function sortSessions(){
|
227
|
+
}
|
228
|
+
|
229
|
+
function renderSession(session_data){
|
230
|
+
|
231
|
+
var session_name = session_data["_name"];
|
232
|
+
var session_time = FnordMetric.util.formatTimeSince(session_data["_updated_at"]);
|
233
|
+
var session_elem = $('li[data-session='+session_data["session_key"]+']:first');
|
234
|
+
|
235
|
+
if(session_elem.length>0){
|
236
|
+
|
237
|
+
if(session_data["_picture"] && (session_data["_picture"].length > 1)){
|
238
|
+
$('.picture img', session_elem).attr('src', session_data["_picture"])
|
239
|
+
}
|
240
|
+
|
241
|
+
if(session_name){
|
242
|
+
$('.name', session_elem).html(session_name);
|
243
|
+
}
|
244
|
+
|
245
|
+
$('.time', session_elem).html(session_time);
|
246
|
+
|
247
|
+
} else {
|
248
|
+
|
249
|
+
var session_picture = $('<img width="25" />');
|
250
|
+
|
251
|
+
if(!session_name){
|
252
|
+
session_name = session_data["session_key"].substr(0,15)
|
253
|
+
};
|
254
|
+
|
255
|
+
if(session_data["_picture"]){
|
256
|
+
session_picture.attr('src', session_data["_picture"]);
|
257
|
+
};
|
258
|
+
|
259
|
+
listElem.append(
|
260
|
+
$('<li class="session"></li>').append(
|
261
|
+
$('<div class="picture"></div>').html(session_picture)
|
262
|
+
).append(
|
263
|
+
$('<span class="name"></span>').html(session_name)
|
264
|
+
).append(
|
265
|
+
$('<span class="time"></span>').html(session_time)
|
266
|
+
).append(
|
267
|
+
$('<span class="history"></span>').html('history')
|
268
|
+
.click(function(){
|
269
|
+
setCheckboxesCheckedState(true, false);
|
270
|
+
updateEventFilter();
|
271
|
+
loadEventHistory({session_key: session_data["session_key"]});
|
272
|
+
})
|
273
|
+
).attr('data-session', session_data["session_key"])
|
274
|
+
);
|
275
|
+
|
276
|
+
}
|
277
|
+
};
|
278
|
+
|
279
|
+
function renderEvent(event_data){
|
280
|
+
var event_time = $('<span class="time"></span>');
|
281
|
+
var event_message = $('<span class="message"></span>');
|
282
|
+
var event_props = $('<span class="properties"></span>');
|
283
|
+
var event_picture = $('<div class="picture"></picture>');
|
284
|
+
|
285
|
+
var event_type = event_data._type;
|
286
|
+
|
287
|
+
if(!event_type){ return true; }
|
288
|
+
|
289
|
+
if(event_data._message){
|
290
|
+
event_message.html(event_data._message);
|
291
|
+
} else if(event_type=="_pageview"){
|
292
|
+
event_message.html("Pageview: " + event_data.url);
|
293
|
+
} else if(event_type.substr(0,5) == '_set_'){
|
294
|
+
return true; /* dont render */
|
295
|
+
} else {
|
296
|
+
event_message.html(event_type);
|
297
|
+
}
|
298
|
+
|
299
|
+
event_time.html(FnordMetric.util.formatTimeOfDay(event_data._time));
|
300
|
+
|
301
|
+
if(event_data._session_key && event_data._session_key.length > 0){
|
302
|
+
var __session_key = event_data._session_key;
|
303
|
+
var load_usersession = (function(){
|
304
|
+
loadEventHistory({session_key: __session_key});
|
305
|
+
});
|
306
|
+
if(session_data=sessionData[event_data._session_key]){
|
307
|
+
if(session_data._name){
|
308
|
+
event_props.append(
|
309
|
+
$('<strong></strong>').html(session_data._name).css({
|
310
|
+
'cursor': 'pointer'
|
311
|
+
}).click(load_usersession)
|
312
|
+
);
|
313
|
+
}
|
314
|
+
if(session_data._picture){
|
315
|
+
event_picture.append(
|
316
|
+
$('<img width="40" />').attr('src', session_data._picture)
|
317
|
+
).click(load_usersession);
|
318
|
+
}
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
feedInnerElem.prepend(
|
323
|
+
$('<li class="feed_event"></li>')
|
324
|
+
.append(event_time)
|
325
|
+
.append(event_picture)
|
326
|
+
.append(event_message)
|
327
|
+
.append(event_props)
|
328
|
+
);
|
329
|
+
}
|
330
|
+
|
331
|
+
function close(){
|
332
|
+
stopPoll();
|
333
|
+
};
|
334
|
+
|
335
|
+
return {
|
336
|
+
load: load,
|
337
|
+
resize: resize,
|
338
|
+
announce: announce,
|
339
|
+
close: close
|
340
|
+
};
|
341
|
+
|
342
|
+
});
|