pimon 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +9 -6
- data/Gemfile.lock +39 -21
- data/README.md +4 -20
- data/lib/pimon.rb +0 -1
- data/lib/pimon/probe/uptime.rb +13 -0
- data/lib/pimon/public/index.js +144 -110
- data/lib/pimon/public/piecon.min.js +5 -0
- data/lib/pimon/stats.rb +1 -1
- data/lib/pimon/stats_collector.rb +6 -2
- data/lib/pimon/version.rb +1 -1
- data/lib/pimon/views/index.haml +3 -1
- data/pimon.gemspec +9 -8
- data/spec/spec_helper.rb +8 -8
- data/spec/stats_collector_spec.rb +4 -0
- metadata +28 -14
- data/Capfile +0 -2
- data/config/config_dev.ru +0 -11
- data/config/deploy.rb +0 -43
- data/config/thin/config.yml +0 -13
data/Gemfile
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem '
|
4
|
-
gem '
|
3
|
+
gem 'rake', '~> 10.1.0'
|
4
|
+
gem 'haml', '~> 4.0.3'
|
5
|
+
gem 'sinatra', '~> 1.4.3', :require => 'sinatra/base'
|
5
6
|
gem 'em-websocket', '= 0.3.8'
|
6
7
|
gem 'sinatra-websocket', '~> 0.2.1'
|
7
|
-
gem '
|
8
|
+
gem 'sys-uptime', '~> 0.6.1'
|
9
|
+
gem 'thin', '~> 1.5.1'
|
8
10
|
|
9
|
-
gem 'pry', '~> 0.9.12' , :group => [:development, :test]
|
11
|
+
gem 'pry', '~> 0.9.12.2' , :group => [:development, :test]
|
10
12
|
|
11
13
|
group :test do
|
12
14
|
gem 'rack-test', '~> 0.6.2'
|
13
|
-
gem 'rspec', '~> 2.
|
15
|
+
gem 'rspec', '~> 2.14.1'
|
14
16
|
gem 'simplecov', '~> 0.7.1', :require => false
|
15
17
|
gem 'simplecov-rcov', '~> 0.2.3'
|
16
18
|
gem 'timecop', '~> 0.6.1'
|
19
|
+
gem 'coveralls', '~> 0.6.7', require: false
|
17
20
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,19 +1,28 @@
|
|
1
1
|
GEM
|
2
|
-
remote:
|
2
|
+
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
4
|
addressable (2.3.3)
|
5
5
|
coderay (1.0.9)
|
6
|
+
colorize (0.5.8)
|
7
|
+
coveralls (0.6.7)
|
8
|
+
colorize
|
9
|
+
multi_json (~> 1.3)
|
10
|
+
rest-client
|
11
|
+
simplecov (>= 0.7)
|
12
|
+
thor
|
6
13
|
daemons (1.1.9)
|
7
|
-
diff-lcs (1.2.
|
14
|
+
diff-lcs (1.2.4)
|
8
15
|
em-websocket (0.3.8)
|
9
16
|
addressable (>= 2.1.1)
|
10
17
|
eventmachine (>= 0.12.9)
|
11
18
|
eventmachine (1.0.3)
|
12
|
-
|
19
|
+
ffi (1.4.0)
|
20
|
+
haml (4.0.3)
|
13
21
|
tilt
|
14
22
|
method_source (0.8.1)
|
23
|
+
mime-types (1.23)
|
15
24
|
multi_json (1.6.1)
|
16
|
-
pry (0.9.12)
|
25
|
+
pry (0.9.12.2)
|
17
26
|
coderay (~> 1.0.5)
|
18
27
|
method_source (~> 0.8)
|
19
28
|
slop (~> 3.4)
|
@@ -22,48 +31,57 @@ GEM
|
|
22
31
|
rack
|
23
32
|
rack-test (0.6.2)
|
24
33
|
rack (>= 1.0)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
rake (10.1.0)
|
35
|
+
rest-client (1.6.7)
|
36
|
+
mime-types (>= 1.16)
|
37
|
+
rspec (2.14.1)
|
38
|
+
rspec-core (~> 2.14.0)
|
39
|
+
rspec-expectations (~> 2.14.0)
|
40
|
+
rspec-mocks (~> 2.14.0)
|
41
|
+
rspec-core (2.14.4)
|
42
|
+
rspec-expectations (2.14.0)
|
31
43
|
diff-lcs (>= 1.1.3, < 2.0)
|
32
|
-
rspec-mocks (2.
|
44
|
+
rspec-mocks (2.14.1)
|
33
45
|
simplecov (0.7.1)
|
34
46
|
multi_json (~> 1.0)
|
35
47
|
simplecov-html (~> 0.7.1)
|
36
48
|
simplecov-html (0.7.1)
|
37
49
|
simplecov-rcov (0.2.3)
|
38
50
|
simplecov (>= 0.4.1)
|
39
|
-
sinatra (1.4.
|
40
|
-
rack (~> 1.
|
51
|
+
sinatra (1.4.3)
|
52
|
+
rack (~> 1.4)
|
41
53
|
rack-protection (~> 1.4)
|
42
54
|
tilt (~> 1.3, >= 1.3.4)
|
43
55
|
sinatra-websocket (0.2.1)
|
44
56
|
em-websocket (~> 0.3.6)
|
45
57
|
eventmachine
|
46
58
|
thin (>= 1.3.1)
|
47
|
-
slop (3.4.
|
48
|
-
|
59
|
+
slop (3.4.5)
|
60
|
+
sys-uptime (0.6.1)
|
61
|
+
ffi (>= 1.0.0)
|
62
|
+
thin (1.5.1)
|
49
63
|
daemons (>= 1.0.9)
|
50
64
|
eventmachine (>= 0.12.6)
|
51
65
|
rack (>= 1.0.0)
|
52
|
-
|
66
|
+
thor (0.18.1)
|
67
|
+
tilt (1.4.1)
|
53
68
|
timecop (0.6.1)
|
54
69
|
|
55
70
|
PLATFORMS
|
56
71
|
ruby
|
57
72
|
|
58
73
|
DEPENDENCIES
|
74
|
+
coveralls (~> 0.6.7)
|
59
75
|
em-websocket (= 0.3.8)
|
60
|
-
haml (~> 4.0.
|
61
|
-
pry (~> 0.9.12)
|
76
|
+
haml (~> 4.0.3)
|
77
|
+
pry (~> 0.9.12.2)
|
62
78
|
rack-test (~> 0.6.2)
|
63
|
-
|
79
|
+
rake (~> 10.1.0)
|
80
|
+
rspec (~> 2.14.1)
|
64
81
|
simplecov (~> 0.7.1)
|
65
82
|
simplecov-rcov (~> 0.2.3)
|
66
|
-
sinatra (~> 1.4.
|
83
|
+
sinatra (~> 1.4.3)
|
67
84
|
sinatra-websocket (~> 0.2.1)
|
68
|
-
|
85
|
+
sys-uptime (~> 0.6.1)
|
86
|
+
thin (~> 1.5.1)
|
69
87
|
timecop (~> 0.6.1)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Pimon
|
2
2
|
|
3
|
-
[![Build Status](https://secure.travis-ci.org/pedrocarrico/pimon.png)](http://travis-ci.org/pedrocarrico/pimon) [![Dependency Status](https://gemnasium.com/pedrocarrico/pimon.png?travis)](https://gemnasium.com/pedrocarrico/pimon) [![Gem Version](https://badge.fury.io/rb/pimon.png)](http://badge.fury.io/rb/pimon) [![Code Climate](https://codeclimate.com/
|
3
|
+
[![Build Status](https://secure.travis-ci.org/pedrocarrico/pimon.png)](http://travis-ci.org/pedrocarrico/pimon) [![Dependency Status](https://gemnasium.com/pedrocarrico/pimon.png?travis)](https://gemnasium.com/pedrocarrico/pimon) [![Gem Version](https://badge.fury.io/rb/pimon.png)](http://badge.fury.io/rb/pimon) [![Code Climate](https://codeclimate.com/github/pedrocarrico/pimon.png)](https://codeclimate.com/github/pedrocarrico/pimon) [![Coverage Status](https://coveralls.io/repos/pedrocarrico/pimon/badge.png?branch=master)](https://coveralls.io/r/pedrocarrico/pimon)
|
4
4
|
|
5
5
|
![Pimon](http://pedrocarrico.net/pimon.jpg "Pimon")
|
6
6
|
|
@@ -58,27 +58,11 @@ The temperature stat is only available with the latest Raspbian distro (2012-09-
|
|
58
58
|
not work if you're developing on other systems.
|
59
59
|
Pimon only works with Ruby 1.9+, please refer to [my blog](http://blog.pedrocarrico.net/post/29478085586/compiling-and-installing-ruby-on-the-raspberry-pi-using "Compiling and installing ruby on the raspberry pi using rbenv…") for a way to install Ruby 1.9.3 on your Raspberry Pi.
|
60
60
|
|
61
|
-
## Deployment with capistrano
|
62
|
-
To deploy on your raspberry pi you just have to have ssh enabled and your keys authorized.
|
63
|
-
Then you can deploy with capistrano using:
|
64
|
-
```
|
65
|
-
cap deploy:setup
|
66
|
-
cap deploy:cold
|
67
|
-
```
|
68
|
-
|
69
|
-
This will setup your raspberry pi and deploy the application.
|
70
|
-
To start and stop the application you have the usual:
|
71
|
-
```
|
72
|
-
cap deploy:start
|
73
|
-
cap deploy:stop
|
74
|
-
```
|
75
|
-
I would recommend installing as a gem and tweak your own configuration file instead of deploying with capistrano as
|
76
|
-
this feature will probably be discontinued in the future.
|
77
|
-
|
78
61
|
## TODO
|
79
62
|
1. Improve disk stats, have a way of having custom mount points
|
80
|
-
2.
|
81
|
-
3.
|
63
|
+
2. Change configuration in realtime
|
64
|
+
3. Cpu frequency probe
|
65
|
+
4. Persist stats
|
82
66
|
|
83
67
|
## Copyright
|
84
68
|
Licensed under the [WTFPL](http://en.wikipedia.org/wiki/WTFPL "Do What The Fuck You Want To Public License") license.
|
data/lib/pimon.rb
CHANGED
data/lib/pimon/public/index.js
CHANGED
@@ -1,120 +1,154 @@
|
|
1
1
|
$(function () {
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
var i = 0,
|
3
|
+
titleStats,
|
4
|
+
rotateFaviconInterval,
|
5
|
+
ws;
|
6
|
+
|
7
|
+
function changeFavicon(o) {
|
8
|
+
titleStats = [
|
9
|
+
{ 'legend' : 'CPU', 'stat' : o.cpu.stats[o.cpu.stats.length - 1], 'color' : o.cpu.color, 'unit' : o.cpu.unit } ,
|
10
|
+
{ 'legend' : 'MEM', 'stat' : o.mem.stats[o.mem.stats.length - 1], 'color' : o.mem.color, 'unit' : o.mem.unit } ,
|
11
|
+
{ 'legend' : 'SWAP', 'stat' : o.swap.stats[o.swap.stats.length - 1], 'color' : o.swap.color, 'unit' : o.swap.unit},
|
12
|
+
{ 'legend' : 'DISK', 'stat' : o.disk.stats[o.disk.stats.length - 1], 'color' : o.disk.color, 'unit' : o.disk.unit},
|
13
|
+
{ 'legend' : 'TEMP', 'stat' : o.temp.stats[o.temp.stats.length - 1], 'color' : o.temp.color, 'unit' : o.temp.unit} ];
|
14
|
+
i = 0;
|
15
|
+
if (rotateFaviconInterval === undefined) {
|
16
|
+
rotateFavicon(titleStats);
|
17
|
+
rotateFaviconInterval = setInterval(function() { rotateFavicon(titleStats); }, 3000);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
function rotateFavicon(titleStats) {
|
22
|
+
Piecon.setOptions({
|
23
|
+
color: titleStats[i].color, // Pie chart color
|
24
|
+
background: '#bbb', // Empty pie chart color
|
25
|
+
shadow: '#fff', // Outer ring color
|
26
|
+
fallback: 'force' // Toggles displaying percentage in the title bar (possible values - true, false, 'force')
|
27
|
+
});
|
28
|
+
Piecon.setProgress(titleStats[i].stat);
|
5
29
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
30
|
+
$('title').text(titleStats[i].stat + titleStats[i].unit + ' ' + titleStats[i].legend);
|
31
|
+
i++;
|
32
|
+
if (i >= titleStats.length) {
|
33
|
+
i = 0;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
function drawChart(o) {
|
38
|
+
new Highcharts.Chart({
|
39
|
+
chart: {
|
40
|
+
renderTo: 'chart',
|
41
|
+
type: 'line',
|
42
|
+
marginRight: 130,
|
43
|
+
marginBottom: 25
|
44
|
+
},
|
45
|
+
title: {
|
46
|
+
text: 'Pimon',
|
47
|
+
x: -20
|
48
|
+
},
|
49
|
+
subtitle: {
|
50
|
+
text: o.hostname,
|
51
|
+
x: -20
|
52
|
+
},
|
53
|
+
xAxis: {
|
54
|
+
categories: o.time.stats
|
55
|
+
},
|
56
|
+
yAxis: {
|
57
|
+
title: {
|
58
|
+
text: 'Usage'
|
59
|
+
},
|
60
|
+
plotLines: [{
|
61
|
+
value: 0,
|
62
|
+
width: 1,
|
63
|
+
color: '#808080'
|
64
|
+
}],
|
65
|
+
max: 100,
|
66
|
+
min: 0
|
67
|
+
},
|
68
|
+
tooltip: {
|
69
|
+
formatter: function() {
|
70
|
+
return '<b>'+ this.series.name +'</b><br/>'+
|
71
|
+
this.x +': '+ this.y + (this.series.name === 'temp' ? o.temp.unit : '%');
|
17
72
|
}
|
73
|
+
},
|
74
|
+
legend: {
|
75
|
+
layout: 'vertical',
|
76
|
+
align: 'right',
|
77
|
+
verticalAlign: 'top',
|
78
|
+
x: -10,
|
79
|
+
y: 100,
|
80
|
+
borderWidth: 0
|
81
|
+
},
|
82
|
+
series: [{
|
83
|
+
name: 'cpu',
|
84
|
+
color: o.cpu.color,
|
85
|
+
data: o.cpu.stats
|
86
|
+
},
|
87
|
+
{
|
88
|
+
name: 'mem',
|
89
|
+
color: o.mem.color,
|
90
|
+
data: o.mem.stats
|
91
|
+
},
|
92
|
+
{
|
93
|
+
name: 'swap',
|
94
|
+
color: o.swap.color,
|
95
|
+
data: o.swap.stats
|
96
|
+
},
|
97
|
+
{
|
98
|
+
name: 'disk',
|
99
|
+
color: o.disk.color,
|
100
|
+
data: o.disk.stats
|
101
|
+
},
|
102
|
+
{
|
103
|
+
name: 'temp',
|
104
|
+
color: o.temp.color,
|
105
|
+
data: o.temp.stats
|
106
|
+
}],
|
107
|
+
credits: {
|
108
|
+
enabled: false
|
109
|
+
}
|
110
|
+
});
|
111
|
+
}
|
112
|
+
|
113
|
+
function maybeInsertWordConnector(text, connector) {
|
114
|
+
return text !== '' ? text + connector : text;
|
115
|
+
}
|
116
|
+
|
117
|
+
function pluralize(count, word) {
|
118
|
+
return ((count === '1') ? ' ' + word : ' ' + word + 's');
|
119
|
+
}
|
120
|
+
|
121
|
+
function formatUptime(uptimeArray) {
|
122
|
+
var uptime = '',
|
123
|
+
days = uptimeArray[0],
|
124
|
+
hours = uptimeArray[1],
|
125
|
+
minutes = uptimeArray[2],
|
126
|
+
seconds = uptimeArray[3];
|
127
|
+
|
128
|
+
if (days !== '0') {
|
129
|
+
uptime = + ' ' + pluralize(days, 'day');
|
18
130
|
}
|
19
131
|
|
20
|
-
|
21
|
-
|
22
|
-
color: titleStats[i]['color'], // Pie chart color
|
23
|
-
background: '#bbb', // Empty pie chart color
|
24
|
-
shadow: '#fff', // Outer ring color
|
25
|
-
fallback: 'force' // Toggles displaying percentage in the title bar (possible values - true, false, 'force')
|
26
|
-
});
|
27
|
-
Piecon.setProgress(titleStats[i]['stat']);
|
28
|
-
|
29
|
-
$('title').text(titleStats[i]['stat'] + titleStats[i]['unit'] + ' ' + titleStats[i]['legend']);
|
30
|
-
i++;
|
31
|
-
if (i >= titleStats.length) {
|
32
|
-
i = 0;
|
33
|
-
}
|
132
|
+
if (hours !== '0') {
|
133
|
+
uptime = maybeInsertWordConnector(uptime, ', ') + hours + ' ' + pluralize(hours, 'hour');
|
34
134
|
}
|
35
135
|
|
36
|
-
|
37
|
-
|
38
|
-
chart: {
|
39
|
-
renderTo: 'chart',
|
40
|
-
type: 'line',
|
41
|
-
marginRight: 130,
|
42
|
-
marginBottom: 25
|
43
|
-
},
|
44
|
-
title: {
|
45
|
-
text: 'Pimon',
|
46
|
-
x: -20
|
47
|
-
},
|
48
|
-
subtitle: {
|
49
|
-
text: o.hostname,
|
50
|
-
x: -20
|
51
|
-
},
|
52
|
-
xAxis: {
|
53
|
-
categories: o.time.stats
|
54
|
-
},
|
55
|
-
yAxis: {
|
56
|
-
title: {
|
57
|
-
text: 'Usage'
|
58
|
-
},
|
59
|
-
plotLines: [{
|
60
|
-
value: 0,
|
61
|
-
width: 1,
|
62
|
-
color: '#808080'
|
63
|
-
}],
|
64
|
-
max: 100,
|
65
|
-
min: 0
|
66
|
-
},
|
67
|
-
tooltip: {
|
68
|
-
formatter: function() {
|
69
|
-
return '<b>'+ this.series.name +'</b><br/>'+
|
70
|
-
this.x +': '+ this.y + (this.series.name === 'temp' ? o.temp.unit : '%');
|
71
|
-
}
|
72
|
-
},
|
73
|
-
legend: {
|
74
|
-
layout: 'vertical',
|
75
|
-
align: 'right',
|
76
|
-
verticalAlign: 'top',
|
77
|
-
x: -10,
|
78
|
-
y: 100,
|
79
|
-
borderWidth: 0
|
80
|
-
},
|
81
|
-
series: [{
|
82
|
-
name: 'cpu',
|
83
|
-
color: o.cpu.color,
|
84
|
-
data: o.cpu.stats
|
85
|
-
},
|
86
|
-
{
|
87
|
-
name: 'mem',
|
88
|
-
color: o.mem.color,
|
89
|
-
data: o.mem.stats
|
90
|
-
},
|
91
|
-
{
|
92
|
-
name: 'swap',
|
93
|
-
color: o.swap.color,
|
94
|
-
data: o.swap.stats
|
95
|
-
},
|
96
|
-
{
|
97
|
-
name: 'disk',
|
98
|
-
color: o.disk.color,
|
99
|
-
data: o.disk.stats
|
100
|
-
},
|
101
|
-
{
|
102
|
-
name: 'temp',
|
103
|
-
color: o.temp.color,
|
104
|
-
data: o.temp.stats
|
105
|
-
}],
|
106
|
-
credits: {
|
107
|
-
enabled: false
|
108
|
-
}
|
109
|
-
});
|
136
|
+
if (minutes !== '0') {
|
137
|
+
uptime = maybeInsertWordConnector(uptime, ', ') + minutes + ' ' + pluralize(minutes, 'minute');
|
110
138
|
}
|
111
139
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
140
|
+
if (seconds !== '0') {
|
141
|
+
uptime = maybeInsertWordConnector(uptime, ' and ') + seconds + ' ' + pluralize(seconds, 'second');
|
142
|
+
}
|
143
|
+
return uptime;
|
144
|
+
}
|
145
|
+
|
146
|
+
ws = new WebSocket('ws://' + window.location.host + window.location.pathname);
|
147
|
+
ws.onclose = function() { alert('Connection to Pimon server lost...'); };
|
148
|
+
ws.onmessage = function(m) {
|
149
|
+
var o = $.parseJSON(m.data);
|
150
|
+
drawChart(o);
|
151
|
+
changeFavicon(o);
|
152
|
+
$('#uptime .up').text(formatUptime(o.uptime.slice(-1)[0]));
|
153
|
+
};
|
120
154
|
});
|
@@ -0,0 +1,5 @@
|
|
1
|
+
(function(){var i={},j=null,k=null,f=null,g=null,h={},l={color:"#ff0084",background:"#bbb",shadow:"#fff",fallback:!1},c,o=navigator.userAgent.toLowerCase();c=function(e){return-1!==o.indexOf(e)};var p=c("msie");c("chrome");c("chrome")||c("safari");var q=c("safari")&&!c("chrome");c("mozilla")&&!c("chrome")&&c("safari");var m=function(e){for(var a=document.getElementsByTagName("link"),c=document.getElementsByTagName("head")[0],f=0,h=a.length;f<h;f++)("icon"===a[f].getAttribute("rel")||"shortcut icon"===
|
2
|
+
a[f].getAttribute("rel"))&&c.removeChild(a[f]);a=document.createElement("link");a.type="image/x-icon";a.rel="icon";a.href=e;document.getElementsByTagName("head")[0].appendChild(a)},n=function(){g||(g=document.createElement("canvas"),g.width=16,g.height=16);return g};i.setOptions=function(e){h={};for(var a in l)h[a]=e.hasOwnProperty(a)?e[a]:l[a];return this};i.setProgress=function(e){f||(f=document.title);if(!k||!j){var a;a:{a=document.getElementsByTagName("link");for(var c=0,i=a.length;c<i;c++)if("icon"===
|
3
|
+
a[c].getAttribute("rel")||"shortcut icon"===a[c].getAttribute("rel")){a=a[c];break a}a=!1}k=j=a?a.getAttribute("href"):"/favicon.ico"}if(!isNaN(parseFloat(e))&&isFinite(e))if(!n().getContext||p||q||!0==h.fallback)document.title=0<e?"("+e+"%) "+f:f;else{"force"===h.fallback&&(document.title=0<e?"("+e+"%) "+f:f);var g=e,b=n(),d=b.getContext("2d"),g=g||0,e=j;a=new Image;a.onload=function(){if(d){d.clearRect(0,0,16,16);d.beginPath();d.moveTo(b.width/2,b.height/2);d.arc(b.width/2,b.height/2,Math.min(b.width/
|
4
|
+
2,b.height/2),0,Math.PI*2,false);d.fillStyle=h.shadow;d.fill();d.beginPath();d.moveTo(b.width/2,b.height/2);d.arc(b.width/2,b.height/2,Math.min(b.width/2,b.height/2)-2,0,Math.PI*2,false);d.fillStyle=h.background;d.fill();if(g>0){d.beginPath();d.moveTo(b.width/2,b.height/2);d.arc(b.width/2,b.height/2,Math.min(b.width/2,b.height/2)-2,-0.5*Math.PI,(-0.5+2*g/100)*Math.PI,false);d.lineTo(b.width/2,b.height/2);d.fillStyle=h.color;d.fill()}m(b.toDataURL())}};e.match(/^data/)||(a.crossOrigin="anonymous");
|
5
|
+
a.src=e}else return!1};i.reset=function(){f&&(document.title=f);k&&(j=k,m(j))};i.setOptions(l);window.Piecon=i})();
|
data/lib/pimon/stats.rb
CHANGED
@@ -6,6 +6,7 @@ require 'pimon/probe/memory_usage'
|
|
6
6
|
require 'pimon/probe/swap_usage'
|
7
7
|
require 'pimon/probe/time_check'
|
8
8
|
require 'pimon/probe/temperature'
|
9
|
+
require 'pimon/probe/uptime'
|
9
10
|
require 'pimon/stats'
|
10
11
|
|
11
12
|
class StatsCollector
|
@@ -17,7 +18,8 @@ class StatsCollector
|
|
17
18
|
Probe::MemoryUsage,
|
18
19
|
Probe::SwapUsage,
|
19
20
|
Probe::DiskUsage,
|
20
|
-
Probe::Temperature
|
21
|
+
Probe::Temperature,
|
22
|
+
Probe::Uptime
|
21
23
|
]
|
22
24
|
@stats = Stats.new(@probes.map(&:symbol).concat([:time]))
|
23
25
|
end
|
@@ -38,10 +40,12 @@ class StatsCollector
|
|
38
40
|
|
39
41
|
def show_stats
|
40
42
|
time = @stats.range(:time)
|
43
|
+
uptime = @stats.range(:uptime)
|
41
44
|
|
42
45
|
stats = {
|
43
46
|
:time => { :stats => time.map { |t| (/\d\d:\d\d:\d\d/.match(t))[0] } },
|
44
|
-
:hostname => @config.hostname
|
47
|
+
:hostname => @config.hostname,
|
48
|
+
:uptime => uptime
|
45
49
|
}
|
46
50
|
|
47
51
|
@probes.each do |probe|
|
data/lib/pimon/version.rb
CHANGED
data/lib/pimon/views/index.haml
CHANGED
@@ -3,8 +3,10 @@
|
|
3
3
|
%title Pimon
|
4
4
|
%script{ :src => '//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.0/jquery-1.8.0.min.js' }
|
5
5
|
%script{ :src => '//cdnjs.cloudflare.com/ajax/libs/highcharts/2.3.1/highcharts.js' }
|
6
|
-
%script{ :src => '
|
6
|
+
%script{ :src => '/piecon.min.js' }
|
7
7
|
%script{ :src => '/index.js' }
|
8
8
|
%body
|
9
9
|
#chart
|
10
10
|
#uptime
|
11
|
+
Uptime:
|
12
|
+
%strong.up
|
data/pimon.gemspec
CHANGED
@@ -20,15 +20,16 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.executables = `git ls-files -- bin/pimon`.split("\n").map{ |f| File.basename(f) }
|
21
21
|
s.require_paths = ['lib']
|
22
22
|
|
23
|
-
s.add_runtime_dependency 'haml', '~> 4.0.
|
24
|
-
s.add_runtime_dependency 'sinatra', '~> 1.4.
|
23
|
+
s.add_runtime_dependency 'haml', '~> 4.0.3'
|
24
|
+
s.add_runtime_dependency 'sinatra', '~> 1.4.3'
|
25
25
|
s.add_runtime_dependency 'em-websocket', '= 0.3.8'
|
26
26
|
s.add_runtime_dependency 'sinatra-websocket', '~> 0.2.1'
|
27
|
-
s.add_runtime_dependency '
|
27
|
+
s.add_runtime_dependency 'sys-uptime', '~> 0.6.1'
|
28
|
+
s.add_runtime_dependency 'thin', '~> 1.5.1'
|
28
29
|
|
29
|
-
s.add_development_dependency 'rack-test',
|
30
|
-
s.add_development_dependency 'rspec',
|
31
|
-
s.add_development_dependency 'simplecov',
|
32
|
-
s.add_development_dependency 'simplecov-rcov',
|
33
|
-
s.add_development_dependency 'timecop',
|
30
|
+
s.add_development_dependency 'rack-test', '~> 0.6.2'
|
31
|
+
s.add_development_dependency 'rspec', '~> 2.14.1'
|
32
|
+
s.add_development_dependency 'simplecov', '~> 0.7.1'
|
33
|
+
s.add_development_dependency 'simplecov-rcov', '~> 0.2.3'
|
34
|
+
s.add_development_dependency 'timecop', '~> 0.6.1'
|
34
35
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# Check http://richardconroy.blogspot.pt/2010/01/issues-testing-sinatra-datamapper-app.html
|
3
3
|
ENV['RACK_ENV'] = 'test'
|
4
4
|
|
5
|
-
if ENV['COVERAGE']
|
5
|
+
if ENV['COVERAGE'] || ENV['TRAVIS']
|
6
6
|
require 'simplecov'
|
7
|
+
require 'coveralls'
|
8
|
+
Coveralls.wear!
|
7
9
|
require 'simplecov-rcov'
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
|
10
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
11
|
+
SimpleCov::Formatter::HTMLFormatter,
|
12
|
+
SimpleCov::Formatter::RcovFormatter,
|
13
|
+
Coveralls::SimpleCov::Formatter
|
14
|
+
]
|
15
15
|
SimpleCov.start do
|
16
16
|
add_filter 'spec'
|
17
17
|
end
|
@@ -16,6 +16,7 @@ describe 'StatsCollector' do
|
|
16
16
|
Probe::MemoryUsage.should_receive(:check)
|
17
17
|
Probe::SwapUsage.should_receive(:check)
|
18
18
|
Probe::Temperature.should_receive(:check)
|
19
|
+
Probe::Uptime.should_receive(:check)
|
19
20
|
|
20
21
|
@stats_collector.collect_stats
|
21
22
|
end
|
@@ -24,6 +25,7 @@ describe 'StatsCollector' do
|
|
24
25
|
should == {
|
25
26
|
:time => { :stats => [] },
|
26
27
|
:hostname => 'test_hostname',
|
28
|
+
:uptime => [],
|
27
29
|
:cpu => { :stats => [], :color => '#D2691E', :unit => '%' },
|
28
30
|
:mem => { :stats => [], :color => '#87CEFA', :unit => '%' },
|
29
31
|
:swap => {:stats => [], :color => '#3CB371', :unit => '%' },
|
@@ -41,6 +43,7 @@ describe 'StatsCollector' do
|
|
41
43
|
Probe::MemoryUsage.should_receive(:check).any_number_of_times.and_return(78)
|
42
44
|
Probe::SwapUsage.should_receive(:check).any_number_of_times.and_return(50)
|
43
45
|
Probe::Temperature.should_receive(:check).any_number_of_times.and_return(40)
|
46
|
+
Probe::Uptime.should_receive(:check).any_number_of_times.and_return([1,2,3,4])
|
44
47
|
|
45
48
|
7.times do
|
46
49
|
@stats_collector.collect_stats
|
@@ -51,6 +54,7 @@ describe 'StatsCollector' do
|
|
51
54
|
should == {
|
52
55
|
:time => { :stats => ['12:00:00', '12:00:00', '12:00:00', '12:00:00', '12:00:00', '12:00:00']},
|
53
56
|
:hostname => 'test_hostname',
|
57
|
+
:uptime => [[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]],
|
54
58
|
:cpu => {:stats => [50, 50, 50, 50, 50, 50], :color => '#D2691E', :unit => '%'},
|
55
59
|
:mem => { :stats => [78, 78, 78, 78, 78, 78], :color =>'#87CEFA', :unit => '%'},
|
56
60
|
:swap=>{ :stats => [50, 50, 50, 50, 50, 50], :color => '#3CB371', :unit => '%'},
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pimon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: haml
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 4.0.
|
21
|
+
version: 4.0.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 4.0.
|
29
|
+
version: 4.0.3
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: sinatra
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 1.4.
|
37
|
+
version: 1.4.3
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 1.4.
|
45
|
+
version: 1.4.3
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: em-websocket
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +75,22 @@ dependencies:
|
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: 0.2.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: sys-uptime
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.6.1
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.6.1
|
78
94
|
- !ruby/object:Gem::Dependency
|
79
95
|
name: thin
|
80
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,7 +98,7 @@ dependencies:
|
|
82
98
|
requirements:
|
83
99
|
- - ~>
|
84
100
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.5.
|
101
|
+
version: 1.5.1
|
86
102
|
type: :runtime
|
87
103
|
prerelease: false
|
88
104
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,7 +106,7 @@ dependencies:
|
|
90
106
|
requirements:
|
91
107
|
- - ~>
|
92
108
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.5.
|
109
|
+
version: 1.5.1
|
94
110
|
- !ruby/object:Gem::Dependency
|
95
111
|
name: rack-test
|
96
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +130,7 @@ dependencies:
|
|
114
130
|
requirements:
|
115
131
|
- - ~>
|
116
132
|
- !ruby/object:Gem::Version
|
117
|
-
version: 2.
|
133
|
+
version: 2.14.1
|
118
134
|
type: :development
|
119
135
|
prerelease: false
|
120
136
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -122,7 +138,7 @@ dependencies:
|
|
122
138
|
requirements:
|
123
139
|
- - ~>
|
124
140
|
- !ruby/object:Gem::Version
|
125
|
-
version: 2.
|
141
|
+
version: 2.14.1
|
126
142
|
- !ruby/object:Gem::Dependency
|
127
143
|
name: simplecov
|
128
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -181,7 +197,6 @@ extra_rdoc_files: []
|
|
181
197
|
files:
|
182
198
|
- .gitignore
|
183
199
|
- .travis.yml
|
184
|
-
- Capfile
|
185
200
|
- Gemfile
|
186
201
|
- Gemfile.lock
|
187
202
|
- README.md
|
@@ -194,12 +209,9 @@ files:
|
|
194
209
|
- bin/random.h
|
195
210
|
- bin/vmstat.c
|
196
211
|
- config/config.ru
|
197
|
-
- config/config_dev.ru
|
198
212
|
- config/default.yml
|
199
|
-
- config/deploy.rb
|
200
213
|
- config/test.yml
|
201
214
|
- config/test_broken.yml
|
202
|
-
- config/thin/config.yml
|
203
215
|
- lib/pimon.rb
|
204
216
|
- lib/pimon/hash_extensions.rb
|
205
217
|
- lib/pimon/pimon_config.rb
|
@@ -211,8 +223,10 @@ files:
|
|
211
223
|
- lib/pimon/probe/system_memory.rb
|
212
224
|
- lib/pimon/probe/temperature.rb
|
213
225
|
- lib/pimon/probe/time_check.rb
|
226
|
+
- lib/pimon/probe/uptime.rb
|
214
227
|
- lib/pimon/public/favicon.ico
|
215
228
|
- lib/pimon/public/index.js
|
229
|
+
- lib/pimon/public/piecon.min.js
|
216
230
|
- lib/pimon/stats.rb
|
217
231
|
- lib/pimon/stats_collector.rb
|
218
232
|
- lib/pimon/version.rb
|
data/Capfile
DELETED
data/config/config_dev.ru
DELETED
data/config/deploy.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
set :application, "pimon"
|
2
|
-
set :user, "pi"
|
3
|
-
|
4
|
-
set :scm, :git
|
5
|
-
|
6
|
-
set :repository, "git://github.com/pedrocarrico/pimon.git"
|
7
|
-
|
8
|
-
set :deploy_to, '/home/pi/app/pimon'
|
9
|
-
set :deploy_via, :remote_cache # quicker checkouts from github
|
10
|
-
|
11
|
-
set :domain, 'raspberrypi'
|
12
|
-
role :app, domain
|
13
|
-
role :web, domain
|
14
|
-
|
15
|
-
set :runner, user
|
16
|
-
set :use_sudo, false
|
17
|
-
|
18
|
-
after 'deploy:update_code', 'deploy:bundle_install'
|
19
|
-
|
20
|
-
namespace :deploy do
|
21
|
-
task :start, :roles => [:web, :app] do
|
22
|
-
run "cd #{deploy_to}/current && PIMON_CONFIG=#{deploy_to}/shared/production.yml nohup thin -C config/thin/config.yml -R config/config.ru start"
|
23
|
-
end
|
24
|
-
|
25
|
-
task :stop, :roles => [:web, :app] do
|
26
|
-
run "cd #{deploy_to}/current && nohup thin -C config/thin/config.yml -R config/config.ru stop"
|
27
|
-
end
|
28
|
-
|
29
|
-
task :restart, :roles => [:web, :app] do
|
30
|
-
deploy.stop
|
31
|
-
deploy.start
|
32
|
-
end
|
33
|
-
|
34
|
-
task :cold do
|
35
|
-
deploy.update
|
36
|
-
deploy.start
|
37
|
-
end
|
38
|
-
|
39
|
-
desc "run 'bundle install' to install Bundler's packaged gems for the current deploy"
|
40
|
-
task :bundle_install, :roles => :app do
|
41
|
-
run "cd #{deploy_to}/current && bundle install --without test development"
|
42
|
-
end
|
43
|
-
end
|
data/config/thin/config.yml
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
environment: production
|
2
|
-
chdir: /home/pi/app/pimon/current
|
3
|
-
address: 127.0.0.1
|
4
|
-
user: pi
|
5
|
-
group: pi
|
6
|
-
port: 4567
|
7
|
-
pid: /home/pi/app/pimon/shared/pids/thin.pid
|
8
|
-
rackup: /home/pi/app/pimon/current/config/config.ru
|
9
|
-
log: /home/pi/app/pimon/shared/log/thin.log
|
10
|
-
max_conns: 1024
|
11
|
-
timeout: 30
|
12
|
-
max_persistent_conns: 512
|
13
|
-
daemonize: true
|