pivotal-apdex 0.1.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.
@@ -0,0 +1,2 @@
1
+ - Initial Release
2
+ - Added Apdex::CalculateFromLog
@@ -0,0 +1,27 @@
1
+ Overview
2
+ ========
3
+ Calculate [Apdex](http://apdex.org) scores from an Apache or Nginx log.
4
+
5
+ Usage
6
+ =====
7
+
8
+ apdex_from_log --help
9
+
10
+ egrep '/users/.+/edit' access.log | apdex_from_log --threshold 0.5 --time-column 11
11
+
12
+
13
+ Example Output
14
+ ==============
15
+
16
+ Score: 0.81
17
+ Satisfied: 63
18
+ Tolerating: 37
19
+ Frustrated: 0
20
+
21
+
22
+ Community
23
+ =========
24
+
25
+ Github: [http://github.com/pivotal/apdex](http://github.com/pivotal/apdex)
26
+
27
+ Tracker: [http://www.pivotaltracker.com/projects/14145](http://www.pivotaltracker.com/projects/14145)
@@ -0,0 +1,15 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "apdex"
5
+ s.executables = "apdex_from_log"
6
+ s.summary = "Calculate apdex scores from an Apache or Nginx log"
7
+ s.email = "pivotallabsopensource@googlegroups.com"
8
+ s.homepage = "http://github.com/pivotal/apdex"
9
+ s.description = "Calculate apdex scores from an Apache or Nginx log"
10
+ s.authors = ["Chad Woolley", "Brian Takita", "Pivotal Labs"]
11
+ s.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/apdex/templates/.gitignore']
12
+ end
13
+ rescue LoadError
14
+ puts "jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-apdex -s http://gems.github.com"
15
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 0
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ require "optparse"
3
+ require "apdex"
4
+
5
+ threshold = 0.5
6
+ time_column = nil
7
+
8
+ opts = OptionParser.new
9
+ #opts.on('-v', '--version') { output_version ; exit 0 }
10
+ #opts.on('-h', '--help') { output_help }
11
+ opts.on('-t', '--threshold [THRESHOLD]', Float, "The apdex threshold (defaults to 0.5)") {|t| threshold = t}
12
+ opts.on('-c', '--time-column [COLUMN]', Integer, "The column of the request time in the log file (required)") {|column| time_column = column}
13
+ opts.parse!(ARGV)
14
+
15
+ puts Apdex::CalculateFromLog.new(:time_column => time_column).print(threshold, $stdin)
@@ -0,0 +1,5 @@
1
+ module Apdex
2
+ end
3
+
4
+ dir = File.dirname(__FILE__)
5
+ require "#{dir}/apdex/calculate_from_log"
@@ -0,0 +1,39 @@
1
+ module Apdex
2
+ # See http://www.apdex.org/overview.html
3
+ class CalculateFromLog
4
+ attr_reader :time_column
5
+
6
+ def initialize(params={})
7
+ @time_column = params[:time_column] || raise(ArgumentError, "You must specify a time_column")
8
+ end
9
+
10
+ def print(threshold, input)
11
+ values = call(threshold, input)
12
+ [
13
+ "Score: #{values[:score]}",
14
+ "Satisfied: #{values[:satisfied]}",
15
+ "Tolerating: #{values[:tolerating]}",
16
+ "Frustrated: #{values[:frustrated]}",
17
+ ].join("\n")
18
+ end
19
+
20
+ def call(threshold, input)
21
+ values = input.map do |line|
22
+ `echo '#{line.strip}' | awk '{print $11}'`.strip.to_f
23
+ end
24
+ output = {}
25
+ output[:satisfied] = output[:tolerating] = output[:frustrated] = 0
26
+ values.each do |value|
27
+ if value <= threshold
28
+ output[:satisfied] += 1
29
+ elsif value <= (threshold * 4)
30
+ output[:tolerating] += 1
31
+ else
32
+ output[:frustrated] += 1
33
+ end
34
+ end
35
+ output[:score] = ("%0.3f" % (1.0 * (output[:satisfied] + output[:tolerating] / 2) / values.size)).to_f
36
+ output
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
2
+
3
+ module Apdex
4
+ describe CalculateFromLog do
5
+ attr_reader :input, :command
6
+ before do
7
+ @input = StringIO.new((<<-LOG).gsub(/^ +/, ""))
8
+ 204.16.153.246 - performatron [23/Apr/2009:16:57:27 -0700] "GET /myspace/compatibility/friend_model_matchings/new?model_id=17702&myspace_id=454017886 HTTP/1.1" 200 4282 0.100 "-" "httperf/0.9.0" "-"
9
+ 204.16.153.246 - performatron [23/Apr/2009:16:57:28 -0700] "GET /myspace/compatibility/friend_model_matchings/new?model_id=17702&myspace_id=454017886 HTTP/1.1" 200 4275 0.200 "-" "httperf/0.9.0" "-"
10
+ 204.16.153.246 - performatron [23/Apr/2009:16:57:28 -0700] "GET /myspace/compatibility/friend_model_matchings/new?model_id=17702&myspace_id=454017886 HTTP/1.1" 200 4282 0.300 "-" "httperf/0.9.0" "-"
11
+ 204.16.153.246 - performatron [23/Apr/2009:16:57:29 -0700] "GET /myspace/compatibility/friend_model_matchings/new?model_id=17702&myspace_id=454017886 HTTP/1.1" 200 4255 0.600 "-" "httperf/0.9.0" "-"
12
+ 204.16.153.246 - performatron [23/Apr/2009:16:57:30 -0700] "GET /myspace/compatibility/friend_model_matchings/new?model_id=17702&myspace_id=454017886 HTTP/1.1" 200 4275 1.000 "-" "httperf/0.9.0" "-"
13
+ 204.16.153.246 - performatron [23/Apr/2009:16:57:30 -0700] "GET /myspace/compatibility/friend_model_matchings/new?model_id=17702&myspace_id=454017886 HTTP/1.1" 200 4269 3.000 "-" "httperf/0.9.0" "-"
14
+ LOG
15
+
16
+ @command = CalculateFromLog.new(:time_column => 11)
17
+ end
18
+
19
+ describe "#print" do
20
+ it "returns the Apdex output in a formatted string" do
21
+ command.print(0.5, input).should == (<<-OUT).gsub(/^ +/, "").strip
22
+ Score: 0.667
23
+ Satisfied: 3
24
+ Tolerating: 2
25
+ Frustrated: 1
26
+ OUT
27
+ end
28
+ end
29
+
30
+ describe "#call" do
31
+ it "returns the Apdex score based on the input log" do
32
+ output = command.call(0.5, input)
33
+ output[:satisfied].should == 3
34
+ output[:tolerating].should == 2
35
+ output[:frustrated].should == 1
36
+ output[:score].should == 0.667
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+ require "spec"
3
+ require "spec/autorun"
4
+ dir = File.dirname(__FILE__)
5
+ $:.unshift(File.expand_path("#{dir}/../lib"))
6
+ require "apdex"
7
+
8
+ Spec::Runner.configure do |config|
9
+ config.mock_with :rr
10
+ end
@@ -0,0 +1,3 @@
1
+ Dir["#{File.dirname(__FILE__)}/**/*_spec.rb"].each do |file|
2
+ require file
3
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pivotal-apdex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chad Woolley
8
+ - Brian Takita
9
+ - Pivotal Labs
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-04-23 00:00:00 -07:00
15
+ default_executable: apdex_from_log
16
+ dependencies: []
17
+
18
+ description: Calculate apdex scores from an Apache or Nginx log
19
+ email: pivotallabsopensource@googlegroups.com
20
+ executables:
21
+ - apdex_from_log
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - README.markdown
26
+ files:
27
+ - CHANGES.markdown
28
+ - README.markdown
29
+ - Rakefile
30
+ - VERSION.yml
31
+ - bin/apdex_from_log
32
+ - lib/apdex.rb
33
+ - lib/apdex/calculate_from_log.rb
34
+ has_rdoc: true
35
+ homepage: http://github.com/pivotal/apdex
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --charset=UTF-8
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.2.0
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: Calculate apdex scores from an Apache or Nginx log
60
+ test_files:
61
+ - spec/apdex/calculate_from_log_spec.rb
62
+ - spec/spec_suite.rb
63
+ - spec/spec_helper.rb