Статьи

Все рубины любят лесозаготовки

Иллюстрация 3d деревянного журнала

Если вы опытный работник Rails, вы, вероятно, воспримете логирование как должное. Однако, если вы один из единорогов, которые пишут приложения на Ruby и не используют Rails, вы, вероятно, сделали запись логов практически без изменений. Приложения, которые не используют базу данных в серверной части или локальные приложения в стиле командной строки без хранилища данных, могут фактически вообще не иметь журналирования. Это проблема? Должны ли вы беспокоиться? Что вообще такое логирование?

Что такое логирование?

Ведение журнала обычно относится к приложению, записывающему различные виды деятельности в файл (или базу данных, или консоль), как это происходит в приложении. Итак, сразу у нас есть довольно нечеткое определение.

  • Что именно вы должны вести? Ошибки? Сделки? Положение дел?
  • Для чего будут использоваться ваши журналы? Аудиторский след? Ошибка отслеживания? Отладка?
  • Кто будет смотреть на эти журналы? Разработчики? Менеджеры? Служба поддержки?

Если я до сих пор не прояснил, ведение журнала — это очень сложный бизнес-процесс. Хотя я не могу сказать вам, что регистрировать, я могу показать вам простой способ добавить ведение журнала в ваше приложение, будь то скрипт, приложение командной строки, веб-приложение Sinatra или что-то еще!

Класс: регистратор

Как разработчики Ruby, нам повезло, что у нас есть стандартная библиотека Ruby , которая снова покрывает нас. В классе Logger есть все, что нам нужно для большинства наших потребностей в журнале. Вы можете иметь один объект журнала для каждого типа журнала, или один для каждого класса, или любую другую комбинацию, которую вы можете себе представить. Для новичка и для большинства простых и умеренных потребностей я обнаружил, что один журнал, который управляет ими, работает хорошо.

Один журнал, чтобы управлять ими всеми

Как добавить это в свое приложение?

require 'logger' class MyLog def self.log if @logger.nil? @logger = Logger.new STDOUT @logger.level = Logger::DEBUG @logger.datetime_format = '%Y-%m-%d %H:%M:%S ' end @logger end end 

Вот и все. Теперь все ваше приложение может записывать в журнал строку вроде этой:

 MyLog.log.info "Look, ma! I'm loggin'!" 

Поскольку он пишет в STDOUT , вы увидите это в своем терминале:

 I, [2014-08-13 15:18:50-0600 #65630] INFO -- : Look, ma! I'm loggin'! 

Как это устроено

Давайте разберемся, что на самом деле делает наш код. Во-первых, мы кое-что не делаем.

Мы не создаем экземпляр объекта logger непосредственно в нашем приложении и не передаем этот объект, все в стиле ООП. Вместо этого мы создаем небольшой класс с именем MyLog с единственным методом класса с именем log . Этот единственный метод проверяет, существует ли объект регистратора, создает его, если он не существует, и возвращает его. Разработчики Ruby обычно не пишут много методов класса, но это умный способ создать глобально доступный объект.

Вы можете просто создать глобальную переменную:

 $log = Logger.new STDOUT $log.level = Logger::DEBUG $log.datetime_format = '%Y-%m-%d %H:%M:%S%z ' 

Но поскольку глобальные переменные изменчивы, он менее стабилен, чем класс с методом класса.

В блоке faux-initialize мы создаем экземпляр объекта Logger, устанавливаем, куда направляется вывод, устанавливаем уровень журнала и устанавливаем формат даты и времени.

 if @logger.nil? @logger = Logger.new STDOUT @logger.level = Logger::DEBUG @logger.datetime_format = '%Y-%m-%d %H:%M:%S%z ' end 

Записи в журнале настроены на переход в STDOUT , но вы можете так же легко направить их в файл с чем-то вроде:

 @logger = Logger.new 'path/to/log/files/log.txt' 

Поначалу уровень журнала немного сложен для понимания, но он в основном контролирует, какая информация записывается в журнал. При указании регистратору писать «уровень» сообщения может быть указан. Это полезно, потому что вы можете установить уровень Logger::WARN для производства, то есть записаны WARN , FATAL , ERROR и UNKNOWN . Таким образом, строки отладки в вашем коде не будут загромождать производственные журналы. Когда вы пишете новые функции или исправляете ошибки в разработке, поднимите уровень до Logger::Debug и все журналы отладки и информации также начнут появляться. Доступны следующие уровни (в порядке «от наиболее серьезных» до «наименее серьезных»):

  • НЕИЗВЕСТНО — не могу даже. Всегда пишется в лог.
  • ФАТАЛЬНО — фатальные ошибки и другие серьезные несчастья.
  • ОШИБКА — произошла ошибка. Кто-то должен это исправить.
  • ПРЕДУПРЕЖДЕНИЕ . Возможно, произошла ошибка. Кто-то, возможно, должен это исправить.
  • ИНФОРМАЦИЯ — Если вам интересно …
  • DEBUG — более сложная версия отладки в стиле put.

Есть соответствующий метод для каждого из уровней. Например, @logger.fatal("App is dying!!") напишет сообщение на FATAL уровне. Класс Logger также имеет методы запросов для каждого уровня (т.е. fatal? ), @logger позволяет вам спросить @logger , поддерживает ли он в настоящее время этот уровень ведения журнала.

Вам решать, на каком уровне должна быть каждая запись в журнале, но как только вы начнете добавлять журналы в свое приложение, становится очевидной разница между фатальной ошибкой, общей информацией и данными отладки.

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

Идите дальше и войдите

С тех пор, как я начал играть с Logger, я больше всего использовал DEBUG и INFO .

DEBUG отлично подходит для проверки содержимого переменной, определения того, вызывается ли определенный метод, отслеживания хода выполнения цикла или всего, что вы хотите отслеживать в своем приложении. В отличие от отладки в стиле, вы можете просто оставить эти вызовы журналов на месте, уменьшить уровень на вашем регистраторе и больше не видеть эти данные в ваших журналах или в консоли. Хотите проверить, соответствует ли массив ожидаемому размеру? Звоните в ваш логгер и смотрите это в своем журнале:

 D [2014-08-13 15:23:42-0600 #65631] DEBUG -- : Array length: 42 

42 вещи в моей жизни, вселенной и множестве всего … это кажется правильным!

INFO хорош для простого ведения журнала транзакций. Базы данных обычно предоставляют такие вещи бесплатно, но скрипты, приложения командной строки или веб-приложения без хранилища данных могут выиграть от ведения общего журнала аудита. Например, вы можете записать завершение определенной задачи:

 I, [2014-08-13 15:25:21-0600 #65632] INFO -- : David published an article. 

Позже, если вы хотите знать, когда Дэвид опубликовал статью, БАМ! это в твоих логах.

MyLog.log.info «Завершение»

Вы используете Ruby Logger? Может быть, у вас есть любимый драгоценный камень для решения всех ваших задач? Если вы уже несколько раз обходили блок регистрации, какие методы и конструкции сработали для вас? Зарегистрируйте свою информацию в комментариях!