Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 888120eb1a662bfeaf9772b81e9120d5aa45cb4e 0 parents
@noahd1 authored
4 History.txt
@@ -0,0 +1,4 @@
+=== 0.1.0 / 2009-02-09
+
+* 1st release
+
19 MIT-LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2008 Noah Davis
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
28 README.rdoc
@@ -0,0 +1,28 @@
+=== Oink
+
+* http://github.com/noahd1/oink
+
+=== Description
+
+Parse through logs to identify ruby on rails actions which increase memory usage
+
+=== Synopsis
+
+
+=== Install
+
+To install the latest release (once there is a release):
+
+ $ sudo gem install oink
+
+For now, just pull down the code from the GitHub repo:
+
+ $ git clone git://github.com/noahd1/oink.git
+ $ cd oink
+ $ rake gem
+ $ rake install_gem
+
+=== Authors
+
+- Maintained by Noah Davis
+- Thanks to Weplay (http://weplay.com) for sponsoring development and supporting open sourcing it from the start
36 Rakefile
@@ -0,0 +1,36 @@
+require 'rubygems'
+require "rake/gempackagetask"
+require "rake/clean"
+require './lib/oink.rb'
+
+spec = Gem::Specification.new do |s|
+ s.name = "oink"
+ s.version = Oink::VERSION
+ s.author = "Noah Davis"
+ s.email = "noahd1" + "@" + "yahoo.com"
+ s.homepage = "http://github.com/noahd1/oink"
+ s.summary = "Parse through logs to identify ruby on rails actions which increase memory usage"
+ s.description = s.summary
+ s.executables = "oink"
+ s.files = %w[History.txt MIT-LICENSE.txt README.rdoc Rakefile] + Dir["bin/*"] + Dir["lib/**/*"]
+end
+
+Rake::GemPackageTask.new(spec) do |package|
+ package.gem_spec = spec
+end
+
+desc 'Show information about the gem.'
+task :write_gemspec do
+ File.open("oink.gemspec", 'w') do |f|
+ f.write spec.to_ruby
+ end
+ puts "Generated: oink.gemspec"
+end
+
+CLEAN.include ["pkg", "*.gem", "doc", "ri", "coverage"]
+
+desc 'Install the package as a gem.'
+task :install_gem => [:clean, :package] do
+ gem = Dir['pkg/*.gem'].first
+ sh "sudo gem install --local #{gem}"
+end
52 bin/oink
@@ -0,0 +1,52 @@
+#!/usr/bin/env ruby
+
+require 'optparse'
+require File.expand_path(File.dirname(__FILE__) + "/../lib/cli")
+require File.expand_path(File.dirname(__FILE__) + "/../lib/oink")
+
+options = { :format => :summary, :threshold => 75 }
+
+opts = OptionParser.new do |opts|
+ opts.banner = "Usage: oink [options] files"
+
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
+ options[:format] = :verbose if v
+ end
+
+ opts.on("-t", "--threshold [INTEGER]", Integer,
+ "Threshold in MB") do |threshold|
+ options[:threshold] = threshold
+ end
+
+ opts.on("-f", "--file filepath", "Output to file") do |filename|
+ options[:output_file] = filename
+ end
+
+end
+
+opts.parse!
+
+if ARGV.empty?
+ puts opts
+ exit
+end
+
+options[:threshold] *= 1024
+output = nil
+
+if options[:output_file]
+ output = File.open(options[:output_file], 'w')
+else
+ output = STDOUT
+end
+
+files = get_file_listing(ARGV)
+
+handles = files.map { |f| File.open(f) }
+
+Oink.new(handles, options[:threshold], :format => options[:format]).each_line do |line|
+ output.puts line
+end
+
+output.close
+handles.each { |h| h.close }
14 lib/cli.rb
@@ -0,0 +1,14 @@
+def get_file_listing(args)
+ listing = []
+ args.each do |file|
+ unless File.exist?(file)
+ raise "Could not find \"#{file}\""
+ end
+ if File.directory?(file)
+ listing += Dir.glob("#{file}/**")
+ else
+ listing << file
+ end
+ end
+ listing
+end
19 lib/logged_request.rb
@@ -0,0 +1,19 @@
+class LoggedRequest
+
+ attr_accessor :action, :datetime, :memory
+
+ def initialize(action, datetime, memory)
+ @action = action
+ @datetime = datetime
+ @memory = memory
+ end
+
+ def <=>(other)
+ self.memory <=> other.memory
+ end
+
+ def >(other)
+ self.memory > other.memory
+ end
+
+end
85 lib/oink.rb
@@ -0,0 +1,85 @@
+require "date"
+require File.expand_path(File.dirname(__FILE__) + "/logged_request")
+require File.expand_path(File.dirname(__FILE__) + "/priority_queue")
+
+class Oink
+ VERSION = '0.1.0'
+
+ def initialize(input, threshold, options = {})
+ @inputs = Array(input)
+ @threshold = threshold
+ @format = options[:format] || :summary
+
+ @pids = {}
+ @oinkers = {}
+ @worst_offenses = PriorityQueue.new(10)
+ @earliest = nil
+ @latest = nil
+ end
+
+ def each_line
+ yield "Actions using over #{@threshold/1024} MB in single request:"
+
+ @inputs.each do |input|
+ input.each_line do |line|
+ line = line.strip
+
+ if line =~ /rails\[(\d+)\]/
+ pid = $1
+
+ unless @pids[pid]
+ @pids[pid] = { :buffer => [], :last_memory_reading => -1, :current_memory_reading => -1, :action => "", :request_finished => true }
+ end
+ @pids[pid][:buffer] << line
+ end
+
+ if line =~ /Processing ((\w+)#(\w+)) /
+
+ unless @pids[pid][:request_finished]
+ @pids[pid][:last_memory_reading] = -1
+ end
+ @pids[pid][:action] = $1
+ @pids[pid][:request_finished] = false
+
+ elsif line =~ /Memory usage: (\d+) /
+
+ memory_reading = $1.to_i
+ @pids[pid][:current_memory_reading] = memory_reading
+
+ elsif line =~ /Completed in/
+
+ @pids[pid][:request_finished] = true
+ unless @pids[pid][:current_memory_reading] == -1 || @pids[pid][:last_memory_reading] == -1
+ memory_diff = @pids[pid][:current_memory_reading] - @pids[pid][:last_memory_reading]
+ if memory_diff > @threshold
+ @oinkers[@pids[pid][:action]] ||= 0
+ @oinkers[@pids[pid][:action]] = @oinkers[@pids[pid][:action]] + 1
+ date = /^(\w+ \d{2} \d{2}:\d{2}:\d{2})/.match(line).captures[0]
+ @worst_offenses.push(LoggedRequest.new(@pids[pid][:action], date, memory_diff))
+ if @format == :verbose
+ @pids[pid][:buffer].each { |b| yield b }
+ yield "---------------------------------------------------------------------"
+ end
+ end
+ end
+ @pids[pid][:buffer] = []
+ @pids[pid][:last_memory_reading] = @pids[pid][:current_memory_reading]
+ @pids[pid][:current_memory_reading] = -1
+
+ end # end elsif
+ end # end each_line
+ end # end each input
+
+ yield "From #{@earliest.strftime('%m %d %Y')} to #{@latest.strftime('%m %d %Y')}" if @earliest && @latest
+ yield "-- SUMMARY --"
+ yield "Rank of Single Time Worst Offenders"
+ @worst_offenses.each_with_index do |offender, index|
+ yield "#{index + 1}. #{offender.datetime}, #{offender.memory} KB, #{offender.action}"
+ end
+ yield "# of Times, Action"
+ @oinkers.sort{|a,b| b[1]<=>a[1]}.each { |elem|
+ yield "#{elem[1]}, #{elem[0]}"
+ }
+ end
+
+end
37 lib/priority_queue.rb
@@ -0,0 +1,37 @@
+class PriorityQueue
+
+ include Enumerable
+
+ def initialize(size)
+ @size = size
+ @queue = []
+ end
+
+ def push(item)
+ if @queue.size < @size
+ @queue << item
+ elsif item > @queue.last
+ @queue[@size - 1] = item
+ end
+ prioritize
+ end
+
+ def to_a
+ @queue
+ end
+
+ def size
+ @queue.size
+ end
+
+ def each
+ @queue.each { |i| yield i }
+ end
+
+protected
+
+ def prioritize
+ @queue.sort! { |a, b| b <=> a }
+ end
+
+end
BIN  pkg/oink-0.1.0.gem
Binary file not shown
16 spec/logged_request_spec.rb
@@ -0,0 +1,16 @@
+require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
+
+describe LoggedRequest do
+
+ describe "sort" do
+ it "should sort by memory used" do
+ lr1 = LoggedRequest.new("Controller#Action", "February 1 10:20", 10)
+ lr2 = LoggedRequest.new("Controller#Action", "February 1 10:20", 5)
+ lr3 = LoggedRequest.new("Controller#Action", "February 1 10:20", 30)
+
+ [lr1, lr2, lr3].sort.should == [lr2, lr1, lr3]
+ end
+ end
+
+
+end
266 spec/oink_spec.rb
@@ -0,0 +1,266 @@
+require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
+
+describe Oink do
+
+ TEN_MEGS = 10 * 1024
+
+ describe "summary with frequent offenders" do
+
+ it "should report actions which exceed the threshold once" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should include("1, MediaController#show")
+ end
+
+ it "should report actions which exceed the threshold multiple times" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{(TEN_MEGS * 2) + 2} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should include("2, MediaController#show")
+ end
+
+ it "should order actions by most exceeded" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{(TEN_MEGS * 2) + 2} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{(TEN_MEGS * 3) + 3} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output[-2].should == "2, MediaController#show"
+ output[-1].should == "1, Users#show"
+ end
+
+ it "should not report actions which do not exceed the threshold" do
+ threshold = 10
+
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should_not include("1, MediaController#show")
+ end
+
+ it "should not report actions which do not complete properly" do
+ threshold = 10
+
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should_not include("1, MediaController#show")
+ end
+
+ it "should not report actions from different pids" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[5513]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[5513]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[5513]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should_not include("1, MediaController#show")
+ end
+
+ describe "summary with top 10 offenses" do
+
+ it "should only report offenses over threshold" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:32 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:33 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:34 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should include("1. Feb 01 01:58:34, #{TEN_MEGS + 1} KB, MediaController#show")
+ end
+
+ it "should not include offenses under the threshold" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:32 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:33 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS} | PID: 4413
+ Feb 01 01:58:34 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should_not include("1. Feb 01 01:58:34, #{TEN_MEGS + 1} KB, MediaController#show")
+ end
+
+ it "should order offenses from biggest to smallest" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:32 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:33 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:34 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:35 ey04-s00297 rails[4413]: Processing DetailsController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:36 ey04-s00297 rails[4413]: Memory usage: #{(TEN_MEGS * 2) + 2} | PID: 4413
+ Feb 01 01:58:37 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output[3].should == "1. Feb 01 01:58:34, #{TEN_MEGS + 1} KB, MediaController#show"
+ output[4].should == "2. Feb 01 01:58:37, #{TEN_MEGS + 1} KB, DetailsController#show"
+ end
+
+ end
+
+ # it "should report the time span" do
+ # str = <<-STR
+ # Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ # Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ # Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ # Mar 13 01:58:29 ey04-s00297 rails[5513]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ # Mar 13 01:58:30 ey04-s00297 rails[5513]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ # Mar 13 03:58:30 ey04-s00297 rails[5513]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ # STR
+ #
+ # io = StringIO.new(str)
+ # output = []
+ # Oink.new(io, TEN_MEGS).each_line do |line|
+ # output << line
+ # end
+ # output.first.should == "Feb 01 01:58:29 - Mar 13 03:58:30"
+ # end
+
+ end
+
+ describe "verbose format" do
+ it "should print the full lines of actions exceeding the threshold" do
+ str = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Parameters: {"id"=>"2332", "controller"=>"users"}
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Parameters: {"id"=>"22900", "controller"=>"media"}
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+ io = StringIO.new(str)
+ output = []
+ Oink.new(io, TEN_MEGS, :format => :verbose).each_line do |line|
+ output << line
+ end
+ output[1..4].should == str.split("\n")[4..7].map { |o| o.strip }
+ end
+ end
+
+ describe "multiple io streams" do
+ it "should accept multiple files" do
+
+ str1 = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ str2 = <<-STR
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: 0 | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Memory usage: #{TEN_MEGS + 1} | PID: 4413
+ Feb 01 01:58:30 ey04-s00297 rails[4413]: Completed in 984ms (View: 840, DB: 4) | 200 OK
+ STR
+
+ io1 = StringIO.new(str1)
+ io2 = StringIO.new(str2)
+ output = []
+ Oink.new([io1, io2], TEN_MEGS).each_line do |line|
+ output << line
+ end
+ output.should include("2, MediaController#show")
+ end
+
+ end
+
+end
75 spec/priority_queue_spec.rb
@@ -0,0 +1,75 @@
+require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
+
+describe PriorityQueue do
+
+ describe "size" do
+
+ it "should report the right size" do
+ pq = PriorityQueue.new(5)
+ pq.push(1)
+ pq.size.should == 1
+ pq.push(2)
+ pq.size.should == 2
+ end
+
+ it "should be limited to the size initialized with" do
+ pq = PriorityQueue.new(5)
+ pq.push(1)
+ pq.push(2)
+ pq.push(3)
+ pq.push(4)
+ pq.push(5)
+ pq.push(6)
+ pq.size.should == 5
+ end
+
+ end
+
+ describe "order" do
+
+ it "should be in order from highest to lowest" do
+ pq = PriorityQueue.new(5)
+ pq.push(1)
+ pq.push(2)
+ pq.push(3)
+ pq.to_a.should == [3,2,1]
+ end
+
+ it "should throw out the lower value when adding a new value" do
+ pq = PriorityQueue.new(3)
+ pq.push(1)
+ pq.push(2)
+ pq.push(3)
+ pq.push(4)
+ pq.to_a.should == [4,3,2]
+ end
+
+ it "should not make it into the queue if it's smaller than the items in the queue" do
+ pq = PriorityQueue.new(3)
+ pq.push(2)
+ pq.push(3)
+ pq.push(4)
+ pq.push(1)
+ pq.to_a.should == [4,3,2]
+ end
+
+ end
+
+ describe "each" do
+ it "should return each item in turn" do
+ arr = []
+ pq = PriorityQueue.new(5)
+ pq.push(2)
+ pq.push(3)
+ pq.push(4)
+ pq.push(1)
+ pq.push(5)
+ pq.each do |i|
+ arr << i
+ end
+ arr.should == [5,4,3,2,1]
+ end
+ end
+
+
+end
5 spec/spec_helper.rb
@@ -0,0 +1,5 @@
+require "rubygems"
+require "spec"
+require File.expand_path(File.dirname(__FILE__) + "/../lib/oink")
+require File.expand_path(File.dirname(__FILE__) + "/../lib/priority_queue")
+require File.expand_path(File.dirname(__FILE__) + "/../lib/logged_request")
Please sign in to comment.
Something went wrong with that request. Please try again.