collectd-interface 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +134 -0
- data/bin/collectd-interface-daemon +401 -0
- data/bin/collectd-interface-plugins +95 -0
- data/graphs/cpus.erb +76 -0
- data/graphs/disk-traffic-root.erb +30 -0
- data/graphs/disk-traffic-srv.erb.disabled +30 -0
- data/graphs/disk-traffic-tmp.erb.disabled +30 -0
- data/graphs/disk-traffic-var.erb.disabled +30 -0
- data/graphs/gridengine-jobs.erb.disabled +32 -0
- data/graphs/load.erb +36 -0
- data/graphs/memory.erb +47 -0
- data/graphs/network-eth0.erb +26 -0
- data/graphs/network-lo.erb +26 -0
- data/graphs/processes.erb +66 -0
- data/public/images/cpus.png +0 -0
- data/public/images/cpus.svg +946 -0
- data/public/images/disk-traffic-root.png +0 -0
- data/public/images/disk-traffic-srv.png +0 -0
- data/public/images/disk-traffic-var.png +0 -0
- data/public/images/load.png +0 -0
- data/public/images/load.svg +638 -0
- data/public/images/memory.png +0 -0
- data/public/images/memory.svg +741 -0
- data/public/images/network-eth0.png +0 -0
- data/public/images/network-eth0.svg +609 -0
- data/public/images/network-lo.png +0 -0
- data/public/images/network-lo.svg +644 -0
- data/public/images/processes.png +0 -0
- data/public/images/processes.svg +832 -0
- data/public/readme/user-interface.png +0 -0
- data/public/script/toggle.js +9 -0
- data/public/style/default.css +275 -0
- data/public/style/nav.css +265 -0
- data/views/README.md +134 -0
- data/views/data.erb +3 -0
- data/views/graph.erb +19 -0
- data/views/readme.erb +3 -0
- data/views/report.erb +17 -0
- data/views/reports/disk-free.erb +20 -0
- data/views/reports/list-open-files-lustre.erb.disabled +44 -0
- data/views/reports/list-open-files-tmp.erb +44 -0
- data/views/reports/processes-cpu-usage.erb +39 -0
- data/views/reports/system-sockets.erb +32 -0
- data/views/show_values.erb +11 -0
- data/views/template/default.erb +21 -0
- data/views/template/header.erb +3 -0
- data/views/template/navigation.erb +9 -0
- data/views/template/options/data.erb +31 -0
- data/views/template/options/graph.erb +23 -0
- data/views/template/options/readme.erb +0 -0
- data/views/template/options/report.erb +11 -0
- metadata +128 -0
data/views/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
Created 10 Feb 2012 -- Last change 14 Feb 2012
|
2
|
+
By Victor Penso
|
3
|
+
|
4
|
+
Description
|
5
|
+
===========
|
6
|
+
|
7
|
+
_Collectd-Interface_ serves a web user-interface to data stored
|
8
|
+
by [Collectd](http://collectd.org/). Furthermore it provides REST
|
9
|
+
access to all data.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
============
|
13
|
+
|
14
|
+
Download and install Collectd following the instructions
|
15
|
+
from the developers.
|
16
|
+
|
17
|
+
On Debian flavored Linux use:
|
18
|
+
|
19
|
+
apt-get install collectd rrdtool
|
20
|
+
|
21
|
+
You will need the [RRDtool](http://oss.oetiker.ch/rrdtool/) too.
|
22
|
+
|
23
|
+
Usage
|
24
|
+
=====
|
25
|
+
|
26
|
+
Get help:
|
27
|
+
|
28
|
+
collectd-interface-daemon --help
|
29
|
+
|
30
|
+
Start the Collectd Interface in fore-ground:
|
31
|
+
|
32
|
+
collectd-interface-daemon
|
33
|
+
|
34
|
+
Open the web-interface <a href='localhost:4567'>localhost:4567</a>.
|
35
|
+
|
36
|
+
Start the Collectd Interface as daemon:
|
37
|
+
|
38
|
+
collectd-interface-daemon -p 5000 -l /var/log/ -P /var/run/ &
|
39
|
+
|
40
|
+
|
41
|
+
Interfaces
|
42
|
+
==========
|
43
|
+
|
44
|
+
Collectd-Interface servers three different kinds of output:
|
45
|
+
|
46
|
+
1. `/graph` is the user-interface showing line charts of many
|
47
|
+
of the data accumulated by Collectd.
|
48
|
+
2. `/report` presents tables of system specific information
|
49
|
+
like disk capacity of a list of network sockets.
|
50
|
+
3. `/data` servers an REST API to all data available from
|
51
|
+
Collectd.
|
52
|
+
|
53
|
+
All content from `/graph`, `/report` and `/data` is accessible
|
54
|
+
by a REST interface, to allow embedding this content into other
|
55
|
+
applications.
|
56
|
+
|
57
|
+
Graph
|
58
|
+
-----
|
59
|
+
|
60
|
+
![Screenshot of User-Interface](https://github.com/vpenso/collectd-interface/raw/master/public/readme/user-interface.png "Screenshot of the User-Interface")
|
61
|
+
|
62
|
+
You can select individual graphs using the drop-down menu followed by
|
63
|
+
clicking the "Show" button. In case you just want to have the image, to
|
64
|
+
embed it into another web-page, use the links beneath the graph.
|
65
|
+
|
66
|
+
Once the graph is generated the caller will be redirected to `/image/`.
|
67
|
+
|
68
|
+
**Parameters**
|
69
|
+
|
70
|
+
It is possible to limit the time-frame of the graph using the option
|
71
|
+
`last=10h`(us (m)inutes,(d)ays or (w)eeks).
|
72
|
+
|
73
|
+
This simple example:
|
74
|
+
|
75
|
+
http://.../memory?last=1w&image=svg
|
76
|
+
|
77
|
+
Requests an SVG image with the memory graph for the last week.
|
78
|
+
|
79
|
+
**Plugin**
|
80
|
+
|
81
|
+
You can create add a custom graph rendering data from Collectd
|
82
|
+
by creating a template which is used to generate the <tt>rrdtool graph</tt>.
|
83
|
+
Take a look to the <tt>graphs/</tt> and <tt>disabled/graphs/</tt> directories
|
84
|
+
for examples. I recommend you the start the Collectd-Interface in
|
85
|
+
debug mode (option <tt>-d</tt>) while you develop new graph templates.
|
86
|
+
|
87
|
+
In case you want to enable graphs from <tt>disabled/graphs/</tt> create
|
88
|
+
a soft link from <tt>graphs/</tt>. The <tt>collectd-interface</tt> daemon will
|
89
|
+
automatically recognize new templates within <tt>graphs</tt> on start.
|
90
|
+
|
91
|
+
Report
|
92
|
+
------
|
93
|
+
|
94
|
+
Reports a basically wrappers around commands like <tt>df -l</tt> or
|
95
|
+
<tt>ss -ar</tt>. The output is available as HTML in the "Report" section
|
96
|
+
of the user-interface.
|
97
|
+
|
98
|
+
TODO
|
99
|
+
|
100
|
+
Data
|
101
|
+
----
|
102
|
+
|
103
|
+
List all available values <a href="/data/">/data/</a> from
|
104
|
+
Collectd. Get the time-series of a specific value.
|
105
|
+
|
106
|
+
http://.../data/interface/if_packets-eth0/rx
|
107
|
+
|
108
|
+
By default the severs will answer with averages
|
109
|
+
of all data-points and an HTML document.
|
110
|
+
|
111
|
+
**Parameters**
|
112
|
+
|
113
|
+
http://.../value?last=36h&resolution=3600
|
114
|
+
|
115
|
+
Request only values from the last 36 hours, with a
|
116
|
+
data point resolution of 1 hour (3600 seconds).
|
117
|
+
Default resolution is the highest possible and you
|
118
|
+
will get by default values of the last 24 hours.
|
119
|
+
In the time specification you can also use (w)eeks,
|
120
|
+
(d)ays and (m)inutes.
|
121
|
+
|
122
|
+
http://.../rx?function=max&format=json
|
123
|
+
|
124
|
+
Request the maximum of all data points for the past
|
125
|
+
in the JSON format. Other consolidation functions
|
126
|
+
are average (default) and min, for the smallest value
|
127
|
+
in a time-frame.
|
128
|
+
|
129
|
+
|
130
|
+
Copying
|
131
|
+
=======
|
132
|
+
|
133
|
+
Copyright 2011 Victor Penso
|
134
|
+
License [GPLv3](http://www.gnu.org/licenses/gpl-3.0.html) (see LICENSE file)
|
data/views/data.erb
ADDED
data/views/graph.erb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
<ul>
|
2
|
+
<% if @display.first == 'all' then %>
|
3
|
+
<% @graphs.keys.sort.each do |name| %>
|
4
|
+
<% url = "/graph/#{name}?#{@args}" %>
|
5
|
+
<li>
|
6
|
+
<img src="<%= url %>"/><br/>
|
7
|
+
<a href="<%= url %>"><%= url %></a>
|
8
|
+
</li>
|
9
|
+
<% end %>
|
10
|
+
<% else %>
|
11
|
+
<% @display.each do |graph| %>
|
12
|
+
<% url = "/graph/#{graph}?#{@args}"%>
|
13
|
+
<li>
|
14
|
+
<img src="<%= url %>"/><br/>
|
15
|
+
<a href="<%= url %>"><%= url %></a>
|
16
|
+
</li>
|
17
|
+
<% end%>
|
18
|
+
<% end %>
|
19
|
+
</ul>
|
data/views/readme.erb
ADDED
data/views/report.erb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<ul style='list-style-type:none; padding-left:0'>
|
2
|
+
<% if @display == 'all' %>
|
3
|
+
<% for val in @reports %>
|
4
|
+
<li>
|
5
|
+
<%= erb("/reports/#{val}".to_sym) %>
|
6
|
+
<% url = "/report/#{val}?format=json" %>
|
7
|
+
<a href="<%= url %>"><%= url %></a>
|
8
|
+
</li>
|
9
|
+
<% end %>
|
10
|
+
<% else %>
|
11
|
+
<li>
|
12
|
+
<%= erb("/reports/#{@display}".to_sym)%>
|
13
|
+
<% url = "/report/#{@display}?format=json" %>
|
14
|
+
<a href="<%= url%>"><%= url %></a>
|
15
|
+
</li>
|
16
|
+
<% end %>
|
17
|
+
</ul>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<% require 'json'
|
2
|
+
content = `df -lh`.split("\n")
|
3
|
+
if @type == 'text' then %><%= content.join("\n") %>
|
4
|
+
<% elsif @type == 'json'
|
5
|
+
keys = content[0].chop.chop.split.map! { |v| v.downcase }
|
6
|
+
json = Array.new
|
7
|
+
content[1..-1].each { |values| json << Hash[*keys.zip(values.split).flatten] } %><%= JSON.pretty_generate json %>
|
8
|
+
<% else %>
|
9
|
+
<div style="font-size:160%"><strong>Local Storage</strong></div>
|
10
|
+
<table>
|
11
|
+
<thead>
|
12
|
+
<tr><th><%= content[0].chop.chop.split.join('</th><th>') %></th></tr>
|
13
|
+
</thead>
|
14
|
+
<tbody>
|
15
|
+
<% content[1..-1].each do |line| %>
|
16
|
+
<tr><td><%= line.split.join('</td><td>') %></td></tr>
|
17
|
+
<% end %>
|
18
|
+
</tbody>
|
19
|
+
</table>
|
20
|
+
<% end %>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<% path = '/lustre' %>
|
2
|
+
<% content = `lsof -u ^root -S2 #{path} | tr -s ' ' | cut -d' ' -f2-4,9-` %>
|
3
|
+
<% if @type == 'text' then %>
|
4
|
+
<%= content %>
|
5
|
+
<% elsif @type == 'json' %>
|
6
|
+
<% require 'json' %>
|
7
|
+
<% struct = Array.new %>
|
8
|
+
<% content = content.split("\n")[1..-1] %>
|
9
|
+
<% keys = ['pid','user','state','file'] %>
|
10
|
+
<% unless content.empty? %>
|
11
|
+
<% content.each do |file| %>
|
12
|
+
<% file = file.split %>
|
13
|
+
<% values = file[0..2] %>
|
14
|
+
<% values << file[3..-1].join(' ') %>
|
15
|
+
<% struct << Hash[*keys.zip(values).flatten] %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
<%= JSON.pretty_generate struct %>
|
19
|
+
<% else %>
|
20
|
+
<div style="font-size:160%"><strong>Open Files in Lustre</strong></div>
|
21
|
+
<table>
|
22
|
+
<thead>
|
23
|
+
<tr>
|
24
|
+
<td>Process ID</td>
|
25
|
+
<td>User</td>
|
26
|
+
<td>State</td>
|
27
|
+
<td>File</td>
|
28
|
+
</tr>
|
29
|
+
</thead>
|
30
|
+
<tbody>
|
31
|
+
<% if content.empty? %>
|
32
|
+
<tr><td>none</td><td>none</td><td>none</td><td>none</td></tr>
|
33
|
+
<% else %>
|
34
|
+
<% content.split("\n")[1..-1].each do |file| %>
|
35
|
+
<% file = file.split%>
|
36
|
+
<tr>
|
37
|
+
<td><%= file[0..2].join('</td><td>') %></td>
|
38
|
+
<td><span style="font-size:80%"><%= file[3..-1].join(' ')%></span></td>
|
39
|
+
</tr>
|
40
|
+
<% end %>
|
41
|
+
<% end %>
|
42
|
+
</tbody>
|
43
|
+
</table>
|
44
|
+
<% end %>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<% path = '/tmp' %>
|
2
|
+
<% content = `lsof -u ^root -S2 #{path} | tr -s ' ' | cut -d' ' -f2-4,9-` %>
|
3
|
+
<% if @type == 'text' then %>
|
4
|
+
<%= content %>
|
5
|
+
<% elsif @type == 'json' %>
|
6
|
+
<% require 'json' %>
|
7
|
+
<% struct = Array.new %>
|
8
|
+
<% content = content.split("\n")[1..-1] %>
|
9
|
+
<% keys = ['pid','user','state','file'] %>
|
10
|
+
<% unless content.empty? %>
|
11
|
+
<% content.each do |file| %>
|
12
|
+
<% file = file.split %>
|
13
|
+
<% values = file[0..2] %>
|
14
|
+
<% values << file[3..-1].join(' ') %>
|
15
|
+
<% struct << Hash[*keys.zip(values).flatten] %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
<%= JSON.pretty_generate struct %>
|
19
|
+
<% else %>
|
20
|
+
<div style="font-size:160%"><strong>Open Files in Temp</strong></div>
|
21
|
+
<table>
|
22
|
+
<thead>
|
23
|
+
<tr>
|
24
|
+
<td>Process ID</td>
|
25
|
+
<td>User</td>
|
26
|
+
<td>State</td>
|
27
|
+
<td>File</td>
|
28
|
+
</tr>
|
29
|
+
</thead>
|
30
|
+
<tbody>
|
31
|
+
<% if content.empty? %>
|
32
|
+
<tr><td>none</td><td>none</td><td>none</td><td>none</td></tr>
|
33
|
+
<% else %>
|
34
|
+
<% content.split("\n")[1..-1].each do |file| %>
|
35
|
+
<% file = file.split%>
|
36
|
+
<tr>
|
37
|
+
<td><%= file[0..2].join('</td><td>') %></td>
|
38
|
+
<td><span style="font-size:80%"><%= file[3..-1].join(' ')%></span></td>
|
39
|
+
</tr>
|
40
|
+
<% end %>
|
41
|
+
<% end %>
|
42
|
+
</tbody>
|
43
|
+
</table>
|
44
|
+
<% end %>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<% content = `ps -d -o pid,user,pcpu,pmem,state,time,args --sort pcpu | sed '/^ 0.0 /d' | tail -n 30` %>
|
2
|
+
<% if @type == 'text' then %>
|
3
|
+
<%= content.split("\n").reverse.join("\n") %>
|
4
|
+
<% elsif @type == 'json' %>
|
5
|
+
<% content = content.split("\n")[1..-1].reverse %>
|
6
|
+
<% keys = ['pid','user','cpu_percent','mem_percent','state','cpu_time','command'] %>
|
7
|
+
<% require 'json'; struct = Array.new %>
|
8
|
+
<% content.each do |process| %>
|
9
|
+
<% process = process.split %>
|
10
|
+
<% values = process[0..5] %>
|
11
|
+
<% values << process[6..-1].join(' ') %>
|
12
|
+
<% struct << Hash[*keys.zip(values).flatten] %>
|
13
|
+
<% end%>
|
14
|
+
<%= JSON.pretty_generate struct %>
|
15
|
+
<% else %>
|
16
|
+
<div style="font-size:160%"><strong>Process CPU Usage</strong></div>
|
17
|
+
<table>
|
18
|
+
<thead>
|
19
|
+
<tr>
|
20
|
+
<th>Process ID</th>
|
21
|
+
<th>User</th>
|
22
|
+
<th>CPU %</th>
|
23
|
+
<th>Memory %</th>
|
24
|
+
<th>State</th>
|
25
|
+
<th>CPU Time</th>
|
26
|
+
<th>Command</th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<% content.split("\n")[1..-1].reverse.each do |process| %>
|
31
|
+
<% process = process.split %>
|
32
|
+
<tr>
|
33
|
+
<td><%= process[0..5].join('</td><td>') %></td>
|
34
|
+
<td><span style="font-size:80%"><%= process[6..-1].join(' ')%></span></td>
|
35
|
+
</tr>
|
36
|
+
<% end %>
|
37
|
+
</tbody>
|
38
|
+
</table>
|
39
|
+
<% end %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<% content = `ss -ar` %>
|
2
|
+
<% if @type == 'text' then %>
|
3
|
+
<%= content %>
|
4
|
+
<% elsif @type == 'json' %>
|
5
|
+
<% content = content.split("\n")[1..-1] %>
|
6
|
+
<% keys = ['state','recive_queue','send_queue','local_address','peer_address'] %>
|
7
|
+
<% require 'json'; struct = Array.new %>
|
8
|
+
<% content.each do |values| %>
|
9
|
+
<% struct << Hash[*keys.zip(values.split).flatten] %>
|
10
|
+
<% end %>
|
11
|
+
<%= JSON.pretty_generate struct %>
|
12
|
+
<% else %>
|
13
|
+
<div style="font-size:160%"><strong>System Sockets</strong></div>
|
14
|
+
<table>
|
15
|
+
<thead>
|
16
|
+
<tr>
|
17
|
+
<th>State</td>
|
18
|
+
<th>Recv-Q</th>
|
19
|
+
<th>Send-Q</th>
|
20
|
+
<th>Local Address:Port</th>
|
21
|
+
<th>Peer Address:Port</th>
|
22
|
+
</tr>
|
23
|
+
</thead>
|
24
|
+
<tbody>
|
25
|
+
<% content.split("\n")[1..-1].each do |line| %>
|
26
|
+
<tr>
|
27
|
+
<td><%= line.split.join("</td>\n<td>") %></td>
|
28
|
+
</tr>
|
29
|
+
<% end %>
|
30
|
+
</tbody>
|
31
|
+
</table>
|
32
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<%= erb "template/header".to_sym %>
|
4
|
+
<title><%= @target.capitalize %></title>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<form action="/<%= @target %>" method='get' style="top">
|
8
|
+
<%= erb "template/navigation".to_sym %>
|
9
|
+
<div id="toggle" class="options">
|
10
|
+
<%= erb "template/options/#{@target}".to_sym %>
|
11
|
+
<div class="submitter">
|
12
|
+
<button class="primary" type="submit"/>Show</button>
|
13
|
+
<button type="button" onClick="toggleCancel()">Cancel</button>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</form>
|
17
|
+
<div class='content'>
|
18
|
+
<%= yield %>
|
19
|
+
</div>
|
20
|
+
</body>
|
21
|
+
</html>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<ul>
|
2
|
+
<li>
|
3
|
+
<div class="label">Select data source:</div>
|
4
|
+
<select name="display">
|
5
|
+
<% for source in @data %>
|
6
|
+
<option><%= source %></option>
|
7
|
+
<% end %>
|
8
|
+
</select>
|
9
|
+
</li>
|
10
|
+
<li>
|
11
|
+
<div class="label">Select output format:</div>
|
12
|
+
<select name="format">
|
13
|
+
<option>text</option>
|
14
|
+
<option>json</option>
|
15
|
+
</select>
|
16
|
+
</li>
|
17
|
+
<li>
|
18
|
+
<div class="label">Values of the last:</div>
|
19
|
+
<input type="text" name="last" value="12h"/>
|
20
|
+
<div class="explain">(s)econds (h)ours (d)ays (w)eeks</div>
|
21
|
+
</li>
|
22
|
+
<li>
|
23
|
+
<div class="label">Data accumulation function:</div>
|
24
|
+
<select name="function">
|
25
|
+
<option>max</option>
|
26
|
+
<option>min</option>
|
27
|
+
<option>average</option>
|
28
|
+
<option>last</option>
|
29
|
+
</select>
|
30
|
+
</li>
|
31
|
+
</ul>
|