httperfrb 0.2.0 → 0.2.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.
- data/HISTORY.md +5 -0
- data/README.md +27 -9
- data/lib/{parser.rb → httperf/parser.rb} +63 -20
- data/lib/httperf/version.rb +3 -0
- data/lib/httperf.rb +11 -6
- metadata +12 -11
    
        data/HISTORY.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            HTTPERF.rb
         | 
| 2 2 | 
             
            ==========
         | 
| 3 3 |  | 
| 4 | 
            -
            ### [Documentation](http://rubyops.github.com/httperfrb/doc/) | [Coverage](http://rubyops.github.com/httperfrb/coverage/) 
         | 
| 4 | 
            +
            ### [Documentation](http://rubyops.github.com/httperfrb/doc/) | [Coverage](http://rubyops.github.com/httperfrb/coverage/) | [RSpec Out](https://github.com/rubyops/httperfrb/blob/master/RSPECOUT.md)
         | 
| 5 5 |  | 
| 6 6 | 
             
            Simple Ruby interface for httperf.
         | 
| 7 7 |  | 
| @@ -10,28 +10,27 @@ Simple Ruby interface for httperf. | |
| 10 10 | 
             
            This currently needs a lot of work to be production ready. It's done more in a scripting style then a true solid application style. 
         | 
| 11 11 |  | 
| 12 12 |  | 
| 13 | 
            -
             | 
| 14 | 
            -
            ### Installing 'httperf'
         | 
| 13 | 
            +
            ## Installing 'httperf'
         | 
| 15 14 |  | 
| 16 15 | 
             
            Requires httperf, of course...
         | 
| 17 16 |  | 
| 18 | 
            -
             | 
| 17 | 
            +
            #### Mac
         | 
| 19 18 |  | 
| 20 19 | 
             
                sudo port install httperf
         | 
| 21 20 |  | 
| 22 | 
            -
             | 
| 21 | 
            +
            #### Debian / Ubuntu
         | 
| 23 22 |  | 
| 24 23 | 
             
                sudo apt-get install httperf
         | 
| 25 24 |  | 
| 26 | 
            -
             | 
| 25 | 
            +
            #### Redhat / CentOS
         | 
| 27 26 |  | 
| 28 27 | 
             
                sudo yum install httperf
         | 
| 29 28 |  | 
| 30 | 
            -
             | 
| 29 | 
            +
            ## Install
         | 
| 31 30 |  | 
| 32 31 | 
             
                gem install httperfrb
         | 
| 33 32 |  | 
| 34 | 
            -
             | 
| 33 | 
            +
            ## Usage - HTTPerf
         | 
| 35 34 |  | 
| 36 35 | 
             
            Some basic usage examples.
         | 
| 37 36 |  | 
| @@ -49,7 +48,7 @@ Some basic usage examples. | |
| 49 48 | 
             
                  puts perf.fork_out
         | 
| 50 49 | 
             
                end
         | 
| 51 50 |  | 
| 52 | 
            -
             | 
| 51 | 
            +
            ### With HTTPerf::Parser
         | 
| 53 52 |  | 
| 54 53 | 
             
                require 'httperf'
         | 
| 55 54 | 
             
                perf = HTTPerf.new( "server" => "host", "port" => 8080, "uri" => "/foo" )
         | 
| @@ -60,6 +59,17 @@ Some basic usage examples. | |
| 60 59 |  | 
| 61 60 | 
             
                puts HTTPerf::Parser.parse( HTTPerf.new( "server" => "host", "port" => 8080, "uri" => "/foo" ).run )
         | 
| 62 61 |  | 
| 62 | 
            +
            ## Useage - HTTPerf::Parser
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                require 'httperf/parser' 
         | 
| 65 | 
            +
                 
         | 
| 66 | 
            +
                # read result from a file, for example   
         | 
| 67 | 
            +
                puts HTTPerf.parse( File.open("httperf.out", "r").read )
         | 
| 68 | 
            +
                
         | 
| 69 | 
            +
                # or verbose output
         | 
| 70 | 
            +
                puts HTTPerf.parse( File.open("httperf_verbose.out", "r").read, true )
         | 
| 71 | 
            +
             | 
| 72 | 
            +
             | 
| 63 73 | 
             
            ##### Parser Keys: 
         | 
| 64 74 |  | 
| 65 75 | 
             
                :command
         | 
| @@ -114,3 +124,11 @@ Some basic usage examples. | |
| 114 124 | 
             
                :errors_other
         | 
| 115 125 |  | 
| 116 126 |  | 
| 127 | 
            +
            ##### Addtional Verbose Parser Keys: 
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                :connection_time_75_pct
         | 
| 130 | 
            +
                :connection_time_80_pct
         | 
| 131 | 
            +
                :connection_time_85_pct
         | 
| 132 | 
            +
                :connection_time_90_pct
         | 
| 133 | 
            +
                :connection_time_95_pct
         | 
| 134 | 
            +
                :connection_time_99_pct
         | 
| @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            #require 'parser/verbose'
         | 
| 1 2 | 
             
            class HTTPerf
         | 
| 2 3 |  | 
| 3 4 | 
             
              # Parse httperf output to a [Hash]
         | 
| @@ -5,14 +6,60 @@ class HTTPerf | |
| 5 6 | 
             
              # This can be used standalone or with HTTPerf results.
         | 
| 6 7 | 
             
              class Parser
         | 
| 7 8 |  | 
| 9 | 
            +
                attr_accessor :verbose
         | 
| 10 | 
            +
             | 
| 8 11 | 
             
                # @return [Hash] returns hash of parsed httperf output
         | 
| 9 12 | 
             
                # @param [String] raw httperf output
         | 
| 10 | 
            -
                def self.parse raw
         | 
| 13 | 
            +
                def self.parse raw, verbose=false
         | 
| 11 14 |  | 
| 12 15 | 
             
                  lines = raw.split("\n") 
         | 
| 16 | 
            +
                  matches = {}
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  # for verbose matching
         | 
| 19 | 
            +
                  verbose_connection_lifetime = []
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  lines.each do |line|
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    if verbose and verbose_expression.match(line)
         | 
| 24 | 
            +
                      verbose_connection_lifetime.push($1) 
         | 
| 25 | 
            +
                      next
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    matched = false
         | 
| 29 | 
            +
                    unless line.empty?
         | 
| 30 | 
            +
                      next if matched
         | 
| 31 | 
            +
                      expressions.each do |key,exp|
         | 
| 32 | 
            +
                        if exp.match(line) and $1
         | 
| 33 | 
            +
                          matches[key] = $1
         | 
| 34 | 
            +
                          matched = true
         | 
| 35 | 
            +
                        end
         | 
| 36 | 
            +
                      end
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 13 39 |  | 
| 40 | 
            +
                  unless verbose_connection_lifetime.empty?
         | 
| 41 | 
            +
                    percentiles.each do |percentile|
         | 
| 42 | 
            +
                      matches["connection_time_#{percentile}_pct".to_sym] = calculate_percentile(percentile, verbose_connection_lifetime)
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  if verbose
         | 
| 47 | 
            +
                    raise "mismatch error occurred" unless expressions.keys.count+percentiles.count == matches.keys.count
         | 
| 48 | 
            +
                  else
         | 
| 49 | 
            +
                    raise "mismatch error occurred" unless expressions.keys.count == matches.keys.count
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
                  return matches
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                protected
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def self.verbose_expression
         | 
| 57 | 
            +
                  /^Connection lifetime = ([0-9]*?\.?[0-9]+)$/
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def self.expressions
         | 
| 14 61 | 
             
                  # While this isn't the most efficent way of doing this, it's the most maintainable.
         | 
| 15 | 
            -
                   | 
| 62 | 
            +
                  {
         | 
| 16 63 | 
             
                    :command                    => /^(httperf .+)$/,
         | 
| 17 64 |  | 
| 18 65 | 
             
                    # Maximum connect burst length:
         | 
| @@ -92,25 +139,21 @@ class HTTPerf | |
| 92 139 | 
             
                    :errors_ftab_full           => /^Errors: fd-unavail .+ ftab-full ([0-9]*?\.?[0-9]+) /,
         | 
| 93 140 | 
             
                    :errors_other               => /^Errors: fd-unavail .+ other ([0-9]*?\.?[0-9]+)/
         | 
| 94 141 | 
             
                  }
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                  matches = {}
         | 
| 142 | 
            +
                end
         | 
| 97 143 |  | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
                    end
         | 
| 111 | 
            -
                  end
         | 
| 112 | 
            -
                  raise "mismatch error occurred" unless expressions.keys.count == matches.keys.count
         | 
| 113 | 
            -
                  return matches
         | 
| 144 | 
            +
                def self.percentiles
         | 
| 145 | 
            +
                  [ 75, 80, 85, 90, 95, 99 ]
         | 
| 146 | 
            +
                end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                private
         | 
| 149 | 
            +
                def self.calculate_percentile percentile, values
         | 
| 150 | 
            +
                  values.sort!
         | 
| 151 | 
            +
                  values[percentile_index(percentile, values.count)]
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                def self.percentile_index percentile, count
         | 
| 155 | 
            +
                  ((count/100)*percentile)-1
         | 
| 114 156 | 
             
                end
         | 
| 115 157 | 
             
              end
         | 
| 116 158 | 
             
            end
         | 
| 159 | 
            +
             | 
    
        data/lib/httperf.rb
    CHANGED
    
    | @@ -1,12 +1,11 @@ | |
| 1 1 | 
             
            # @author Joshua Mervine <joshua@mervine.net>
         | 
| 2 2 | 
             
            require 'open4'
         | 
| 3 | 
            -
            require 'parser'
         | 
| 3 | 
            +
            require 'httperf/parser'
         | 
| 4 | 
            +
            require 'httperf/version'
         | 
| 4 5 | 
             
            class HTTPerf
         | 
| 5 | 
            -
              # gem version
         | 
| 6 | 
            -
              VERSION = "0.2.0"
         | 
| 7 6 |  | 
| 8 7 | 
             
              # @return [Boolean] parse flag
         | 
| 9 | 
            -
              attr_accessor :parse
         | 
| 8 | 
            +
              attr_accessor :parse, :verbose
         | 
| 10 9 |  | 
| 11 10 | 
             
              # availbe instance methods
         | 
| 12 11 | 
             
              @fork_out, @fork_err = ''
         | 
| @@ -57,6 +56,8 @@ class HTTPerf | |
| 57 56 | 
             
              #   -  wsesslog
         | 
| 58 57 | 
             
              #   -  wset
         | 
| 59 58 | 
             
              def initialize options={}, path=nil
         | 
| 59 | 
            +
                self.parse = options.delete("parse") 
         | 
| 60 | 
            +
                self.verbose = true if options.has_key?("verbose")
         | 
| 60 61 | 
             
                options.each_key do |k|
         | 
| 61 62 | 
             
                  raise "'#{k}' is an invalid httperf param" unless params.keys.include?(k)
         | 
| 62 63 | 
             
                end
         | 
| @@ -89,7 +90,7 @@ class HTTPerf | |
| 89 90 | 
             
                end
         | 
| 90 91 | 
             
                if status == 0
         | 
| 91 92 | 
             
                  if @parse
         | 
| 92 | 
            -
                    return Parser.parse(out.join)
         | 
| 93 | 
            +
                    return Parser.parse(out.join, self.verbose)
         | 
| 93 94 | 
             
                  else
         | 
| 94 95 | 
             
                    return out.join
         | 
| 95 96 | 
             
                  end
         | 
| @@ -109,7 +110,7 @@ class HTTPerf | |
| 109 110 | 
             
              # return results of last fork
         | 
| 110 111 | 
             
              def fork_out
         | 
| 111 112 | 
             
                if @parse
         | 
| 112 | 
            -
                  return Parse.parse | 
| 113 | 
            +
                  return Parse.parse(@fork_out, self.parse)
         | 
| 113 114 | 
             
                else
         | 
| 114 115 | 
             
                  return @fork_out
         | 
| 115 116 | 
             
                end
         | 
| @@ -126,6 +127,10 @@ class HTTPerf | |
| 126 127 | 
             
                return "#{@command} #{options}"
         | 
| 127 128 | 
             
              end
         | 
| 128 129 |  | 
| 130 | 
            +
              def verbose
         | 
| 131 | 
            +
                @verbose||false
         | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
             | 
| 129 134 | 
             
              private
         | 
| 130 135 | 
             
              # build commandline options string
         | 
| 131 136 | 
             
              def options
         | 
    
        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.2. | 
| 4 | 
            +
              version: 0.2.1
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -13,7 +13,7 @@ date: 2012-08-11 00:00:00.000000000Z | |
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: rspec
         | 
| 16 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &13320100 !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: * | 
| 24 | 
            +
              version_requirements: *13320100
         | 
| 25 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 26 | 
             
              name: simplecov
         | 
| 27 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &13317140 !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: * | 
| 35 | 
            +
              version_requirements: *13317140
         | 
| 36 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 37 | 
             
              name: yard
         | 
| 38 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &13316620 !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: * | 
| 46 | 
            +
              version_requirements: *13316620
         | 
| 47 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 48 | 
             
              name: open4
         | 
| 49 | 
            -
              requirement: & | 
| 49 | 
            +
              requirement: &13316040 !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: * | 
| 57 | 
            +
              version_requirements: *13316040
         | 
| 58 58 | 
             
            description: Simple interface for calling httperf via ruby.
         | 
| 59 59 | 
             
            email:
         | 
| 60 60 | 
             
            - joshua@mervine.net
         | 
| @@ -62,7 +62,8 @@ executables: [] | |
| 62 62 | 
             
            extensions: []
         | 
| 63 63 | 
             
            extra_rdoc_files: []
         | 
| 64 64 | 
             
            files:
         | 
| 65 | 
            -
            - lib/ | 
| 65 | 
            +
            - lib/httperf/version.rb
         | 
| 66 | 
            +
            - lib/httperf/parser.rb
         | 
| 66 67 | 
             
            - lib/httperf.rb
         | 
| 67 68 | 
             
            - README.md
         | 
| 68 69 | 
             
            - HISTORY.md
         | 
| @@ -81,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 81 82 | 
             
                  version: '0'
         | 
| 82 83 | 
             
                  segments:
         | 
| 83 84 | 
             
                  - 0
         | 
| 84 | 
            -
                  hash:  | 
| 85 | 
            +
                  hash: 4261295427007759208
         | 
| 85 86 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 86 87 | 
             
              none: false
         | 
| 87 88 | 
             
              requirements:
         |