Class: Chainsaw::Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/chainsaw/filter.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(logfile, range, options = OpenStruct.new) ⇒ Filter

Initialize a Filter instance. We read the logfile here and attempt to detect what type of logfile it is.

logfile - the String path of the logfile to be filtered range - the “time” range to filter through (Time or Range) options - an OpenStruct representing the options

Returns the Filter instance



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/chainsaw/filter.rb', line 13

def initialize(logfile, range, options = OpenStruct.new)
  @logfile    = logfile
  @range      = range
  @options    = options
  @log        = File.open(@logfile)
  @format     = Detector.detect(@log)
  @line_count = 0

  @log.rewind

  self
end

Instance Attribute Details

#line_countObject (readonly)

Returns the value of attribute line_count.



3
4
5
# File 'lib/chainsaw/filter.rb', line 3

def line_count
  @line_count
end

Class Method Details

.filter(*args) ⇒ Object

A convinence method to initialize a Filter object using the given args and start filtering it



100
101
102
# File 'lib/chainsaw/filter.rb', line 100

def self.filter(*args)
  new(*args).start
end

.parse_timestamp(timestamp, time_format) ⇒ Object

Parse a timestamp using the given time_format.

timestamp - the String timestamp time_format - the String time format used to parse

Returns a parsed Time object



91
92
93
94
95
# File 'lib/chainsaw/filter.rb', line 91

def self.parse_timestamp(timestamp, time_format)
  dt = DateTime.strptime(timestamp, time_format)

  Time.local(dt.year, dt.month, dt.day, dt.hour, dt.min, dt.sec)
end

Instance Method Details

#found(line, timestamp) ⇒ Object

A matching line was found, set @outputting incase we run into lines that aren’t timestamped.

line - the String logline timestamp - the String timestamp from the logline



62
63
64
65
66
67
68
69
# File 'lib/chainsaw/filter.rb', line 62

def found(line, timestamp)
  @outputting = true
  @line_count += 1

  out(line, timestamp)

  STDIN.gets if @options.interactive && !@options.output_file
end

#out(line, timestamp = nil) ⇒ Object

Output the logline to STDOUT or File. We also colorize if requested.

line - the String logline timestamp - the String timestamp from the logline



75
76
77
78
79
80
81
82
83
# File 'lib/chainsaw/filter.rb', line 75

def out(line, timestamp = nil)
  if @options.output_file
    File.open(@options.output_file, 'a') { |f| f.write(line) }
  elsif @options.colorize && timestamp
    puts line.sub(timestamp, "\033[32m#{timestamp}\033[0m")
  else
    puts line
  end
end

#startObject

Start iterating through the log lines and filtering them accordingly.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/chainsaw/filter.rb', line 27

def start
  @log.each_line do |line|
    filter    = @options.filter
    match     = line.match(@format.pattern)

    if match
      timestamp = match[1]
      time      = Filter.parse_timestamp(timestamp, @format.time_format)
    else
      timestamp = time = nil
    end

    # a match was found if we are filtering additional text, check that too
    if match && @range.cover?(time) && ( !filter || filter && line.include?(filter) )
      found(line, timestamp)
    # a match was found and we are outputting non-timestamped lines
    elsif match && @outputting
      @outputting = false
    # outputting non-timestamped lines
    elsif @outputting
      out(line)
    end
  end

  unless @options.output_file
    hind = (@line_count.zero? || @line_count > 1) ? 's' : ''
    puts "\n\033[33mFound #{@line_count} line#{hind} \033[0m"
  end
end