perfmonger 0.6.1

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