class SemanticLogger::Appender::Bugsnag
def bugsnag_notify(exception, hash, level)
def bugsnag_notify(exception, hash, level) if ::Bugsnag::VERSION.to_i >= 6 ::Bugsnag.notify(exception) do |report| report.severity = level hash.each_pair { |key, value| report.add_tab(key, value) } end else hash[:severity] = level ::Bugsnag.notify(exception, hash) end end
def call(log, logger)
def call(log, logger) hash = SemanticLogger::Formatters::Raw.new.call(log, logger) hash.delete(:message) if hash[:exception] && (hash[:message] == hash[:exception][:message]) hash.delete(:time) hash.delete(:level_index) hash.delete(:exception) hash[:file] = "#{hash[:file]}:#{hash.delete(:line)}" if hash.key?(:file) hash end
def extract_exception(log)
def extract_exception(log) if log.exception # Manually constructed Exception, without a backtrace. log.exception.set_backtrace(log.backtrace) if !log.exception.backtrace && log.backtrace return log.exception end error = RuntimeError.new(log.message) error.set_backtrace(log.backtrace) if log.backtrace error end
def initialize(level: :error, **args, &block)
Proc: Only include log messages where the supplied Proc returns true
regular expression. All other messages will be ignored.
RegExp: Only include log messages where the class name matches the supplied.
filter: [Regexp|Proc]
Default: Use the built-in formatter (See: #call)
the output from this appender
An instance of a class that implements #call, or a Proc to be used to format
formatter: [Object|Proc]
Default: :error
Override the log level for this appender.
level: [:trace | :debug | :info | :warn | :error | :fatal]
Parameters
Create Bugsnag Error / Exception Appender
def initialize(level: :error, **args, &block) raise "Bugsnag only supports :info, :warn, or :error log levels" unless %i[info warn error fatal].include?(level) # Replace the Bugsnag logger so that we can identify its log messages and not forward them to Bugsnag ::Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] } super end
def log(log)
def log(log) # Ignore logs coming from Bugsnag itself return false if log.name == "Bugsnag" # Send error messages as Runtime exceptions exception = extract_exception(log) hash = formatter.call(log, self) bugsnag_notify(exception, hash, log_level(log.level)) true end
def log_level(level)
def log_level(level) case level when :error, :fatal "error" when :warn "warning" else "info" end end