Class: MongoRequestLogger::Logger

Inherits:
ActiveSupport::BufferedLogger
  • Object
show all
Defined in:
lib/mongo_request_logger/logger.rb

Constant Summary collapse

LEVELS =
{
    DEBUG => 'DEBUG',
    INFO => 'INFO',
    WARN => 'WARN',
    ERROR => 'ERROR',
    FATAL => 'FATAL',
    UNKNOWN => 'UNKNOWN',
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter, file, level = DEBUG) ⇒ Logger

Returns a new instance of Logger.



8
9
10
11
12
13
# File 'lib/mongo_request_logger/logger.rb', line 8

def initialize(adapter, file, level=DEBUG)
  super(file, level)
  @adapter = adapter
  @mongo_record = {}  # This is required as a workaround for logging in the console
  create_indexes
end

Instance Attribute Details

#adapterObject (readonly)

Returns the value of attribute adapter.



6
7
8
# File 'lib/mongo_request_logger/logger.rb', line 6

def adapter
  @adapter
end

Instance Method Details

#add(severity, message = nil, progname = nil, &block) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/mongo_request_logger/logger.rb', line 91

def add(severity, message = nil, progname = nil, &block)
  unless level > severity
    time = Time.now.strftime "%H:%M:%S.%L"
    prefix = "#{time} [#{level_to_s(severity)}] "
    #if ActiveRecord::Base.colorize_logging
    #  # remove colorization done by rails and just save the actual message
    #  @mongo_record[:messages] << prefix + message.gsub(/(\e(\[([\d;]*[mz]?))?)?/, '').strip rescue nil
    #else
    @mongo_record[:messages] ||= []
    @mongo_record[:messages] << prefix + message
    #end
  end

  # To do normal file logging as well, add a call to super here
  # We only log ERROR and above to the text file logs.
  if severity >= ERROR
    super
  end
end

#add_metadata(options = {}) ⇒ Object



79
80
81
82
83
# File 'lib/mongo_request_logger/logger.rb', line 79

def (options={})
  options.each_pair do |key, value|
    @mongo_record[key] = value
  end
end

#add_metadata_set(key, *values) ⇒ Object



85
86
87
88
89
# File 'lib/mongo_request_logger/logger.rb', line 85

def  key, *values
  key = key.to_s
  @mongo_record[key] ||= Set.new
  @mongo_record[key] += values
end

#create_indexesObject



15
16
17
18
19
20
21
22
# File 'lib/mongo_request_logger/logger.rb', line 15

def create_indexes
  adapter.create_index '_id'
  adapter.create_index 'objects'
  adapter.create_index 'tags'
  adapter.create_index 'path'
  adapter.create_index 'user_id'
  adapter.create_index 'timestamp'
end

#level_to_s(level) ⇒ Object



33
34
35
# File 'lib/mongo_request_logger/logger.rb', line 33

def level_to_s(level)
  LEVELS[level]
end

#log_request(options = {}) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/mongo_request_logger/logger.rb', line 54

def log_request(options={})
  @mongo_record = options.merge({
                                    :messages => [],
                                    :timestamp => Time.now.utc,
                                    :pid => Process.pid,
                                })

  begin
    start_time = Time.now
    return yield
  rescue Exception => e
    # The backtrace is not useful metadata, and we want to write it to the text log as well.
    exception e
    @mongo_record[:exception] = {:class => e.class.to_s, :message => e.message}
    raise
  ensure
    # Benchmark.measure doesn't handle exceptions well, so we measure the time ourselves.
    end_time = Time.now
    runtime = end_time.to_f - start_time.to_f
    @mongo_record[:runtime] = (runtime.real * 1000).ceil

    do_log @mongo_record
  end
end

#sanitize(obj) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/mongo_request_logger/logger.rb', line 37

def sanitize obj
  if obj.is_a? Hash
    result = {}
    obj.each do |k, v|
      # We replace all non-alphanumeric characters with underscores
      result[k.to_s.gsub(/\W/, "_")] = sanitize(v)
    end
    result
  elsif obj.is_a? Array or obj.is_a? Set
    obj.map {|o| sanitize(o)}
  elsif obj.is_a? Time or obj.is_a? String or obj.is_a? Integer
    obj
  else
    obj.to_s
  end
end