ifttt-gdash 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/lib/gdash.rb +56 -0
- data/lib/gdash/dashboard.rb +52 -0
- data/lib/gdash/monkey_patches.rb +37 -0
- data/lib/gdash/sinatra_app.rb +202 -0
- data/public/js/bootstrap-alerts.js +104 -0
- data/public/js/bootstrap-dropdown.js +50 -0
- data/public/js/bootstrap-modal.js +238 -0
- data/public/js/bootstrap-popover.js +77 -0
- data/public/js/bootstrap-scrollspy.js +105 -0
- data/public/js/bootstrap-tabs.js +62 -0
- data/public/js/bootstrap-twipsy.js +307 -0
- data/public/js/jquery-1.5.2.min.js +16 -0
- data/public/js/jquery.tablesorter.min.js +4 -0
- data/public/js/less-1.1.3.min.js +16 -0
- data/public/lib/bootstrap.less +26 -0
- data/public/lib/forms.less +465 -0
- data/public/lib/mixins.less +217 -0
- data/public/lib/patterns.less +1006 -0
- data/public/lib/reset.less +141 -0
- data/public/lib/scaffolding.less +135 -0
- data/public/lib/tables.less +170 -0
- data/public/lib/type.less +187 -0
- data/public/lib/variables.less +60 -0
- data/sample/README.md +5 -0
- data/sample/email-full-screen.png +0 -0
- data/sample/email.png +0 -0
- data/sample/email/cpu.graph +19 -0
- data/sample/email/dash.yaml +2 -0
- data/sample/email/io.graph +12 -0
- data/sample/email/load.graph +6 -0
- data/sample/email/network.graph +11 -0
- data/views/README.md +177 -0
- data/views/_interval_filter.erb +5 -0
- data/views/dashboard.erb +47 -0
- data/views/detailed_dashboard.erb +45 -0
- data/views/full_size_dashboard.erb +36 -0
- data/views/index.erb +18 -0
- data/views/layout.erb +66 -0
- metadata +55 -17
@@ -0,0 +1,60 @@
|
|
1
|
+
/* Variables.less
|
2
|
+
* Variables to customize the look and feel of Bootstrap
|
3
|
+
* ----------------------------------------------------- */
|
4
|
+
|
5
|
+
|
6
|
+
// Links
|
7
|
+
@linkColor: #0069d6;
|
8
|
+
@linkColorHover: darken(@linkColor, 15);
|
9
|
+
|
10
|
+
// Grays
|
11
|
+
@black: #000;
|
12
|
+
@grayDark: lighten(@black, 25%);
|
13
|
+
@gray: lighten(@black, 50%);
|
14
|
+
@grayLight: lighten(@black, 75%);
|
15
|
+
@grayLighter: lighten(@black, 90%);
|
16
|
+
@white: #fff;
|
17
|
+
|
18
|
+
// Accent Colors
|
19
|
+
@blue: #049CDB;
|
20
|
+
@blueDark: #0064CD;
|
21
|
+
@green: #46a546;
|
22
|
+
@red: #9d261d;
|
23
|
+
@yellow: #ffc40d;
|
24
|
+
@orange: #f89406;
|
25
|
+
@pink: #c3325f;
|
26
|
+
@purple: #7a43b6;
|
27
|
+
|
28
|
+
// Baseline grid
|
29
|
+
@basefont: 13px;
|
30
|
+
@baseline: 18px;
|
31
|
+
|
32
|
+
// Griditude
|
33
|
+
// Modify the grid styles in mixins.less
|
34
|
+
@gridColumns: 16;
|
35
|
+
@gridColumnWidth: 60px;
|
36
|
+
@gridGutterWidth: 10px;
|
37
|
+
@extraSpace: (@gridGutterWidth * 2); // For our grid calculations
|
38
|
+
@siteWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1));
|
39
|
+
|
40
|
+
// Color Scheme
|
41
|
+
// Use this to roll your own color schemes if you like (unused by Bootstrap by default)
|
42
|
+
@baseColor: @blue; // Set a base color
|
43
|
+
@complement: spin(@baseColor, 180); // Determine a complementary color
|
44
|
+
@split1: spin(@baseColor, 158); // Split complements
|
45
|
+
@split2: spin(@baseColor, -158);
|
46
|
+
@triad1: spin(@baseColor, 135); // Triads colors
|
47
|
+
@triad2: spin(@baseColor, -135);
|
48
|
+
@tetra1: spin(@baseColor, 90); // Tetra colors
|
49
|
+
@tetra2: spin(@baseColor, -90);
|
50
|
+
@analog1: spin(@baseColor, 22); // Analogs colors
|
51
|
+
@analog2: spin(@baseColor, -22);
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
// More variables coming soon:
|
56
|
+
// - @basefont to @baseFontSize
|
57
|
+
// - @baseline to @baseLineHeight
|
58
|
+
// - @baseFontFamily
|
59
|
+
// - @primaryButtonColor
|
60
|
+
// - anything else? File an issue on GitHub
|
data/sample/README.md
ADDED
Binary file
|
data/sample/email.png
ADDED
Binary file
|
@@ -0,0 +1,19 @@
|
|
1
|
+
title "Combined CPU Usage"
|
2
|
+
vtitle "percent"
|
3
|
+
area :stacked
|
4
|
+
description "The combined CPU usage for all Exim Anti Spam servers"
|
5
|
+
|
6
|
+
field :iowait, :scale => 0.001,
|
7
|
+
:color => "red",
|
8
|
+
:alias => "IO Wait",
|
9
|
+
:data => "sumSeries(derivative(mw*.munin.cpu.iowait))"
|
10
|
+
|
11
|
+
field :system, :scale => 0.001,
|
12
|
+
:color => "orange",
|
13
|
+
:alias => "System",
|
14
|
+
:data => "sumSeries(derivative(mw*.munin.cpu.system))"
|
15
|
+
|
16
|
+
field :user, :scale => 0.001,
|
17
|
+
:color => "yellow",
|
18
|
+
:alias => "User",
|
19
|
+
:data => "sumSeries(derivative(mw*.munin.cpu.user))"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
title "Combined IO"
|
2
|
+
area :first
|
3
|
+
vtitle "blocks"
|
4
|
+
|
5
|
+
field :down, :color => "blue",
|
6
|
+
:alias => "Writes",
|
7
|
+
:data => "sumSeries(derivative(mw*.munin.iostat.dev*_write))"
|
8
|
+
|
9
|
+
field :up, :color => "green",
|
10
|
+
:alias => "Reads",
|
11
|
+
:data => "sumSeries(derivative(mw*.munin.iostat.dev*_read))"
|
12
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
title "Combined Network Usage"
|
2
|
+
vtitle "bps"
|
3
|
+
area :first
|
4
|
+
|
5
|
+
field :up, :color => "green",
|
6
|
+
:alias => "Up",
|
7
|
+
:data => "sumSeries(nonNegativeDerivative(mw*.munin.if_*.up))"
|
8
|
+
|
9
|
+
field :down, :color => "blue",
|
10
|
+
:alias => "Down",
|
11
|
+
:data => "sumSeries(nonNegativeDerivative(mw*.munin.if_*.down))"
|
data/views/README.md
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
What?
|
2
|
+
=====
|
3
|
+
|
4
|
+
A simple Graphite dashboard built using Twitter's Bootstrap.
|
5
|
+
|
6
|
+
Adding new dashboards is very easy and individual graphs are
|
7
|
+
described using a small DSL.
|
8
|
+
|
9
|
+
See the _sample_ directory for a sample dashboard configuration.
|
10
|
+
|
11
|
+
![Sample dashboard](https://github.com/ripienaar/gdash/raw/master/sample/email.png)
|
12
|
+
|
13
|
+
Config?
|
14
|
+
-------
|
15
|
+
|
16
|
+
This dashboard is a Sinatra application, I suggest deploying it
|
17
|
+
in Passenger or other Sinatra application server.
|
18
|
+
|
19
|
+
A sample _gdash.yaml-sample_ is included, you should rename it to
|
20
|
+
_gdash.yaml_ and adjust the url to your Graphite etc in there.
|
21
|
+
|
22
|
+
The SinatraApp class take two required arguments:
|
23
|
+
|
24
|
+
* Where graphite is installed
|
25
|
+
* The directory that has your _dashboards_ directory full of templates
|
26
|
+
|
27
|
+
and additional options:
|
28
|
+
|
29
|
+
* The title to show at the top of your Graphite
|
30
|
+
* A prefix to prepend to all URLs in the dashboard
|
31
|
+
* How many columns of graphs to create, 2 by default.
|
32
|
+
* How often dashboard page is refreshed, 60 sec by default.
|
33
|
+
* The width of the graphs, 500 by default
|
34
|
+
* The height of the graphs, 250 by default
|
35
|
+
* Where your whisper files are stored - future use
|
36
|
+
* Optional interval quick filters
|
37
|
+
|
38
|
+
Creating Dashboards?
|
39
|
+
--------------------
|
40
|
+
|
41
|
+
You can have multiple top level categories of dashboard. Just create directories
|
42
|
+
in the _templatedir_ for each top level category.
|
43
|
+
|
44
|
+
In each top level category create a sub directory with a short name for each new dashboard.
|
45
|
+
|
46
|
+
You need a file called _dash.yaml_ for each dashboard, here is a sample:
|
47
|
+
|
48
|
+
:name: Email Metrics
|
49
|
+
:description: Hourly metrics for the email system
|
50
|
+
|
51
|
+
Then create descriptions in files like _cpu.graph_ in the same directory, here
|
52
|
+
is a sample:
|
53
|
+
|
54
|
+
title "Combined CPU Usage"
|
55
|
+
vtitle "percent"
|
56
|
+
area :stacked
|
57
|
+
description "The combined CPU usage for all Exim Anti Spam servers"
|
58
|
+
|
59
|
+
field :iowait, :scale => 0.001,
|
60
|
+
:color => "red",
|
61
|
+
:alias => "IO Wait",
|
62
|
+
:data => "sumSeries(derivative(mw*munin.cpu.iowait))"
|
63
|
+
|
64
|
+
field :system, :scale => 0.001,
|
65
|
+
:color => "orange",
|
66
|
+
:alias => "System",
|
67
|
+
:data => "sumSeries(derivative(mw*.munin.cpu.system))"
|
68
|
+
|
69
|
+
field :user, :scale => 0.001,
|
70
|
+
:color => "yellow",
|
71
|
+
:alias => "User",
|
72
|
+
:data => "sumSeries(derivative(mw*.munin.cpu.user))"
|
73
|
+
|
74
|
+
The dashboard will use the _description_ field to show popup information bubbles
|
75
|
+
when someone hovers over a graph with their mouse for 2 seconds.
|
76
|
+
|
77
|
+
The graphs are described using a DSL that has its own project and documented
|
78
|
+
over at https://github.com/ripienaar/graphite-graph-dsl/wiki
|
79
|
+
|
80
|
+
At the moment we do not support the _Related Items_ feature of the DSL.
|
81
|
+
|
82
|
+
Template Directory Layout?
|
83
|
+
--------------------------
|
84
|
+
|
85
|
+
The directory layout is such that you can have many groupins of dashboards each with
|
86
|
+
many dashboards underneath it, an example layout of your templates dir would be:
|
87
|
+
|
88
|
+
graph_templates
|
89
|
+
`-- virtualization
|
90
|
+
|-- dom0
|
91
|
+
| |-- dash.yaml
|
92
|
+
| |-- iowait.graph
|
93
|
+
| |-- load.graph
|
94
|
+
| |-- system.graph
|
95
|
+
| |-- threads.graph
|
96
|
+
| `-- user.graph
|
97
|
+
`-- kvm1
|
98
|
+
|-- dash.yaml
|
99
|
+
|-- disk_read.graph
|
100
|
+
|-- disk_write.graph
|
101
|
+
|-- ssd_read.graph
|
102
|
+
`-- ssd_write.graph
|
103
|
+
|
104
|
+
Here we have a group of dashboards called 'virtualization' with 2 dashboards inside it
|
105
|
+
each with numerous graphs.
|
106
|
+
|
107
|
+
You can create as many groups as you want each with many dashboards inside.
|
108
|
+
|
109
|
+
Custom Time Intervals?
|
110
|
+
--------------------
|
111
|
+
|
112
|
+
You can reuse your dashboards and adjust the time interval by using the following url
|
113
|
+
structure:
|
114
|
+
|
115
|
+
http://gdash.example.com/dashboard/email/time/-8d/-7d
|
116
|
+
|
117
|
+
or
|
118
|
+
|
119
|
+
http://gdash.example.com/dashboard/email/?from=-8d&until=-7d
|
120
|
+
http://gdash.example.com/dashboard/email/full/2/600/300?from=-8d&until=-7d
|
121
|
+
|
122
|
+
This will display the _email_ dashboard with a time interval same day last week.
|
123
|
+
If you hit */dashboard/email/time/* it will default to the past hour (*-1hour*)
|
124
|
+
See http://graphite.readthedocs.org/en/1.0/url-api.html#from-until for more info
|
125
|
+
acceptable *from* and *until* values.
|
126
|
+
|
127
|
+
Quick interval filters shown in interface are configurable in _gdash.yaml_ options sections. Eg:
|
128
|
+
|
129
|
+
:options:
|
130
|
+
:interval_filters:
|
131
|
+
- :label: Last Hour
|
132
|
+
:from: -1h
|
133
|
+
:to: now
|
134
|
+
- :label: Last Day
|
135
|
+
:from: -1day
|
136
|
+
- :label: Current Week
|
137
|
+
:from: monday
|
138
|
+
:to: now
|
139
|
+
|
140
|
+
Quick filter is not shown when *interval_filters* section is missing in configuration file.
|
141
|
+
|
142
|
+
Time Intervals Display?
|
143
|
+
-----------------------
|
144
|
+
|
145
|
+
If you configure time intervals in the config file you can click on any graph in
|
146
|
+
the main dashboard view and get a view with different time intervals of the same
|
147
|
+
graph
|
148
|
+
|
149
|
+
:options:
|
150
|
+
:intervals:
|
151
|
+
- [ "-1hour", "1 hour" ]
|
152
|
+
- [ "-2hour", "2 hour" ]
|
153
|
+
- [ "-1day", "1 day" ]
|
154
|
+
- [ "-1month", "1 month" ]
|
155
|
+
- [ "-1year", "1 year" ]
|
156
|
+
|
157
|
+
With this in place in the _config.yaml_ clicking on a graph will show the 5 intervals
|
158
|
+
defined above of that graph
|
159
|
+
|
160
|
+
Full Screen Displays?
|
161
|
+
---------------------
|
162
|
+
|
163
|
+
You can reuse your dashboards for big displays against a wall in your NOC or office
|
164
|
+
by using the following url structure:
|
165
|
+
|
166
|
+
http://gdash.example.com/dashboard/email/full/4/600/300
|
167
|
+
http://gdash.example.com/dashboard/email/full/4?width=600&height=300
|
168
|
+
|
169
|
+
This will display the _email_ dashboard in _4_ columns each graph with a width of
|
170
|
+
_600_ and a height of _300_
|
171
|
+
|
172
|
+
The screen will refresh every minute
|
173
|
+
|
174
|
+
Contact?
|
175
|
+
--------
|
176
|
+
|
177
|
+
R.I.Pienaar / rip@devco.net / http://www.devco.net/ / @ripienaar
|
data/views/dashboard.erb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
<% unless @error %>
|
2
|
+
<%= dashboard_preheader %>
|
3
|
+
<h1><%= @dashboard.name %> <small><%= @dashboard.description %></small></h1>
|
4
|
+
<%= dashboard_header %>
|
5
|
+
<%= erb :_interval_filter, :layout => false unless @interval_filters.empty? %>
|
6
|
+
<div class="row">
|
7
|
+
<table>
|
8
|
+
<% row = 1 %>
|
9
|
+
<% grouped_graphs = @dashboard.graphs.in_groups_of(@graph_columns) %>
|
10
|
+
<% grouped_graphs.each do |graphs| %>
|
11
|
+
<tr>
|
12
|
+
<% graphs.each do |graph| %>
|
13
|
+
<% i = grouped_graphs.rindex(graphs) * @graph_columns + graphs.rindex(graph) %>
|
14
|
+
<td>
|
15
|
+
<% if graph %>
|
16
|
+
<% if graph[:graphite][:description] %>
|
17
|
+
<a href='<%= uri_to_details(i) %>'>
|
18
|
+
<img src='<%= [@top_level[@params[:category]].graphite_render, graph[:graphite][:url].to_s.force_encoding('UTF-8')].join "?" %>' rel="<%= row == 1 ? 'popover-below' : 'popover-above' %>" title="<%= graph[:graphite][:title] %>" data-content="<%= graph[:graphite][:description] %>"></a>
|
19
|
+
<% else %>
|
20
|
+
<a href='<%= uri_to_details(i) %>'>
|
21
|
+
<img src='<%= [@top_level[@params[:category]].graphite_render, graph[:graphite][:url]].join "?" %>'></a>
|
22
|
+
<% end %>
|
23
|
+
<%= graph_caption(graph) %>
|
24
|
+
<% end %>
|
25
|
+
</td>
|
26
|
+
<% end %>
|
27
|
+
</tr>
|
28
|
+
<% row += 1 %>
|
29
|
+
<% end %>
|
30
|
+
</table>
|
31
|
+
</div>
|
32
|
+
<script>
|
33
|
+
$(function () {
|
34
|
+
$("img[rel=popover-above]")
|
35
|
+
.popover({
|
36
|
+
placement: "above", delayIn: 1000
|
37
|
+
})
|
38
|
+
})
|
39
|
+
|
40
|
+
$(function () {
|
41
|
+
$("img[rel=popover-below]")
|
42
|
+
.popover({
|
43
|
+
placement: "below", delayIn: 1000
|
44
|
+
})
|
45
|
+
})
|
46
|
+
</script>
|
47
|
+
<% end %>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<% unless @error %>
|
2
|
+
<h1><%= @dashboard.name %> <small><%= @dashboard.description %></small></h1>
|
3
|
+
<div class="row">
|
4
|
+
<table>
|
5
|
+
<% row = 1 %>
|
6
|
+
<% @graphs.in_groups_of(@graph_columns) do |graphrows| %>
|
7
|
+
<tr>
|
8
|
+
<% graphrows.each do |graph| %>
|
9
|
+
<td>
|
10
|
+
<% if graph %>
|
11
|
+
<% if graph[:description] %>
|
12
|
+
<img src='<%= [@top_level[@params[:category]].graphite_render, graph[:url]].join "?" %>' rel="<%= row == 1 ? 'popover-below' : 'popover-above' %>" title="<%= graph[:title] %>" data-content="<%= graph[:description] %>">
|
13
|
+
<% else %>
|
14
|
+
<img src='<%= [@top_level[@params[:category]].graphite_render, graph[:url]].join "?" %>'>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
</td>
|
18
|
+
<% end %>
|
19
|
+
</tr>
|
20
|
+
<% row += 1 %>
|
21
|
+
<% end %>
|
22
|
+
</table>
|
23
|
+
</div>
|
24
|
+
<script>
|
25
|
+
$(function () {
|
26
|
+
$("img[rel=popover-above]")
|
27
|
+
.popover({
|
28
|
+
placement: "above", delayIn: 1000
|
29
|
+
})
|
30
|
+
.click(function(e) {
|
31
|
+
e.preventDefault()
|
32
|
+
})
|
33
|
+
})
|
34
|
+
|
35
|
+
$(function () {
|
36
|
+
$("img[rel=popover-below]")
|
37
|
+
.popover({
|
38
|
+
placement: "below", delayIn: 1000
|
39
|
+
})
|
40
|
+
.click(function(e) {
|
41
|
+
e.preventDefault()
|
42
|
+
})
|
43
|
+
})
|
44
|
+
</script>
|
45
|
+
<% end %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<script src="<%= @prefix %>/js/jquery-1.5.2.min.js"></script>
|
4
|
+
</head>
|
5
|
+
<% if @error %>
|
6
|
+
<h2><%= @error %></h2>
|
7
|
+
<% else %>
|
8
|
+
<body bgcolor="black">
|
9
|
+
<table width="100%" height="100%">
|
10
|
+
<% @dashboard.graphs.in_groups_of(params["columns"]) do |graphs| %>
|
11
|
+
<tr>
|
12
|
+
<% graphs.each do |graph| %>
|
13
|
+
<td valign="middle" align="center">
|
14
|
+
<% if graph %>
|
15
|
+
<img src='<%= [@top_level[@params[:category]].graphite_render, graph[:graphite][:url]].join "?" %>'>
|
16
|
+
<% end %>
|
17
|
+
</td>
|
18
|
+
<% end %>
|
19
|
+
</tr>
|
20
|
+
<% end %>
|
21
|
+
</table>
|
22
|
+
<script>
|
23
|
+
$(document).ready(function() {
|
24
|
+
setInterval(reloadDash, <%= @refresh_rate * 1000 %>);
|
25
|
+
});
|
26
|
+
function reloadDash() {
|
27
|
+
var now = new Date();
|
28
|
+
$('img').each(function(index) {
|
29
|
+
var url = $(this).attr('src').replace(/&\d+$/, '');
|
30
|
+
$(this).attr('src', url + '&' + now.getTime());
|
31
|
+
});
|
32
|
+
}
|
33
|
+
</script>
|
34
|
+
</body>
|
35
|
+
<% end %>
|
36
|
+
</html>
|