Module: Log

Extended by:
Log
Included in:
Log
Defined in:
lib/droid/heroku/logger_client.rb,
lib/droid/heroku/logger_client.rb

Defined Under Namespace

Classes: Config, InvalidConfiguration

Constant Summary collapse

SyslogConvertion =
{
  'error'   => 3,
  'warning' => 4,
  'notice'  => 5,
  'debug'   => 7,
}

Instance Method Summary collapse

Instance Method Details

#configure {|config| ... } ⇒ Object

Yields:

  • (config)


152
153
154
155
156
# File 'lib/droid/heroku/logger_client.rb', line 152

def configure
  config = Config.new
  yield(config)
  set_default_options(config.to_hash)
end

#console_log(msg) ⇒ Object



178
179
180
# File 'lib/droid/heroku/logger_client.rb', line 178

def console_log(msg)
  console_puts "#{Time.now.iso8601} #{msg}" if default_options[:console_log]
end

#console_puts(*args) ⇒ Object



120
121
122
# File 'lib/droid/heroku/logger_client.rb', line 120

def console_puts(*args)
  $stderr.puts(*args)
end

#context(options) ⇒ Object



145
146
147
148
149
150
# File 'lib/droid/heroku/logger_client.rb', line 145

def context(options)
  prev_options = default_options.dup
  default_options.merge!(options)
  yield
  @@default_options = prev_options
end

#debug(msg, options = {}) ⇒ Object



47
48
49
# File 'lib/droid/heroku/logger_client.rb', line 47

def debug(msg, options={})
  log msg, options.merge(:level => 'debug')
end

#default_error(e) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/droid/heroku/logger_client.rb', line 85

def default_error(e)
  # avoid backtrace in /usr or vendor if possible
  system, app = e.backtrace.partition { |b| b =~ /(^\/usr\/|vendor)/ }
  reordered_backtrace = app + system

  # avoid "/" as the method name (we want the controller action)
  row = 0
  row = 1 if reordered_backtrace[row].match(/in `\/'$/)

  # get file and method name
  begin
    file, method = reordered_backtrace[row].match(/(.*):in `(.*)'$/)[1..2]
    file.gsub!(/.*\//, '')
    self.log "#{e.class} in #{file} #{method}: #{e.message}", :exception => e, :level => 'error'
  rescue
    self.log "#{e.class} in #{e.backtrace.first}: #{e.message}", :exception => e, :level => 'error'
  end
end

#default_optionsObject



162
163
164
# File 'lib/droid/heroku/logger_client.rb', line 162

def default_options
  @@default_options ||= { :console_log => true }
end

#error(msg, options = {}) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/droid/heroku/logger_client.rb', line 61

def error(msg, options={})
  # Fake an exception for error messages with no exception object
  # so that we get a backtrace.
  if options[:exception].nil?
    begin
      raise StandardError, msg
    rescue => error
      error.backtrace.shift
      options[:exception] = error
    end
  end

  log msg, options.merge(:level => 'error')
end

#event(name, options = {}) ⇒ Object



138
139
140
141
142
143
# File 'lib/droid/heroku/logger_client.rb', line 138

def event(name, options = {})
  console_log("EVENT: #{name} begins")
  result = yield
  console_log("EVENT: #{name} complete")
  result
end

#exception(e) ⇒ Object



124
125
126
127
128
# File 'lib/droid/heroku/logger_client.rb', line 124

def exception(e)
  msg = "Exception #{e.class} -> #{e.message}\n"
  msg += filtered_backtrace(e.backtrace)
  Log.error e.message, :exception => e
end

#failsafe(params) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
# File 'lib/droid/heroku/logger_client.rb', line 166

def failsafe(params)
  case default_options[:failsafe]
    when :file
      dir = defined?(RAILS_ROOT) ? RAILS_ROOT : '.'
      File.open("#{dir}/failsafe.log", "a") do |f|
        f.puts "#{Time.now} #{params[:log][:level]} : #{params[:log][:message]}"
      end
    when :console, nil
      console_log(params[:log][:message])
  end
end

#filtered_backtrace(backtrace) ⇒ Object



130
131
132
133
134
135
136
# File 'lib/droid/heroku/logger_client.rb', line 130

def filtered_backtrace(backtrace)
  backtrace.select do |line|
    !line.match(/^\/usr/)
  end.map do |line|
    "   #{line}\n"
  end.join
end

#format_syslog_exception(e) ⇒ Object



201
202
203
204
205
206
207
# File 'lib/droid/heroku/logger_client.rb', line 201

def format_syslog_exception(e)
  if e.respond_to?(:backtrace)
    "\t#{e.class}: #{e.message}\n" + e.backtrace.map { |t| "\t#{t}" }.join("\n")
  else
    "\t#{e.class}: #{e.message}"
  end
end

#log(msg, options = {}) ⇒ Object



78
79
80
81
82
83
# File 'lib/droid/heroku/logger_client.rb', line 78

def log(msg, options={})
  console_log(msg)
  syslog(msg, options)
rescue InvalidConfiguration => e
  raise e
end

#notice(msg, options = {}) ⇒ Object Also known as: info



51
52
53
# File 'lib/droid/heroku/logger_client.rb', line 51

def notice(msg, options={})
  log msg, options.merge(:level => 'notice')
end

#set_default_options(options) ⇒ Object



158
159
160
# File 'lib/droid/heroku/logger_client.rb', line 158

def set_default_options(options)
  default_options.merge!(options)
end

#syslog(msg, opts = {}) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/droid/heroku/logger_client.rb', line 182

def syslog(msg, opts = {})
  @retried = false
  begin
    level = SyslogConvertion[opts[:level]]
    if opts[:exception]
      msg += "\n" + format_syslog_exception(opts[:exception])
    end
    syslog_resource.log(level, '%s', trim_syslog_msg(msg))
  rescue Exception => e
    failsafe(:log => { :level => 'error', :message => "could not log to syslog: #{e.class.name} #{e.message}"})
    unless @retried
      @retried = true
      @@syslog.close rescue nil
      @@syslog = Syslog.open(default_options[:component]) rescue nil
      retry
    end
  end
end

#syslog_resourceObject



214
215
216
# File 'lib/droid/heroku/logger_client.rb', line 214

def syslog_resource
  @@syslog ||= Syslog.open(default_options[:component].to_s, Syslog::LOG_PID | Syslog::LOG_CONS, default_options[:syslog_facility] || Syslog::LOG_USER)
end

#trim_syslog_msg(msg) ⇒ Object



209
210
211
212
# File 'lib/droid/heroku/logger_client.rb', line 209

def trim_syslog_msg(msg)
  return msg if msg.size < 800
  msg[0, 796] + " ..."
end

#warning(msg, options = {}) ⇒ Object



57
58
59
# File 'lib/droid/heroku/logger_client.rb', line 57

def warning(msg, options={})
  log msg, options.merge(:level => 'warning')
end

#web_error(args) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/droid/heroku/logger_client.rb', line 104

def web_error(args)
  e = args[:exception]
  summary = "#{e.class} processing #{args[:url]}"

  body = []
  body << "\tURL: #{args[:url]}"
  body << "\tParams: #{args[:params].inspect}"
  body << "\tUser: #{args[:user]}" if args[:user]
  body << "\tBacktrace:"
  body << "\t\t#{e.class} (#{e.message}):"
  body += e.backtrace.map { |l| "\t\t#{l}" }
  body = body.join("\n")

  log "#{summary}\n#{body}", :level => 'error'
end