pivotal-apdex 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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