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.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/production_log/parser.rb', line 128

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