Class: BenchmarkForRails::LogParser

Inherits:
Object
  • Object
show all
Defined in:
lib/benchmark_for_rails/log_parser.rb

Constant Summary collapse

B4R_RE =

pulls B4R lines out of the logfile.

/^B4R/
PROCESSING_RE =
/\AProcessing .+ at (\d+-\d+-\d+ \d+:\d+:\d+)\Z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file = nil, threshold = nil) ⇒ LogParser

Returns a new instance of LogParser.



13
14
15
16
# File 'lib/benchmark_for_rails/log_parser.rb', line 13

def initialize(file = nil, threshold = nil)
  self.file = file || RAILS_ROOT + '/log/production.log'
  self.threshold = threshold
end

Instance Attribute Details

#fileObject

The log file to be read.



4
5
6
# File 'lib/benchmark_for_rails/log_parser.rb', line 4

def file
  @file
end

#thresholdObject

If set to a Time, will limit the parsed responses to those after the threshold. This lets you parse the last hour’s worth of data out of a log.

Depends on the ‘elif’ gem.



11
12
13
# File 'lib/benchmark_for_rails/log_parser.rb', line 11

def threshold
  @threshold
end

Instance Method Details

#benchmarksObject

reads the resource_paths to calculate average times for each benchmark type. that is, this returns averages indexed by benchmark, not path.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/benchmark_for_rails/log_parser.rb', line 42

def benchmarks
  if @benchmarks.nil?
    benchmarks = {}
    resource_paths.each do |path|
      path.requests.each do |request|
        request.each do |benchmark, time| (benchmarks[benchmark] ||= []) << time end
      end
    end

    @benchmarks = {}
    benchmarks.each do |benchmark, times| @benchmarks[benchmark] = (times.sum || 0) / times.size end
  end
  @benchmarks
end

#linesObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/benchmark_for_rails/log_parser.rb', line 21

def lines
  if @lines.nil?
    if threshold
      require 'elif'
      @lines = []
      Elif.foreach(self.file) do |line|
        if B4R_RE.match(line)
          @lines << line
        elsif threshold and PROCESSING_RE.match(line)
          @lines.pop and break if Time.parse($1) < self.threshold
        end
      end
    else
      @lines ||= File.read(self.file).grep(/^B4R/)
    end
  end
  @lines
end

#resource_pathsObject

pulls ResourcePath objects out of the file



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/benchmark_for_rails/log_parser.rb', line 58

def resource_paths
  if @resource_paths.nil?
    paths_by_path = {}
    lines.each do |line|
      path_name = ResourcePath.path_from(line)
      paths_by_path[path_name] ||= ResourcePath.new(path_name)
      paths_by_path[path_name].add_request(line)
    end
    @resource_paths = paths_by_path.values
  end
  @resource_paths
end

#slowest(number = 10, total_time = false) ⇒ Object

returns the slowest few ResourcePaths optionally determines slowness by weighting speed vs frequency (e.g. total time, not average time)



73
74
75
# File 'lib/benchmark_for_rails/log_parser.rb', line 73

def slowest(number = 10, total_time = false)
  resource_paths.sort_by(&(total_time ? :total_time : :average_time)).reverse[0...number]
end