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,193 @@
1
+
2
+ require 'spec_helper'
3
+
4
+ describe PerfMonger::Command::SummaryCommand do
5
+ before(:each) do
6
+ @summary = PerfMonger::Command::SummaryCommand.new
7
+ @logfile = data_file('test.log')
8
+ @logfile_2devices = data_file('2devices.log')
9
+ end
10
+
11
+ describe 'read_logfile method' do
12
+ it 'should return 3 valid records' do
13
+ records = @summary.read_logfile(@logfile)
14
+ records.size.should == 3
15
+ records.each do |record|
16
+ record.should be_a Hash
17
+ record.should include "time"
18
+
19
+ record.should include "ioinfo"
20
+ record["ioinfo"].should include "devices"
21
+ record["ioinfo"]["devices"].should be_a Array
22
+ record["ioinfo"]["devices"].should include "sda"
23
+ record["ioinfo"].should include "sda"
24
+ record["ioinfo"]["sda"].should be_a Hash
25
+ record["ioinfo"]["sda"].should include "riops"
26
+ record["ioinfo"]["sda"].should include "wiops"
27
+ record["ioinfo"]["sda"].should include "rsecps"
28
+ record["ioinfo"]["sda"].should include "wsecps"
29
+ record["ioinfo"]["sda"].should include "r_await"
30
+ record["ioinfo"]["sda"].should include "w_await"
31
+
32
+ record.should include "cpuinfo"
33
+ record["cpuinfo"].should be_a Hash
34
+ record["cpuinfo"].should include "nr_cpu"
35
+ record["cpuinfo"].should include "cpus"
36
+ record["cpuinfo"].should include "all"
37
+ end
38
+ end
39
+ end
40
+
41
+ describe 'make_summary method' do
42
+ before(:each) do
43
+ @records = @summary.read_logfile(@logfile)
44
+ end
45
+
46
+ it 'should return nil for empty records' do
47
+ @summary.make_summary([]).should be_nil
48
+ end
49
+
50
+ it 'should return valid format result' do
51
+ summary = @summary.make_summary(@records)
52
+
53
+ summary.should be_a Hash
54
+ summary.should include "time"
55
+
56
+ summary.should include "ioinfo"
57
+ summary["ioinfo"].should include "devices"
58
+ summary["ioinfo"]["devices"].should be_a Array
59
+ summary["ioinfo"]["devices"].should include "sda"
60
+ summary["ioinfo"].should include "sda"
61
+ summary["ioinfo"]["sda"].should be_a Hash
62
+ summary["ioinfo"]["sda"].should include "riops"
63
+ summary["ioinfo"]["sda"].should include "wiops"
64
+ summary["ioinfo"]["sda"].should include "rsecps"
65
+ summary["ioinfo"]["sda"].should include "wsecps"
66
+ summary["ioinfo"]["sda"].should include "r_await"
67
+ summary["ioinfo"]["sda"].should include "w_await"
68
+
69
+ summary.should include "cpuinfo"
70
+ summary["cpuinfo"].should include "nr_cpu"
71
+ summary["cpuinfo"].should include "cpus"
72
+ summary["cpuinfo"].should include "all"
73
+ cpu_entries = [summary["cpuinfo"]["all"], *summary["cpuinfo"]["cpus"]]
74
+ cpu_entries.each do |entry|
75
+ entry.should be_a Hash
76
+ entry.should include "usr"
77
+ entry.should include "nice"
78
+ entry.should include "sys"
79
+ entry.should include "iowait"
80
+ entry.should include "irq"
81
+ entry.should include "soft"
82
+ entry.should include "steal"
83
+ entry.should include "guest"
84
+ entry.should include "idle"
85
+ end
86
+ end
87
+
88
+ it 'should calculate avg. IOPS correctly against non-equal intervals' do
89
+ @records[0]["time"] = 0.0
90
+ @records[1]["time"] = 1.0
91
+ @records[2]["time"] = 3.0
92
+
93
+ @records[0]["ioinfo"]["sda"]["riops"] = 0.0 # no effect for result
94
+ @records[1]["ioinfo"]["sda"]["riops"] = 3.0
95
+ @records[2]["ioinfo"]["sda"]["riops"] = 6.0
96
+
97
+ # avg. riops should be ((3.0 * 1.0 + 6.0 * 3.0) / 3.0) == 5.0
98
+ summary = @summary.make_summary(@records)
99
+
100
+ summary["ioinfo"]["sda"]["riops"].should be_within(5.0e-6).of(5.0)
101
+ end
102
+
103
+ it 'should return 0.0 for r_await if all values are zero' do
104
+ @records[0]["ioinfo"]["sda"]["r_await"] = 0.0
105
+ @records[1]["ioinfo"]["sda"]["r_await"] = 0.0
106
+ @records[2]["ioinfo"]["sda"]["r_await"] = 0.0
107
+
108
+ summary = @summary.make_summary(@records)
109
+
110
+ summary["ioinfo"]["sda"]["r_await"].should == 0.0
111
+ end
112
+
113
+ it 'should calculate avg. r_await/w_await correctly' do
114
+ @records[0]["ioinfo"]["sda"]["riops"] = 0.0
115
+ @records[0]["ioinfo"]["sda"]["r_await"] = 0.0
116
+ @records[1]["ioinfo"]["sda"]["riops"] = 100.0
117
+ @records[1]["ioinfo"]["sda"]["r_await"] = 1.0
118
+ @records[2]["ioinfo"]["sda"]["riops"] = 200.0
119
+ @records[2]["ioinfo"]["sda"]["r_await"] = 4.0
120
+
121
+ summary = @summary.make_summary(@records)
122
+
123
+ summary["ioinfo"]["sda"]["r_await"].should be_within(3.0e-6).of(3.0)
124
+ end
125
+ end
126
+
127
+ describe 'make_summary method with 2 devices' do
128
+ before(:each) do
129
+ @records = @summary.read_logfile(@logfile_2devices)
130
+ end
131
+
132
+ it 'should calculate avg. riops in total' do
133
+ @records[0]["time"] = 0.0
134
+ @records[1]["time"] = 0.5
135
+
136
+ @records[0]["ioinfo"]["total"]["riops"] = 0.0
137
+ @records[1]["ioinfo"]["total"]["riops"] = 10.0
138
+
139
+ summary = @summary.make_summary(@records)
140
+
141
+ summary["ioinfo"]["total"]["riops"].should be_within(10.0e-6).of(10.0)
142
+ end
143
+ end
144
+
145
+ it "should respond to make_accumulation" do
146
+ @summary.should respond_to(:make_accumulation)
147
+ end
148
+
149
+ describe "make_accumulation" do
150
+ before(:each) do
151
+ @records = @summary.read_logfile(@logfile)
152
+ end
153
+
154
+ it "should return valid format" do
155
+ accum = @summary.make_accumulation(@records)
156
+ accum.should be_a Hash
157
+ accum.keys.should include "ioinfo"
158
+ # accum.keys.should include "cpuinfo"
159
+ end
160
+
161
+ it "should return nil if no ioinfo" do
162
+ @records.each do |record|
163
+ record.delete("ioinfo")
164
+ end
165
+
166
+ @summary.make_accumulation(@records).should be_nil
167
+ end
168
+
169
+ it "should return nil if only 1 record given" do
170
+ @summary.make_accumulation([@records.first]).should be_nil
171
+ end
172
+
173
+ it "should return valid IO data volume accumulation" do
174
+ @records[0]["time"] = 0.0
175
+ @records[0]["ioinfo"]["sda"]["riops"] = 0.0
176
+ @records[0]["ioinfo"]["sda"]["rsecps"] = 0.0
177
+ @records[0]["ioinfo"]["sda"]["avgrq-sz"] = 16.0
178
+ @records[1]["time"] = 2.0
179
+ @records[1]["ioinfo"]["sda"]["riops"] = 2.0
180
+ @records[1]["ioinfo"]["sda"]["rsecps"] = 2.0
181
+ @records[1]["ioinfo"]["sda"]["avgrq-sz"] = 16.0
182
+ @records[2]["time"] = 4.0
183
+ @records[2]["ioinfo"]["sda"]["riops"] = 1.0
184
+ @records[2]["ioinfo"]["sda"]["rsecps"] = 4.0
185
+ @records[2]["ioinfo"]["sda"]["avgrq-sz"] = 16.0
186
+
187
+ accum = @summary.make_accumulation(@records)
188
+
189
+ accum["ioinfo"]["sda"]["read_requests"].should be_within(6.0e-6).of(6.0)
190
+ accum["ioinfo"]["sda"]["read_bytes"].should be_within(1e-6).of(6144.0)
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,145 @@
1
+
2
+ #include "test.h"
3
+ #include <perfmonger.h>
4
+
5
+
6
+ /* global variables */
7
+
8
+ int argc;
9
+ char **argv;
10
+
11
+ /* utility function proto */
12
+
13
+ void setup_arguments(const char *arg, ...);
14
+
15
+ /* test function proto */
16
+ void test_parse_args (void);
17
+ void test_parse_args_switches(void);
18
+
19
+ /* cutter setup/teardown */
20
+
21
+ void
22
+ cut_setup(void)
23
+ {
24
+ argc = 0;
25
+ argv = NULL;
26
+ }
27
+
28
+ void
29
+ cut_teardown(void)
30
+ {
31
+
32
+ }
33
+
34
+ /* utility function bodies */
35
+
36
+ void
37
+ setup_arguments(const char *arg, ...)
38
+ {
39
+ va_list ap;
40
+
41
+ argc = 1;
42
+ argv = malloc(sizeof(char *));
43
+ argv[0] = (char *) arg;
44
+
45
+ va_start(ap, arg);
46
+ while((arg = va_arg(ap, char *)) != NULL) {
47
+ argv = realloc(argv, sizeof(char *) * (argc + 1));
48
+ argv[argc ++] = (char *) arg;
49
+ }
50
+ va_end(ap);
51
+
52
+ cut_take_memory(argv);
53
+ }
54
+
55
+ /* test function bodies */
56
+
57
+ void
58
+ test_parse_args(void)
59
+ {
60
+ option_t option;
61
+
62
+ setup_arguments("collector", NULL);
63
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
64
+
65
+ /* show help and exit */
66
+ setup_arguments("collector", "-h", NULL);
67
+ cut_assert_equal_int(-1, parse_args(argc, argv, &option));
68
+
69
+ /* check -d option and default values */
70
+ setup_arguments("collector", "-d", "/path/to/dev", NULL);
71
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
72
+ cut_assert_equal_int(1, option.nr_dev);
73
+ cut_assert_equal_string("/path/to/dev", option.dev_list[0]);
74
+ cut_assert_equal_double(1.0, 0.0001, option.interval);
75
+ cut_assert_false(option.report_cpu);
76
+ cut_assert_true(option.report_io);
77
+ cut_assert_false(option.verbose);
78
+
79
+ /* with multiple devices */
80
+ setup_arguments("collector", "-d", "/path/to/dev0", "-d", "/path/to/dev1", NULL);
81
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
82
+ cut_assert_equal_int(2, option.nr_dev);
83
+ cut_assert_equal_string("/path/to/dev0", option.dev_list[0]);
84
+ cut_assert_equal_string("/path/to/dev1", option.dev_list[1]);
85
+ cut_assert_true(option.report_io);
86
+
87
+ /* with interval in integer */
88
+ setup_arguments("collector", "-d", "/path/to/dev", "-i", "10", NULL);
89
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
90
+ cut_assert_equal_double(10.0, 0.0001, option.interval);
91
+ cut_assert_true(option.report_io);
92
+
93
+ /* with interval in floating point */
94
+ setup_arguments("collector", "-d", "/path/to/dev", "-i", "0.5", NULL);
95
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
96
+ cut_assert_equal_double(0.5, 0.0001, option.interval);
97
+ cut_assert_true(option.report_io);
98
+
99
+ /* with verbose */
100
+ setup_arguments("collector", "-d", "/path/to/dev", "-v", NULL);
101
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
102
+ cut_assert_true(option.verbose);
103
+ cut_assert_true(option.report_io);
104
+ }
105
+
106
+ void
107
+ test_parse_args_switches(void)
108
+ {
109
+ option_t option;
110
+
111
+ /* with cpu (default if no device is specified) */
112
+ setup_arguments("collector", NULL);
113
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
114
+ cut_assert_true (option.report_cpu);
115
+ cut_assert_false(option.report_io);
116
+ cut_assert_false(option.report_ctxsw);
117
+
118
+ /* without cpu if some devices are specified */
119
+ setup_arguments("collector", "-d", "/path/to/dev", NULL);
120
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
121
+ cut_assert_false(option.report_cpu);
122
+ cut_assert_true (option.report_io);
123
+ cut_assert_false(option.report_ctxsw);
124
+
125
+ /* with cpu if explicitly specified by -C */
126
+ setup_arguments("collector", "-C", "-d", "/path/to/dev", NULL);
127
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
128
+ cut_assert_true (option.report_cpu);
129
+ cut_assert_true (option.report_io);
130
+ cut_assert_false(option.report_ctxsw);
131
+
132
+ /* without cpu if context switch option is specified */
133
+ setup_arguments("collector", "-S", NULL);
134
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
135
+ cut_assert_false(option.report_cpu);
136
+ cut_assert_false(option.report_io);
137
+ cut_assert_true (option.report_ctxsw);
138
+
139
+ /* with cpu if explicitly specified by -C */
140
+ setup_arguments("collector", "-C", "-S", NULL);
141
+ cut_assert_equal_int(0, parse_args(argc, argv, &option));
142
+ cut_assert_true (option.report_cpu);
143
+ cut_assert_false(option.report_io);
144
+ cut_assert_true (option.report_ctxsw);
145
+ }
data/test/test.h ADDED
@@ -0,0 +1,9 @@
1
+ #ifndef TEST_H
2
+ #define TEST_H
3
+
4
+ #include <cutter.h>
5
+ #include <gcutter.h>
6
+ #include <glib.h>
7
+
8
+
9
+ #endif
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: perfmonger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.1
5
+ platform: ruby
6
+ authors:
7
+ - Yuto HAYAMIZU
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: yet anothor performance measurement/monitoring tool
56
+ email: y.hayamizu@gmail.com
57
+ executables:
58
+ - perfmonger
59
+ extensions:
60
+ - ext/perfmonger/extconf.rb
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .dir-locals.el
64
+ - .gitignore
65
+ - .rspec
66
+ - .travis.yml
67
+ - COPYING
68
+ - Gemfile
69
+ - HOWTO.md
70
+ - NEWS
71
+ - README.md
72
+ - Rakefile
73
+ - bin/perfmonger
74
+ - data/NOTICE
75
+ - data/Twitter_Bootstrap_LICENSE.txt
76
+ - data/assets/css/bootstrap-responsive.css
77
+ - data/assets/css/bootstrap.css
78
+ - data/assets/css/perfmonger.css
79
+ - data/assets/dashboard.erb
80
+ - data/assets/img/glyphicons-halflings-white.png
81
+ - data/assets/img/glyphicons-halflings.png
82
+ - data/assets/js/bootstrap.js
83
+ - data/assets/js/bootstrap.min.js
84
+ - data/assets/js/canvasjs.js
85
+ - data/assets/js/canvasjs.min.js
86
+ - data/sysstat.ioconf
87
+ - ext/perfmonger/extconf.rb
88
+ - ext/perfmonger/perfmonger.h
89
+ - ext/perfmonger/perfmonger_record.c
90
+ - ext/perfmonger/sysstat/common.c
91
+ - ext/perfmonger/sysstat/common.h
92
+ - ext/perfmonger/sysstat/ioconf.c
93
+ - ext/perfmonger/sysstat/ioconf.h
94
+ - ext/perfmonger/sysstat/iostat.c
95
+ - ext/perfmonger/sysstat/iostat.h
96
+ - ext/perfmonger/sysstat/libsysstat.h
97
+ - ext/perfmonger/sysstat/mpstat.c
98
+ - ext/perfmonger/sysstat/mpstat.h
99
+ - ext/perfmonger/sysstat/rd_stats.c
100
+ - ext/perfmonger/sysstat/rd_stats.h
101
+ - ext/perfmonger/sysstat/sysconfig.h
102
+ - lib/perfmonger.rb
103
+ - lib/perfmonger/cli.rb
104
+ - lib/perfmonger/command/base_command.rb
105
+ - lib/perfmonger/command/fingerprint.rb
106
+ - lib/perfmonger/command/plot.rb
107
+ - lib/perfmonger/command/record.rb
108
+ - lib/perfmonger/command/record_option.rb
109
+ - lib/perfmonger/command/server.rb
110
+ - lib/perfmonger/command/stat.rb
111
+ - lib/perfmonger/command/stat_option.rb
112
+ - lib/perfmonger/command/summary.rb
113
+ - lib/perfmonger/config.rb
114
+ - lib/perfmonger/version.rb
115
+ - misc/release-howto.txt
116
+ - misc/sample-cpu.png
117
+ - misc/sample-read-iops.png
118
+ - perfmonger.gemspec
119
+ - test/run-test.sh
120
+ - test/spec/bin_spec.rb
121
+ - test/spec/data/2devices.expected
122
+ - test/spec/data/2devices.output
123
+ - test/spec/spec_helper.rb
124
+ - test/spec/summary_spec.rb
125
+ - test/test-perfmonger.c
126
+ - test/test.h
127
+ homepage: http://github.com/hayamiz/perfmonger/
128
+ licenses:
129
+ - GPL-2
130
+ metadata: {}
131
+ post_install_message: ! "\n============================================================\n\nThank
132
+ you for installing perfmonger.\nTry to start performance monitoring with:\n\n perfmonger
133
+ record\n\nEnjoy.\n\n============================================================\n\n"
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: 1.9.0
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ! '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.4.5
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: yet anothor performance measurement/monitoring tool
153
+ test_files: []
154
+ has_rdoc: