Module: LogParser

Defined in:
lib/production_log/parser.rb

Overview

LogParser parses a Syslog log file looking for lines logged by the ‘rails’ program. A typical log line looks like this:

Mar  7 00:00:20 online1 rails[59600]: Person Load (0.001884)   SELECT * FROM people WHERE id = 10519 LIMIT 1

LogParser does not work with Rails’ default logger because there is no way to group all the log output of a single request. You must use SyslogLogger.

Defined Under Namespace

Classes: LogEntry

Class Method Summary collapse

Class Method Details

.parse(stream) ⇒ Object

Parses IO stream stream, creating a LogEntry for each recognizable log entry.

Log entries are recognised as starting with Processing, continuing with the same process id through Completed.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/production_log/parser.rb', line 148

def self.parse(stream) # :yields: log_entry
  buckets = Hash.new { |h,k| h[k] = [] }
  comp_count = Hash.new 0

  stream.each_line do |line|
    line =~ / ([^ ]+) ([^ ]+)\[(\d+)\]: (.*)/
    next if $2.nil? or $2 == 'newsyslog'
    bucket = [$1, $2, $3].join '-'
    data = $4

    buckets[bucket] << data

    case data
    when /^Start rendering component / then
      comp_count[bucket] += 1
    when /^End of component rendering$/ then
      comp_count[bucket] -= 1
    when /^Completed/ then
      next unless comp_count[bucket] == 0
      entry = buckets.delete bucket
      next unless entry.any? { |l| l =~ /^Processing/ }
      yield LogEntry.new(entry)
    end
  end

  buckets.sort.each do |bucket, data|
    yield LogEntry.new(data)
  end
end