httperfrb 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/Gemfile +3 -5
  2. data/HISTORY.md +5 -0
  3. data/README.md +65 -1
  4. data/lib/httperf.rb +15 -3
  5. data/lib/parser.rb +116 -0
  6. metadata +12 -11
data/Gemfile CHANGED
@@ -2,11 +2,9 @@ source :rubygems
2
2
  gem 'open4'
3
3
 
4
4
  group :development do
5
- gem 'yard'
6
- gem 'redcarpet'
7
- end
8
-
9
- group :test do
10
5
  gem 'rspec'
11
6
  gem 'simplecov'
7
+ gem 'yard'
8
+ gem 'redcarpet'
9
+ gem 'rake'
12
10
  end
data/HISTORY.md CHANGED
@@ -1,6 +1,11 @@
1
1
  HTTPerf.rb
2
2
  ==========
3
3
 
4
+ ### 0.2.0
5
+
6
+ * added parser
7
+ * changed default output of run to parsed
8
+
4
9
  ### 0.1.2
5
10
 
6
11
  * fixed an issue with run output
data/README.md CHANGED
@@ -31,7 +31,7 @@ Requires httperf, of course...
31
31
 
32
32
  gem install httperfrb
33
33
 
34
- #### Usage
34
+ ### Usage
35
35
 
36
36
  Some basic usage examples.
37
37
 
@@ -48,5 +48,69 @@ Some basic usage examples.
48
48
  unless perf.fork_err.nil?
49
49
  puts perf.fork_out
50
50
  end
51
+
52
+ #### With HTTPerf::Parser
53
+
54
+ require 'httperf'
55
+ perf = HTTPerf.new( "server" => "host", "port" => 8080, "uri" => "/foo" )
56
+ puts perf.parser = true
57
+ puts perf.run
58
+
59
+ # or directly
60
+
61
+ puts HTTPerf::Parser.parse( HTTPerf.new( "server" => "host", "port" => 8080, "uri" => "/foo" ).run )
62
+
63
+ ##### Parser Keys:
64
+
65
+ :command
66
+ :max_connect_burst_length
67
+ :total_connections
68
+ :total_requests
69
+ :total_replies
70
+ :total_test_duration
71
+ :connection_rate_per_sec
72
+ :connection_rate_ms_conn
73
+ :connection_time_min
74
+ :connection_time_avg
75
+ :connection_time_max
76
+ :connection_time_median
77
+ :connection_time_stddev
78
+ :connection_time_connect
79
+ :connection_length
80
+ :request_rate_per_sec
81
+ :request_rate_ms_request
82
+ :request_size
83
+ :reply_rate_min
84
+ :reply_rate_avg
85
+ :reply_rate_max
86
+ :reply_rate_stddev
87
+ :reply_rate_samples
88
+ :reply_time_response
89
+ :reply_time_transfer
90
+ :reply_size_header
91
+ :reply_size_content
92
+ :reply_size_footer
93
+ :reply_size_total
94
+ :reply_status_1xx
95
+ :reply_status_2xx
96
+ :reply_status_3xx
97
+ :reply_status_4xx
98
+ :reply_status_5xx
99
+ :cpu_time_user_sec
100
+ :cpu_time_system_sec
101
+ :cpu_time_user_pct
102
+ :cpu_time_system_pct
103
+ :cpu_time_total_pct
104
+ :net_io_kb_sec
105
+ :net_io_bps
106
+ :errors_total
107
+ :errors_client_timeout
108
+ :errors_socket_timeout
109
+ :errors_conn_refused
110
+ :errors_conn_reset
111
+ :errors_fd_unavail
112
+ :errors_addr_unavail
113
+ :errors_ftab_full
114
+ :errors_other
51
115
 
52
116
 
data/lib/httperf.rb CHANGED
@@ -1,8 +1,12 @@
1
1
  # @author Joshua Mervine <joshua@mervine.net>
2
2
  require 'open4'
3
+ require 'parser'
3
4
  class HTTPerf
4
5
  # gem version
5
- VERSION = "0.1.2"
6
+ VERSION = "0.2.0"
7
+
8
+ # @return [Boolean] parse flag
9
+ attr_accessor :parse
6
10
 
7
11
  # availbe instance methods
8
12
  @fork_out, @fork_err = ''
@@ -84,7 +88,11 @@ class HTTPerf
84
88
  status = wait_thr.value
85
89
  end
86
90
  if status == 0
87
- return out.join
91
+ if @parse
92
+ return Parser.parse(out.join)
93
+ else
94
+ return out.join
95
+ end
88
96
  else
89
97
  return err.join
90
98
  end
@@ -100,7 +108,11 @@ class HTTPerf
100
108
 
101
109
  # return results of last fork
102
110
  def fork_out
103
- @fork_out
111
+ if @parse
112
+ return Parse.parse @fork_out
113
+ else
114
+ return @fork_out
115
+ end
104
116
  end
105
117
 
106
118
  # return errors from last fork
data/lib/parser.rb ADDED
@@ -0,0 +1,116 @@
1
+ class HTTPerf
2
+
3
+ # Parse httperf output to a [Hash]
4
+ #
5
+ # This can be used standalone or with HTTPerf results.
6
+ class Parser
7
+
8
+ # @return [Hash] returns hash of parsed httperf output
9
+ # @param [String] raw httperf output
10
+ def self.parse raw
11
+
12
+ lines = raw.split("\n")
13
+
14
+ # While this isn't the most efficent way of doing this, it's the most maintainable.
15
+ expressions = {
16
+ :command => /^(httperf .+)$/,
17
+
18
+ # Maximum connect burst length:
19
+ :max_connect_burst_length => /Maximum connect burst length: ([0-9]*?\.?[0-9]+)$/,
20
+
21
+ # Total:
22
+ :total_connections => /^Total: connections ([0-9]*?\.?[0-9]+) /,
23
+ :total_requests => /^Total: connections .+ requests ([0-9]*?\.?[0-9]+) /,
24
+ :total_replies => /^Total: connections .+ replies ([0-9]*?\.?[0-9]+) /,
25
+ :total_test_duration => /^Total: connections .+ test-duration ([0-9]*?\.?[0-9]+) /,
26
+
27
+ # Connection rate:
28
+ :connection_rate_per_sec => /^Connection rate: ([0-9]*?\.?[0-9]+) /,
29
+ :connection_rate_ms_conn => /^Connection rate: .+ \(([0-9]*?\.?[0-9]+) ms/,
30
+
31
+ # Connection time [ms]:
32
+ :connection_time_min => /^Connection time \[ms\]: min ([0-9]*?\.?[0-9]+) /,
33
+ :connection_time_avg => /^Connection time \[ms\]: min .+ avg ([0-9]*?\.?[0-9]+) /,
34
+ :connection_time_max => /^Connection time \[ms\]: min .+ max ([0-9]*?\.?[0-9]+) /,
35
+ :connection_time_median => /^Connection time \[ms\]: min .+ median ([0-9]*?\.?[0-9]+) /,
36
+ :connection_time_stddev => /^Connection time \[ms\]: min .+ stddev ([0-9]*?\.?[0-9]+)$/,
37
+ :connection_time_connect => /^Connection time \[ms\]: connect ([0-9]*?\.?[0-9]+)$/,
38
+
39
+ # Connection length [replies/conn]:
40
+ :connection_length => /^Connection length \[replies\/conn\]: ([0-9]*?\.?[0-9]+)$/,
41
+
42
+ # Request rate:
43
+ :request_rate_per_sec => /^Request rate: ([0-9]*?\.?[0-9]+) req/,
44
+ :request_rate_ms_request => /^Request rate: .+ \(([0-9]*?\.?[0-9]+) ms/,
45
+
46
+ # Request size [B]:
47
+ :request_size => /^Request size \[B\]: ([0-9]*?\.?[0-9]+)$/,
48
+
49
+ # Reply rate [replies/s]:
50
+ :reply_rate_min => /^Reply rate \[replies\/s\]: min ([0-9]*?\.?[0-9]+) /,
51
+ :reply_rate_avg => /^Reply rate \[replies\/s\]: min .+ avg ([0-9]*?\.?[0-9]+) /,
52
+ :reply_rate_max => /^Reply rate \[replies\/s\]: min .+ max ([0-9]*?\.?[0-9]+) /,
53
+ :reply_rate_stddev => /^Reply rate \[replies\/s\]: min .+ stddev ([0-9]*?\.?[0-9]+) /,
54
+ :reply_rate_samples => /^Reply rate \[replies\/s\]: min .+ \(([0-9]*?\.?[0-9]+) samples/,
55
+
56
+ # Reply time [ms]:
57
+ :reply_time_response => /^Reply time \[ms\]: response ([0-9]*?\.?[0-9]+) /,
58
+ :reply_time_transfer => /^Reply time \[ms\]: response .+ transfer ([0-9]*?\.?[0-9]+)$/,
59
+
60
+ # Reply size [B]:
61
+ :reply_size_header => /^Reply size \[B\]: header ([0-9]*?\.?[0-9]+) /,
62
+ :reply_size_content => /^Reply size \[B\]: header .+ content ([0-9]*?\.?[0-9]+) /,
63
+ :reply_size_footer => /^Reply size \[B\]: header .+ footer ([0-9]*?\.?[0-9]+) /,
64
+ :reply_size_total => /^Reply size \[B\]: header .+ \(total ([0-9]*?\.?[0-9]+)\)/,
65
+
66
+ # Reply status:
67
+ :reply_status_1xx => /^Reply status: 1xx=([0-9]*?\.?[0-9]+) /,
68
+ :reply_status_2xx => /^Reply status: .+ 2xx=([0-9]*?\.?[0-9]+) /,
69
+ :reply_status_3xx => /^Reply status: .+ 3xx=([0-9]*?\.?[0-9]+) /,
70
+ :reply_status_4xx => /^Reply status: .+ 4xx=([0-9]*?\.?[0-9]+) /,
71
+ :reply_status_5xx => /^Reply status: .+ 5xx=([0-9]*?\.?[0-9]+)/,
72
+
73
+ # CPU time [s]:
74
+ :cpu_time_user_sec => /^CPU time \[s\]: user ([0-9]*?\.?[0-9]+) /,
75
+ :cpu_time_system_sec => /^CPU time \[s\]: user .+ system ([0-9]*?\.?[0-9]+) /,
76
+ :cpu_time_user_pct => /^CPU time \[s\]: user .+ \(user ([0-9]*?\.?[0-9]+)\% /,
77
+ :cpu_time_system_pct => /^CPU time \[s\]: user .+ system .+ system ([0-9]*?\.?[0-9]+)\% /,
78
+ :cpu_time_total_pct => /^CPU time \[s\]: user .+ total ([0-9]*?\.?[0-9]+)\%/,
79
+
80
+ # Net I/O:
81
+ :net_io_kb_sec => /^Net I\/O: ([0-9]*?\.?[0-9]+) KB/,
82
+ :net_io_bps => /^Net I\/O: .+ \((.+) bps\)/,
83
+
84
+ # Errors:
85
+ :errors_total => /^Errors: total ([0-9]*?\.?[0-9]+) /,
86
+ :errors_client_timeout => /^Errors: total .+ client-timo ([0-9]*?\.?[0-9]+) /,
87
+ :errors_socket_timeout => /^Errors: total .+ socket-timo ([0-9]*?\.?[0-9]+) /,
88
+ :errors_conn_refused => /^Errors: total .+ connrefused ([0-9]*?\.?[0-9]+) /,
89
+ :errors_conn_reset => /^Errors: total .+ connreset ([0-9]*?\.?[0-9]+)/,
90
+ :errors_fd_unavail => /^Errors: fd-unavail ([0-9]*?\.?[0-9]+) /,
91
+ :errors_addr_unavail => /^Errors: fd-unavail .+ addrunavail ([0-9]*?\.?[0-9]+) /,
92
+ :errors_ftab_full => /^Errors: fd-unavail .+ ftab-full ([0-9]*?\.?[0-9]+) /,
93
+ :errors_other => /^Errors: fd-unavail .+ other ([0-9]*?\.?[0-9]+)/
94
+ }
95
+
96
+ matches = {}
97
+
98
+ lines.each do |line|
99
+ matched = false
100
+ unless line.empty?
101
+ expressions.each do |key,exp|
102
+ matchdata = (exp.match(line)).to_a
103
+ if $1
104
+ matches[key] = $1
105
+ matched = true
106
+ next
107
+ end
108
+ end
109
+ next if matched
110
+ end
111
+ end
112
+ raise "mismatch error occurred" unless expressions.keys.count == matches.keys.count
113
+ return matches
114
+ end
115
+ end
116
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httperfrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-10 00:00:00.000000000Z
12
+ date: 2012-08-11 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &15314460 !ruby/object:Gem::Requirement
16
+ requirement: &19603340 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *15314460
24
+ version_requirements: *19603340
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: simplecov
27
- requirement: &15313820 !ruby/object:Gem::Requirement
27
+ requirement: &19602580 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *15313820
35
+ version_requirements: *19602580
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: yard
38
- requirement: &15313240 !ruby/object:Gem::Requirement
38
+ requirement: &19602060 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *15313240
46
+ version_requirements: *19602060
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: open4
49
- requirement: &15312020 !ruby/object:Gem::Requirement
49
+ requirement: &19601460 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *15312020
57
+ version_requirements: *19601460
58
58
  description: Simple interface for calling httperf via ruby.
59
59
  email:
60
60
  - joshua@mervine.net
@@ -62,6 +62,7 @@ executables: []
62
62
  extensions: []
63
63
  extra_rdoc_files: []
64
64
  files:
65
+ - lib/parser.rb
65
66
  - lib/httperf.rb
66
67
  - README.md
67
68
  - HISTORY.md
@@ -80,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
81
  version: '0'
81
82
  segments:
82
83
  - 0
83
- hash: -118998426605859077
84
+ hash: 1424181618950298738
84
85
  required_rubygems_version: !ruby/object:Gem::Requirement
85
86
  none: false
86
87
  requirements: