Rails.logger.error(msg) したら Bugsnag にも通知しちゃうやつ
注意: quiet_assets など、broadcast 後に Rails.logger.level= する様な実装をしているケースには未対応。
こんな感じでやってみた。
- lib/ext と lib/bugsnag に分けたのは、Bugsnag クライアントが lib/bugsnag にマッチしたバックトレース行を読み飛ばしてくれる実装になっているから
- Bugsnag.configure の config.logger をセットしてるのは、デフォルトの Rails.logger を Bugsnag クライアント内部で使っているため(再帰回避)
- broadcast するタイミングはどこが適切かよくわかってない
diff --git a/config/application.rb b/config/application.rb index 3ddf16f..e10572f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -17,6 +17,8 @@ Bundler.require(*Rails.groups) module RailsExampleActivesupportLoggerBroadcast class Application < Rails::Application + config.autoload_paths += %W(#{config.root}/lib/ext #{config.root}/lib/bugsnag) + # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. @@ -31,5 +33,11 @@ module RailsExampleActivesupportLoggerBroadcast # Do not swallow errors in after_commit/after_rollback callbacks. config.active_record.raise_in_transactional_callbacks = true + + config.after_initialize do + error_logger = ErrorMonitor::Logger.new(:bugsnag) + error_logger.level = Logger::WARN + Rails.logger.extend ActiveSupport::Logger.broadcast(error_logger) + end end end diff --git a/config/initializers/bugsnag.rb b/config/initializers/bugsnag.rb index 3b6d7ae..2bff2a2 100644 --- a/config/initializers/bugsnag.rb +++ b/config/initializers/bugsnag.rb @@ -1,3 +1,4 @@ Bugsnag.configure do |config| config.api_key = ENV['BUGSNAG_API_KEY'] + config.logger = ActiveSupport::Logger.new(Rails.root.join('log/bugsnag.log')) end diff --git a/lib/bugsnag/error_monitor/bugsnag.rb b/lib/bugsnag/error_monitor/bugsnag.rb new file mode 100644 index 0000000..620e0ea --- /dev/null +++ b/lib/bugsnag/error_monitor/bugsnag.rb @@ -0,0 +1,15 @@ +module ErrorMonitor + class Bugsnag + def write(message) + if message[:options][:severity] >= Logger::ERROR + message[:options][:severity] = 'error' + elsif message[:options][:severity] >= Logger::WARN + message[:options][:severity] = 'warning' + else + message[:options][:severity] = 'info' + end + + ::Bugsnag.notify(message[:exception], message[:options]) + end + end +end diff --git a/lib/ext/error_monitor/logger.rb b/lib/ext/error_monitor/logger.rb new file mode 100644 index 0000000..cd4db68 --- /dev/null +++ b/lib/ext/error_monitor/logger.rb @@ -0,0 +1,20 @@ +require 'active_support/logger' + +module ErrorMonitor + class Logger < ActiveSupport::Logger + def initialize(*args) + @progname = nil + @level = ERROR + @default_formatter = proc do |severity, datetime, progname, msg| + { + exception: RuntimeError.new(msg), + options: { + severity: SEV_LABEL.index(severity) + } + } + end + @formatter = nil + @logdev = "ErrorMonitor::#{args.first.to_s.camelize}".constantize.new + end + end +end
追記
取り急ぎ Gem にしてみた。