Создание пользовательского регистратора Rails

Я использую Rails 5 и мне нужно создать собственный регистратор Rails.

Например, в некоторых местах контроллеров я хочу, чтобы эти вызовы регистрировались:

Rails.logger.info('Event happened',
  { event_id: '...', email: '...', ...}
)

И наконец, в моем файле журнала я хочу увидеть что-то вроде этого:

{
  "level": "info",
  "ts": 1507972311.8043,
  "caller": "controller/api/v2/news.rb:101",
  "msg": "Event happened",
  "app": "My App",
  "env": "production",
  "context": {
    "event_id": "1234567",
    "email": "[email protected]",
    "first_name": "John",
    "last_name": "Doe"
  }
}

Это возможно? Как сделать это для всех уровней лога (информация/отладка/ошибка) одновременно?


person Community    schedule 18.07.2017    source источник
comment
Вы можете использовать что-то вроде этого. logger.debug {Хэш атрибутов человека: #{@person.attributes.inspect}}   -  person Srikanth    schedule 18.07.2017


Ответы (2)


Создайте свою собственную оболочку:

class LocalLogger

  def self.log(*args)
    new.log(*args)
  end

  def logger
    Rails.logger
  end
  delegate :info, :debug, :warn, :error, to: :logger

  def log(level: :info, payload)
    send(level, payload.inspect)
  end
end

LocalLogger.log level: :warn, {foo: bar}

Измените метод log, чтобы он вел себя так, как вы хотите.

Тем не менее, избегайте искушения быть слишком умным с этим - поведение регистратора по умолчанию довольно хорошее и будет вести себя так, как ожидает большинство других разработчиков.

person ReggieB    schedule 18.07.2017
comment
у меня не работает: `синтаксическая ошибка, неожиданный tIDENTIFIER (SyntaxError) def log(level: :info, payload)` - person Sergio Belevskij; 23.11.2018
comment
Проверьте свою версию Ruby. Этот синтаксис не будет работать со старыми версиями Ruby. Если это так, попробуйте def log(level, payload), а затем используйте LocalLogger.log :warn, {foo: :bar} - person ReggieB; 23.11.2018

Лучшим решением было бы объявить собственный Logger#formatter:

Rails.logger.      
      instance_variable_get(:@logger).
      instance_variable_get(:@log).
      formatter = proc do |severity, datetime, progname, msg|
                    DO WHATEVER YOU WANT HERE
                  end
person Aleksei Matiushkin    schedule 18.07.2017
comment
Не сломается ли это, если Rails.logger изменит свою реализацию? - person Kris; 18.07.2017
comment
@Kris Очевидно, будет. Использование Rails означает, что все может сломаться, когда Rails изменит свою реализацию. Даже Rails.logger может перестать существовать. - person Aleksei Matiushkin; 18.07.2017
comment
В той же основной версии он не сломался бы, если бы вы использовали их общедоступный API. Вот почему я бы обернул Rails.logger, используя SimpleDelegator. - person Kris; 19.07.2017