Class: RailsLogDeinterleaver::Parser
- Inherits:
-
Object
- Object
- RailsLogDeinterleaver::Parser
- Defined in:
- lib/rails_log_deinterleaver/parser.rb
Instance Method Summary collapse
- #ensure_timeouts_logged ⇒ Object
-
#initialize(filename, options = {}) ⇒ Parser
constructor
A new instance of Parser.
-
#output_logs_for_pid(pid) ⇒ Object
Output all lines of the log for a single request, followed by an empty blank line.
- #pid_for_line(line) ⇒ Object
- #process_line(line) ⇒ Object
- #run ⇒ Object
- #time_for_line(line) ⇒ Object
Constructor Details
#initialize(filename, options = {}) ⇒ Parser
Returns a new instance of Parser.
7 8 9 10 11 12 13 14 15 16 |
# File 'lib/rails_log_deinterleaver/parser.rb', line 7 def initialize(filename, ={}) @filename = filename @options = @options[:request_timeout] ||= 30 @options[:date_time_format] ||= "%b %d %H:%M:%S" @options[:start_request_regex] ||= /\[\d+\]: Started/ @options[:end_request_regex] ||= /\[\d+\]: Completed/ @options[:output] ||= $stdout @pids = {} end |
Instance Method Details
#ensure_timeouts_logged ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/rails_log_deinterleaver/parser.rb', line 75 def ensure_timeouts_logged expired_time = Time.now - @options[:request_timeout] # Loop over a clone of @pids because there is a chance that the parent thread # will want to add to the @pids Hash whilst this is running, triggering an exception. @pids.dup.each do |pid, details| if details[:last_seen_at] <= expired_time output_logs_for_pid(pid) end end sleep 1 self.ensure_timeouts_logged end |
#output_logs_for_pid(pid) ⇒ Object
Output all lines of the log for a single request, followed by an empty blank line.
62 63 64 65 |
# File 'lib/rails_log_deinterleaver/parser.rb', line 62 def output_logs_for_pid(pid) @options[:output].puts (@pids[pid][:lines] << '') @pids.delete(pid) end |
#pid_for_line(line) ⇒ Object
67 68 69 |
# File 'lib/rails_log_deinterleaver/parser.rb', line 67 def pid_for_line(line) line.match(/\[(\d+)\]/).captures.first.to_i end |
#process_line(line) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rails_log_deinterleaver/parser.rb', line 33 def process_line(line) # It is possible for the file to contain UTF-8 byte streams. Get rid of them here. # String#encode does not do anything if source and destination encoding are the same, # so encode to UTF-16 before converting back to UTF-8. line = line.encode('UTF-16', :invalid => :replace, :replace => '').encode('UTF-8') pid = pid_for_line(line) if line.match(@options[:start_request_regex]) if @pids[pid] # Already a request started but not finished for this pid. (Should be rare) # Log what we have to start a new request output_logs_for_pid(pid) end @pids[pid] = {lines: []} end return unless @pids[pid] @pids[pid][:last_seen_at] = Time.now @pids[pid][:lines].push(line) if line.match(@options[:end_request_regex]) output_logs_for_pid(pid) end end |
#run ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/rails_log_deinterleaver/parser.rb', line 18 def run Thread.new do self.ensure_timeouts_logged end File.open(@filename, 'r:UTF-8') do |log| log.extend(File::Tail) log.interval = 0.1 log.backward(@options[:backward]) if @options[:backward] log.tail do |line| process_line line end end end |
#time_for_line(line) ⇒ Object
71 72 73 |
# File 'lib/rails_log_deinterleaver/parser.rb', line 71 def time_for_line(line) DateTime.strptime(line, @options[:date_time_format]) end |