Я настроил регистратор в Rails с более приятным однострочным форматом, который хорошо работает для большинства типов сообщений во время обычной разработки. Некоторое время назад я получил этот код, и он пытается
# application.rb
config.logger = ActiveSupport::Logger.new("#{Rails.root}/log/#{Rails.env}.log", 10, 10 * 1024 * 1024)
config.logger.formatter = proc do |severity, time, program, msg|
begin
if program.nil?
program = caller
.find { |path| path.start_with? Rails.root.to_s }
.split('/').last
.split(':')[0,2].join(':')
# callee = caller[5].split('/').last
# callee = callee.split(':')[0,2].join(':')
# program = callee
end
rescue Exception => e
# do nothing
end
# disabled for development
message = msg.to_s.gsub("\n", " ")
"#{time} - #{severity} - #{program} - #{message}\n"
end
Однако мне также нужно обрабатывать исключения, вызванные ошибками контроллера. Чтобы обрабатывать все исключения в контроллерах и корректно восстанавливаться с них (т.е. не нарушать API JSON, но показывать что-то значимое для пользователя), я добавил следующий модуль ExceptionHandler
:
module ExceptionHandler
extend ActiveSupport::Concern
included do
rescue_from StandardError do |e|
logger.error(e.message)
# render an error to the user
end
end
end
Теперь, когда регистрируется исключение, проблема в том, что его источник всегда будет происходить из самого обработчика исключения:
2020-03-20 08:54:07 +0000 - ERROR - exception_handler.rb:116 - comparison of Integer with String failed
Как я могу сказать регистратору, что на самом деле program
быть источником исключения?
Я знаю, что могу получить его через Rails.backtrace_cleaner.clean(e.backtrace).first
, но как мне передать это регистратору? Я мог бы добавить это к message
вручную, но это побеждает цель.