collectd-interface 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+

|
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>
|