class Chef::Deployment::Monitor::Logmon

Public Class Methods

new() click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 25
def initialize
  @sinks = { }
end

Public Instance Methods

digest(data) click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 69
def digest(data)
  md5 = Digest::MD5.new
  md5.update data.to_s
  data = data.dup
  data['digest'] = md5.hexdigest
  data
end
extract_query_string(url) click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 81
def extract_query_string(url)
  return unless url

  query_string = url.split('?', 2)[1]
  return unless query_string

  result = {}
  query_string.split('&').each do |value|
    segments = value.split('=', 2)
    next if segments[0].nil? || segments[0].empty?

    result[segments[0]] = segments[1]
  end
  result
end
filter(data) click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 77
def filter(data)
  Monitor::Config[:blacklisted?].call(data)
end
format(data) click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 61
def format(data)
  # convert to timestamp
  data_dup = data.dup
  data_dup['time'] = DateTime.strptime(data['time'], '%d/%b/%C:%T %z').to_time.to_i
  data_dup['server'] = data['server'].strip
  data_dup
end
run() click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 28
def run
  begin
    File.open(Monitor::Config[:mon_file]) do |mon|
      mon.extend(File::Tail)
      mon.interval = 5
      mon.backward(1)
      mon.tail do |line|
        data = scan(line)
        # skipping the objects 'checksum-.*' and 'reports'
        unless data.nil? || data['org'].nil? || data['object'] =~ /(^checksum-.*$|^reports$)/
          data = format(data)
          unless filter(data)
            Monitor::Log.new(data.to_json, 'INFO')
            data = digest(data)
            sinks(data).each { |sink| sink.receive(data) }
          end
        end
      end
    end
  end
end
scan(line) click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 97
def scan(line)
  @regex = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) - (.{0})- \[([^\]]+?)\]  "(\w+) ([^\s]+?) (HTTP\/1\.1)" (\d+) "(.*)" (\d+) "-" "(.*)" "(.*)" "(.*)" "(.*)" "(.*)" "(.*)" "(.*)" "(.*)" "(.*)"/
  if line =~ @regex
    return nil if Regexp.last_match(7).to_i == 403 # forbidden request do not count
    data = {}
    data['time']    = Regexp.last_match(3)
    data['user']    = Regexp.last_match(16)
    data['server']  = LOGMONNAME
    data['org']     = Regexp.last_match(5).split('/')[2] unless Regexp.last_match(5).split('/')[2].nil?
    data['object']  = Regexp.last_match(5).split('/')[3] unless Regexp.last_match(5).split('/')[3].nil?
    data['name']    = Regexp.last_match(5).split('/')[4] unless Regexp.last_match(5).split('/')[4].nil?
    data['query']   = extract_query_string(Regexp.last_match(5))
    if Regexp.last_match(5).split('/')[3] == 'policy_groups'
      data['subobject'] = Regexp.last_match(5).split('/')[5] unless Regexp.last_match(5).split('/')[5].nil?
      data['subname']   = Regexp.last_match(5).split('/')[6] unless Regexp.last_match(5).split('/')[6].nil?
    else
      data['version'] = Regexp.last_match(5).split('/')[5] unless Regexp.last_match(5).split('/')[5].nil?
    end
    data['action']  = Regexp.last_match(4)
    return data
  end
  nil
end
sinks(data) click to toggle source
# File lib/chef_deployment_monitor/logmon.rb, line 50
def sinks(data)
  route = Monitor::Config[:route].call(data)
  unless @sinks.has_key? route
    @sinks[route] = [MarkerFileSink.new(::File.join(Monitor::Config[:output_file_directory],
                                                    Monitor::Config[:marker_file_template] % route)),
                     HistoryFileSink.new(::File.join(Monitor::Config[:output_file_directory],
                                                     Monitor::Config[:history_file_template] % route))]
  end
  @sinks[route]
end