httperfrb 0.1.2 → 0.2.0

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 (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: