perfmonger 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +15 -0
  2. data/.dir-locals.el +2 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +12 -0
  6. data/COPYING +674 -0
  7. data/Gemfile +5 -0
  8. data/HOWTO.md +15 -0
  9. data/NEWS +115 -0
  10. data/README.md +61 -0
  11. data/Rakefile +8 -0
  12. data/bin/perfmonger +6 -0
  13. data/data/NOTICE +8 -0
  14. data/data/Twitter_Bootstrap_LICENSE.txt +176 -0
  15. data/data/assets/css/bootstrap-responsive.css +1109 -0
  16. data/data/assets/css/bootstrap.css +6167 -0
  17. data/data/assets/css/perfmonger.css +17 -0
  18. data/data/assets/dashboard.erb +319 -0
  19. data/data/assets/img/glyphicons-halflings-white.png +0 -0
  20. data/data/assets/img/glyphicons-halflings.png +0 -0
  21. data/data/assets/js/bootstrap.js +2280 -0
  22. data/data/assets/js/bootstrap.min.js +6 -0
  23. data/data/assets/js/canvasjs.js +9042 -0
  24. data/data/assets/js/canvasjs.min.js +271 -0
  25. data/data/sysstat.ioconf +268 -0
  26. data/ext/perfmonger/extconf.rb +19 -0
  27. data/ext/perfmonger/perfmonger.h +58 -0
  28. data/ext/perfmonger/perfmonger_record.c +754 -0
  29. data/ext/perfmonger/sysstat/common.c +627 -0
  30. data/ext/perfmonger/sysstat/common.h +207 -0
  31. data/ext/perfmonger/sysstat/ioconf.c +515 -0
  32. data/ext/perfmonger/sysstat/ioconf.h +84 -0
  33. data/ext/perfmonger/sysstat/iostat.c +1100 -0
  34. data/ext/perfmonger/sysstat/iostat.h +121 -0
  35. data/ext/perfmonger/sysstat/libsysstat.h +19 -0
  36. data/ext/perfmonger/sysstat/mpstat.c +953 -0
  37. data/ext/perfmonger/sysstat/mpstat.h +79 -0
  38. data/ext/perfmonger/sysstat/rd_stats.c +2388 -0
  39. data/ext/perfmonger/sysstat/rd_stats.h +651 -0
  40. data/ext/perfmonger/sysstat/sysconfig.h +13 -0
  41. data/lib/perfmonger/cli.rb +115 -0
  42. data/lib/perfmonger/command/base_command.rb +39 -0
  43. data/lib/perfmonger/command/fingerprint.rb +453 -0
  44. data/lib/perfmonger/command/plot.rb +429 -0
  45. data/lib/perfmonger/command/record.rb +32 -0
  46. data/lib/perfmonger/command/record_option.rb +149 -0
  47. data/lib/perfmonger/command/server.rb +294 -0
  48. data/lib/perfmonger/command/stat.rb +60 -0
  49. data/lib/perfmonger/command/stat_option.rb +29 -0
  50. data/lib/perfmonger/command/summary.rb +402 -0
  51. data/lib/perfmonger/config.rb +6 -0
  52. data/lib/perfmonger/version.rb +5 -0
  53. data/lib/perfmonger.rb +12 -0
  54. data/misc/release-howto.txt +17 -0
  55. data/misc/sample-cpu.png +0 -0
  56. data/misc/sample-read-iops.png +0 -0
  57. data/perfmonger.gemspec +44 -0
  58. data/test/run-test.sh +39 -0
  59. data/test/spec/bin_spec.rb +37 -0
  60. data/test/spec/data/2devices.expected +42 -0
  61. data/test/spec/data/2devices.output +42 -0
  62. data/test/spec/spec_helper.rb +20 -0
  63. data/test/spec/summary_spec.rb +193 -0
  64. data/test/test-perfmonger.c +145 -0
  65. data/test/test.h +9 -0
  66. metadata +154 -0
@@ -0,0 +1,17 @@
1
+ /*!
2
+ * PerfMonger Monitor CSS
3
+ *
4
+ * Copyright 2013, Yuto HAYAMIZU <y.hayamizu@gmail.com>
5
+ * Licensed under GPLv3
6
+ *
7
+ */
8
+
9
+ div.perfmonger-graph {
10
+ width: 100%;
11
+ height: 90%;
12
+ }
13
+
14
+ section.graph-wrapper {
15
+ padding-top: 30px;
16
+ padding-bottom: 60px;
17
+ }
@@ -0,0 +1,319 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>PerfMonger Realtime Monitor: <%= hostname %></title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta name="description" content="">
8
+ <meta name="author" content="">
9
+
10
+ <!-- Le styles -->
11
+ <link href="../assets/css/perfmonger.css" rel="stylesheet">
12
+ <link href="../assets/css/bootstrap.css" rel="stylesheet">
13
+ <style type="text/css">
14
+ body {
15
+ padding-top: 60px;
16
+ padding-bottom: 40px;
17
+ }
18
+ </style>
19
+ <link href="../assets/css/bootstrap-responsive.css" rel="stylesheet">
20
+
21
+ <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
22
+ <!--[if lt IE 9]>
23
+ <script src="../assets/js/html5shiv.js"></script>
24
+ <![endif]-->
25
+
26
+ <!-- Fav and touch icons -->
27
+ <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../assets/ico/apple-touch-icon-144-precomposed.png">
28
+ <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../assets/ico/apple-touch-icon-114-precomposed.png">
29
+ <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../assets/ico/apple-touch-icon-72-precomposed.png">
30
+ <link rel="apple-touch-icon-precomposed" href="../assets/ico/apple-touch-icon-57-precomposed.png">
31
+ <link rel="shortcut icon" href="../assets/ico/favicon.png">
32
+ </head>
33
+
34
+ <body>
35
+
36
+ <div class="navbar navbar-inverse navbar-fixed-top">
37
+ <div class="navbar-inner">
38
+ <div class="container">
39
+ <a class="brand" href="#">PerfMonger Realtime Monitor: <%= hostname %></a>
40
+ <!--
41
+ <div class="nav-collapse collapse">
42
+ <ul class="nav">
43
+ <li class="active"><a href="#">Home</a></li>
44
+ <li><a href="#about">About</a></li>
45
+ <li><a href="#contact">Contact</a></li>
46
+ </ul>
47
+ </div><!--/.nav-collapse -->
48
+ -->
49
+ </div>
50
+ </div>
51
+ </div>
52
+
53
+ <div class="container">
54
+ <div class="row">
55
+ <div class="span3">
56
+ <div class="well sidebar-nav affix">
57
+ <ul class="nav nav-list">
58
+ <% if report_cpu %>
59
+ <li><a href="#cpu_section">CPU usage</a></li>
60
+ <% end %>
61
+ <% devices.each do |dev| %>
62
+ <% edev = escape_device_name(dev) %>
63
+ <li><a href="#<%= edev %>_iops_section"><code><%= dev %></code>: IOPS</a></li>
64
+ <li><a href="#<%= edev %>_throughput_section"><code><%= dev %></code>: I/O throughput</a></li>
65
+ <% end %>
66
+ </ul>
67
+ </div>
68
+ </div> <!-- div.well -->
69
+ <% graph_divs = ['cpu_graph'] %>
70
+
71
+ <div class="span9">
72
+ <% if report_cpu %>
73
+ <section id="cpu_section" class="graph-wrapper">
74
+ <div id="cpu_graph" class="perfmonger-graph"></div>
75
+ </section>
76
+ <% end %>
77
+
78
+ <% devices.each do |dev| %>
79
+ <% edev = escape_device_name(dev) %>
80
+ <% graph_divs.push(edev + "_iops_graph") %>
81
+ <% graph_divs.push(edev + "_throughput_graph") %>
82
+
83
+ <section id="<%= edev %>_iops_section" class="graph-wrapper">
84
+ <div id="<%= edev %>_iops_graph" class="perfmonger-graph"></div>
85
+ </section>
86
+
87
+ <section id="<%= edev %>_throughput_section" class="graph-wrapper">
88
+ <div id="<%= edev %>_throughput_graph" class="perfmonger-graph"></div>
89
+ </section>
90
+ <% end %>
91
+ </div> <!-- /span9 -->
92
+ </div> <!-- /row -->
93
+ </div> <!-- /container -->
94
+
95
+ <!-- Le javascript
96
+ ================================================== -->
97
+ <!-- Placed at the end of the document so the pages load faster -->
98
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
99
+ <script src="../assets/js/bootstrap.js"></script>
100
+ <script src="../assets/js/canvasjs.min.js"></script>
101
+
102
+
103
+ <script>
104
+ var records = [];
105
+
106
+ var sector2mb = 512 / 1024.0 / 1024.0;
107
+
108
+ function fitGraphHeight() {
109
+ var new_height = $(window).height() - 60;
110
+ <% graph_divs.each do |graph_div| %>
111
+ $('div#<%= graph_div %>').height(new_height);
112
+ <% end %>
113
+ }
114
+
115
+ $(window).resize(function() {
116
+ fitGraphHeight();
117
+ });
118
+ fitGraphHeight();
119
+
120
+ <% if report_cpu %>
121
+ var cpu_usr_data = [{x: new Date(new Date() - 1000), y: 0.0}];
122
+ var cpu_sys_data = [{x: new Date(new Date() - 1000), y: 0.0}];
123
+ var cpu_other_data = [{x: new Date(new Date() - 1000), y: 0.0}];
124
+ var cpu_chart = new CanvasJS.Chart("cpu_graph",
125
+ {
126
+ title:{
127
+ text: "CPU usage",
128
+ },
129
+ toolTip: {
130
+ enabled: false,
131
+ },
132
+ axisX: {
133
+ valueFormatString: "HH:mm:ss",
134
+ interval:5,
135
+ intervalType: "second",
136
+ },
137
+ axisY:{
138
+ suffix: "%",
139
+ includeZero: true,
140
+ },
141
+ data: [
142
+ {
143
+ type: "stackedArea",
144
+ showInLegend: true,
145
+ name: "%usr",
146
+ dataPoints: cpu_usr_data
147
+ },{
148
+ type: "stackedArea",
149
+ showInLegend: true,
150
+ name: "%sys",
151
+ dataPoints: cpu_sys_data
152
+ },{
153
+ type: "stackedArea",
154
+ showInLegend: true,
155
+ name: "%other",
156
+ dataPoints: cpu_other_data
157
+ },
158
+ ]
159
+ });
160
+ cpu_chart.render();
161
+ <% end %>
162
+
163
+ <% devices.each do |dev| %>
164
+ <% edev = escape_device_name(dev) %>
165
+ var <%= edev %>_riops_data = [{x: new Date(new Date() - 1000), y: 0.0}];
166
+ var <%= edev %>_wiops_data = [{x: new Date(new Date() - 1000), y: 0.0}];
167
+ var <%= edev %>_rthroughput_data = [{x: new Date(new Date() - 1000), y: 0.0}];
168
+ var <%= edev %>_wthroughput_data = [{x: new Date(new Date() - 1000), y: 0.0}];
169
+
170
+ var <%= edev %>_iops_chart = new CanvasJS.Chart("<%= edev %>_iops_graph",
171
+ {
172
+ title:{
173
+ text: "<%= dev %>: I/O per second",
174
+ },
175
+ toolTip: {
176
+ enabled: false,
177
+ },
178
+ axisX: {
179
+ valueFormatString: "HH:mm:ss",
180
+ interval:5,
181
+ intervalType: "second",
182
+ },
183
+ axisY:{
184
+ title: "# of I/O [1/sec]",
185
+ includeZero: true,
186
+ },
187
+ data: [
188
+ {
189
+ type: "line",
190
+ showInLegend: true,
191
+ name: "Read IOPS",
192
+ dataPoints: <%= edev %>_riops_data
193
+ },{
194
+ type: "line",
195
+ showInLegend: true,
196
+ name: "Write IOPS",
197
+ dataPoints: <%= edev %>_wiops_data
198
+ },
199
+ ]
200
+ });
201
+ <%= edev %>_iops_chart.render();
202
+
203
+ var <%= edev %>_throughput_chart = new CanvasJS.Chart("<%= edev %>_throughput_graph",
204
+ {
205
+ title:{
206
+ text: "<%= dev %>: I/O throughput",
207
+ },
208
+ toolTip: {
209
+ enabled: false,
210
+ },
211
+ axisX: {
212
+ valueFormatString: "HH:mm:ss",
213
+ interval:5,
214
+ intervalType: "second",
215
+ },
216
+ axisY:{
217
+ title: "throughput [MB/s]",
218
+ includeZero: true,
219
+ },
220
+ data: [
221
+ {
222
+ type: "line",
223
+ showInLegend: true,
224
+ name: "Read throughput",
225
+ dataPoints: <%= edev %>_rthroughput_data
226
+ },{
227
+ type: "line",
228
+ showInLegend: true,
229
+ name: "Write throughput",
230
+ dataPoints: <%= edev %>_wthroughput_data
231
+ },
232
+ ]
233
+ });
234
+ <%= edev %>_throughput_chart.render();
235
+ <% end %>
236
+
237
+ function render_all() {
238
+ <% if report_cpu %>
239
+ cpu_chart.render();
240
+ <% end %>
241
+
242
+ <% devices.each do |dev| %>
243
+ <% edev = escape_device_name(dev) %>
244
+ <%= edev %>_iops_chart.render();
245
+ <%= edev %>_throughput_chart.render();
246
+ <% end %>
247
+ }
248
+
249
+ function add_record(record) {
250
+ if (records.length > 0 && records[records.length - 1]['time'] >= record) {
251
+ // old or duplicate record received
252
+ return;
253
+ }
254
+ records.push(record);
255
+
256
+ var t = new Date(record['time'] * 1000);
257
+
258
+ <% if report_cpu %>
259
+ var cpu_record = record['cpuinfo']['all'];
260
+ var cpu_usr = cpu_record['usr'] + cpu_record['nice'];
261
+ var cpu_sys = cpu_record['sys'];
262
+ var cpu_other = 100.0 - cpu_record['idle'] - cpu_usr - cpu_sys;
263
+ if (cpu_other < 0.0) cpu_other = 0.0;
264
+
265
+ cpu_usr_data.push({x: t, y: cpu_usr});
266
+ cpu_sys_data.push({x: t, y: cpu_sys});
267
+ cpu_other_data.push({x: t, y: cpu_other});
268
+ <% end %>
269
+
270
+ <% devices.each do |dev| %>
271
+ <% edev = escape_device_name(dev) %>
272
+ <%= edev %>_riops_data.push({x: t, y: record['ioinfo']['<%= dev %>']['riops']});
273
+ <%= edev %>_wiops_data.push({x: t, y: record['ioinfo']['<%= dev %>']['wiops']});
274
+
275
+ <%= edev %>_rthroughput_data.push({x: t, y: record['ioinfo']['<%= dev %>']['rsecps'] * sector2mb});
276
+ <%= edev %>_wthroughput_data.push({x: t, y: record['ioinfo']['<%= dev %>']['wsecps'] * sector2mb});
277
+ <% end %>
278
+
279
+ last_record = records[records.length - 1];
280
+
281
+ while (records[0]['time'] < last_record['time'] - 30.0) {
282
+ records.shift();
283
+
284
+ <% if report_cpu %>
285
+ cpu_usr_data.shift();
286
+ cpu_sys_data.shift();
287
+ cpu_other_data.shift();
288
+ <% end %>
289
+
290
+ <% devices.each do |dev| %>
291
+ <% edev = escape_device_name(dev) %>
292
+ <%= edev %>_riops_data.shift();
293
+ <%= edev %>_wiops_data.shift();
294
+
295
+ <%= edev %>_rthroughput_data.shift();
296
+ <%= edev %>_wthroughput_data.shift();
297
+ <% end %>
298
+ }
299
+
300
+ render_all();
301
+ }
302
+
303
+ var handleMessage = function handleMessage( evt ) {
304
+ var record = JSON.parse(evt.data);
305
+ if (record['ioinfo'] != null) {
306
+ add_record(record);
307
+ }
308
+ };
309
+ var handleEnd = function handleEnd( evt ) {
310
+ evt.currentTarget.close();
311
+ }
312
+
313
+ var source = new EventSource( '/faucet' );
314
+ source.addEventListener( 'message', handleMessage, false );
315
+ source.addEventListener( 'end' , handleEnd , false );
316
+
317
+ </script>
318
+ </body>
319
+ </html>