Статьи

Оптимизация ведения журнала Ruby для более быстрой отладки и решения проблем

Эта статья была спонсирована Loggly . Спасибо за поддержку спонсоров, которые делают возможным использование SitePoint.

В английском языке слова, оканчивающиеся на суффикс «-ly», обычно классифицируются как наречия. Наречия для грамматически оспариваемых (и многих из нас разработчиков) модифицируют глаголы. Вот несколько примеров с выделенными наречиями:

  • Иезавель бежит быстро . (имеется в виду, очень быстро)
  • Комментарий тролля скрытно скрывается за анонимностью интернета. (имеется в виду, как слабак или незаметно)

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

Логгли: адв . Записано в полном и расширяемом виде. Разумный разработчик развернул приложение loggly ».

Я не воспринимаю эту рекомендацию легкомысленно . В то время как любой язык является живым, дышащим, добавление новых терминов должно производиться только тогда, когда обнаруживается, что концепция недостаточно представлена ​​в существующей идиоме. Испытав сервис, предлагаемый Loggly , я чувствую, что такая концепция была найдена.

В этой статье я собираюсь взглянуть на Loggly с точки зрения Rubyist, объясняя, как настроить Loggly, добавив его в пример Leaderboards . Если вы читали эту статью, то знаете, что Leaderboard — это простое приложение Rails, размещенное на Heroku. Он имеет некоторое поведение JavaScript, что позволит мне показать некоторые журналы на стороне клиента.

Но сначала давайте посмотрим, почему вы хотите войти в систему в первую очередь, прежде чем переходить к настройке для наших целей.

Зачем регистрироваться?

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

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

Как только вы согласились с необходимостью войти, возникает новая проблема. У большинства приложений есть тонны движущихся частей: операционная система, веб-сервер, приложение, база данных, фоновые задания… и это лишь некоторые из них. Все эти части имеют один или несколько процессов для регистрации, и мы даже не говорили о кластеризации. Как вы управляете всеми журналами, когда вам нужно увидеть за кулисами производства? Loggly может помочь с простым и расширяемым поиском в журнале, интуитивно понятным пользовательским интерфейсом, развертыванием без агентов (я думаю, что это лучшая часть) и моделью с оплатой по мере использования.

Настройка

Зайдите в Loggly и зарегистрируйтесь для бесплатной учетной записи. Различные страницы настройки легко становятся доступны после того, как вы войдете в систему и используете поддомен своей учетной записи Loggly (user.loggly.com), так что вы можете следовать моим настройкам ниже.

logglyruby1 - домашняя страница loggly

Когда вы попадете на страницу «Настройка источника», вы легко увидите, как настроить Loggly для операционных систем, приложений на стороне сервера и приложений на стороне клиента. Я попробую настроить его с помощью Rails и Angular, чтобы добавить Loggly в мой пример списка лидеров, о котором я упоминал выше. Я создал ветку в хранилище приложений для этих изменений здесь .

Серверный

Когда дело доходит до использования Loggly с Rails, у вас есть несколько вариантов. Первый — настроить syslog на использование Loggly, а затем использовать гем syslogger в вашем приложении. Во-вторых, использовать гем logglier , который я решил сделать.

Настройка gem logglier — это стандартная вещь Rails: 1) поместите информацию о конфигурации в инициализатор, 2) войдите как обычно .

Gemfile

gem 'logglier' 

(Не забудьте связать)

конфиг / Инициализаторы / loggly.rb

 loggly = Logglier.new('<a href="https://logs-01.loggly.com/inputs/3e8f8c6f-2161-4544-8c04-bc134ac82590/tag/rails">https://logs-01.loggly.com/inputs/3e8f8c6f-2161-4544-8c04-bc134ac82590/tag/rails</a>', threaded: true, format: :json) <br /> Rails.logger.extend(ActiveSupport::Logger.broadcast(loggly)) 

Чувак, эта настройка была сделана быстро , но не торопливо . К вашему сведению, это будет работать только в Rails 4, поскольку добавлена ​​возможность трансляции логов нескольким регистраторам. Если вы находитесь на Rails 3, посмотрите этот пост .

Время писать в журнал Rails, как если бы мы не использовали Loggly:

приложение / контроллеры / leaderboards_controller.rb

 class LeaderboardsController < ApplicationController before_action :query_options def show Rails.logger.info("Showing a leaderboard") ...rest of file... 

Серьезно , это может быть проще?

Поскольку я хотел бы полностью вам сообщить, учтите, что приведенная выше конфигурация будет отправлять ВСЕ журналы Rails в Loggly. Это означает, что все шаблоны рендеринга и все остальное Rails болтали в свои логи. Если вам не нравится это, вы можете разумно включить что-то вроде логгирования, чтобы немного успокоить вещи. Я покажу несколько примеров позже.

Сторона клиента

Сколько ваших приложений регистрируется на клиенте? У вас есть ваш javascript для отправки событий журнала? Как насчет ваших приложений для iOS или Android? Могу поспорить, что большинство из нас почти не заходят от клиента.

К счастью, существует созданный сообществом модуль Angular с открытым исходным кодом для Loggly, который называется (достаточно креативно ) angular-loggly . Большая часть конфигурации — это стандартный материал Angular, когда вы включаете источник в свой конвейер активов.

application.js

 //= require angular/angular //= require angular-loggly/logglyService.min # I added this //= require_tree 

Обратите внимание, что если вы не используете файл .min , вам нужно будет отдельно загрузить javascript Loggly.

leaderboards.js.erb

 var App = angular.module('App', ['loggly']) .run(function(loggly) { loggly.setApiKey('3e8f8c6f-2161-4544-8c04-bc134ac82590'); }) ...existing angular code... 

Опять же, большая часть того, что мне было нужно, это Angular bootstrapping. Я включаю модуль Loggly в зависимости от приложения, затем настраиваю ключ API в функции run, которая запускается один раз для загрузки страницы.

Теперь это просто вопрос регистрации с использованием сервиса Loggly. Вот как я изменил директиву entryForm , которая обрабатывает редактирование одной записи entryForm лидеров, когда пользователь дважды щелкает по партитуре:

 .directive('entryForm', function (loggly){ // Inject loggly service return { restrict: 'E', scope: { entry: '=entry' }, templateUrl: "<%=asset_path 'templates/entry_form.html'%>", link: function(scope, elem, attrs) { var input = elem.find('input'), form = elem.find('form'); scope.editing = false; elem.bind('dblclick', function(){ loggly.info("Editing started"); // Call loggly scope.editing = true; input.select(); scope.$apply(); }); input.bind('keydown', function(e) { switch(e.which) { case 13: //Enter form.submit(); case 27: //Esc loggly.info("Editing Cancelled") // Call loggly scope.editing = false; } scope.$apply(); }); } }; }) 

И логирование на стороне клиента обрабатывается ловко . Rockin’.

Инфраструктура — Heroku

Последнее, что я продемонстрирую вам сегодня, — это настройку Loggly как утечки журналов для Heroku. Как и в большинстве вещей Heroku, это легко:

 $> heroku drains:add https://logs-01.loggly.com/bulk/<your loggly token>/tag/heroku --ap <your heroku app name> Successfully added drain https://logs-01.loggly.com/bulk/<your loggly token>/tag/heroku updating...done. Updated to 3.30.3 

Обратите внимание, что он просто использует конечную точку массовых событий Loggly HTTP / S, которая, как ни удивительно , позволяет обрабатывать как отдельные, так и массовые события. В основном, просто настройте любое приложение для POST на http://logs-01.loggly.com/inputs/ /tag/http/ http://logs-01.loggly.com/inputs/ /tag/http/ , вот так:

 curl -H "content-type:text/plain" -d '{ "message" : "hello" }' http://logs-01.loggly.com/inputs/<token>/tag/http/ 

И вы сделали. Основная конечная точка позволяет отправлять 5 МБ на пакет.

Между HTTP / S и File Monitoring (еще одна функция, которую мы, к сожалению, опускаем в этой статье), нет абсолютно ничего, что не может быть зарегистрировано. Ничего. Не стесняйтесь тратить свое время неразумно, пытаясь придумать один.

Loggly в действии

Трудно понять, когда и как вам понадобится решение для ведения журнала, прежде чем запускать приложение в производство. Приложения просто не ведут себя так же, как в процессе разработки. Здесь я рассмотрю несколько примеров из моего собственного использования приложения Leaderboard, которое я упоминал ранее .

Напомним, что это приложение Rails, состоящее из простой таблицы лидеров, способной принимать имя и оценку для новой записи, возвращать представление JSON с указанным именем, поддерживать представление HTML и JSON всех записей в таблице лидеров, а не разрешить возвращение более 100 записей для одного запроса и удалить указанное имя из списка лидеров. Я использовал redis и гем лидеров от пользователя Github agoragames .

Вот скриншот того, что я придумал, но перейдите по ссылке выше для полной истории.

logglyruby2 - таблица лидеров

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

Ошибки журнала

Loggly умело собрал веб-интерфейс пользователя, который является интуитивно понятным и расширяемым. После того, как вы определили некоторые события, нажмите на вкладку «Dashboards» в верхней части страницы Loggly и вот что-то вроде этого:

logglyruby3 - панель приборов

Панель инструментов отображает гистограмму «Все события» за последний час. Это легко изменить за последние 24 часа одним щелчком мыши. Также есть «Сохраненные поиски», «Оповещения» и «Лучшие значения». Это панель инструментов по умолчанию, но вы можете добавить свою собственную, просто щелкнув ссылку «+ Новый» на панели вкладок.

С этим мощным пользовательским интерфейсом в моих руках и игрой с функциями приложения Leaderboard я заметил, что я получаю ошибки в журналах для некоторых записей POST / /:

 2015-04-12 13:30:10.837 UTC at=info method=POST path="/entries/" host=ccleader.herokuapp.com request_id=0e02eb90-f4bc-4e30-b5c9-7773d8dc3517 fwd="75.190.154.129" dyno=web.1 connect=1ms service=63ms status=404 bytes=1804 2015-04-12 13:27:25.863 UTC at=info method=POST path="/entries/" host=ccleader.herokuapp.com request_id=98e34aee-c08d-4b5c-b8d9-fc495293a12ffwd="75.190.154.129" dyno=web.1 connect=0ms service=10ms status=404 bytes=1804 

Другой информации не было.

К счастью , вкладка «Поиск» в Loggly позволяет вам вводить поисковый запрос или тэг, указывать диапазон дат (крайне важный при просмотре журналов), избранные поиски или создавать оповещения из поиска. Поиски также включают полнотекстовый поиск, так что вы можете точно определить запись, когда это необходимо.

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

В поисках этих 404-х: их было много. Loggly также имеет очень удобную кнопку «Просмотр окружающих событий» при выборе записи в журнале, которая отображает события вокруг выбранного события. Когда я нажал на это, он показал:

logglyruby4 - окружающие события

Таким образом, некоторые из удалений для записей были неудачными. Но почему? Я не мог воспроизвести это. В обычном приложении Rails / ActiveRecord был бы параметр id, связанный с запросом. Здесь мы используем имя, которое отсутствует в запросе выше. Запрос должен выглядеть так:

 Started DELETE "/entries/Catherine%20Lynch%20MD" 

но похоже

 Started DELETE "/entries/" 

В нашей таблице лидеров должен быть пустой строковый ключ. Похоже, нам нужна проверка … (которую я с удовольствием оставлю в качестве упражнения для пользователя.)

Отслеживание запроса

Вот еще одно потенциальное приложение для ведения журнала: отслеживание запроса по всем частям, через которые он проходит в течение своего жизненного цикла (веб-сервер, приложение, объекты служб и т. Д.). Простое решение — добавить Request ID в HTTP-запрос и заставить Rails писать это в журнал. Как объясняется в этой статье в блоге Heroku, добавьте:

 config.log_tags =[:uuid] 

… В config / application.rb или config / environment / production.rb . Теперь, когда я нахожу неправильный запрос, я могу получить этот id , найти его в пользовательском интерфейсе Loggly и получить все связанные записи журнала. Из приведенного выше примера один из 404 имел request id d52588de-6aee-42d5-b223-3e2586388d61 . Ища это в пользовательском интерфейсе Loggly, я получаю записи журнала Rails и маршрутизатора.

 2015-04-12 16:49:27.361 UTC at=info method=POST path="/entries/" host=ccleader.herokuapp.com request_id=d52588de-6aee-42d5-b223-3e2586388d61 fwd="75.190.154.129" dyno=web.1 connect=5ms service=73ms status=404 bytes=1804 2015-04-12 16:49:27.299 UTC [d52588de-6aee-42d5-b223-3e2586388d61] Started DELETE "/entries/" for 75.190.154.129 at 2015-04-12 16:49:27 +0000 

Вы можете увидеть тег UUID добавленный к записи Rails выше. Это может быть чрезвычайно полезно в сочетании с пользовательским интерфейсом Loggly.

logglyruby5 - тег uuid

Заворачивать

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

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

Пока вы это делаете, я буду связываться с Вебстером по поводу добавления моей новой наречи…