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