Когда вы впервые знакомитесь с New Relic , легко быть пораженным всеми функциями . Но, как и в случае с большинством инструментов, когда вы медленно поднимаетесь по кривой обучения и знакомитесь с функциями, предоставляемыми из коробки, вы начинаете удивляться, как все это свисает под капотом, и если есть еще что-то, что вы можете сделать с тем, что у вас есть в рука.
Сегодня я расскажу о том, как New Relic на самом деле отслеживает транзакции и как вы можете подключиться к процессу. Мы быстро взглянем на поддержку, оказываемую New Relic для мониторинга фоновых заданий, а также рассмотрим пользовательские метрики New Relic, их использование и преимущества, которые вы получите от этого. К концу у вас будет более глубокое понимание того, как работает New Relic, и вы сможете использовать его более полно. Другими словами, у нас будет более глубокое знание наших инструментов — то, к чему должен стремиться каждый разработчик.
Давайте начнем с краткого обзора того, как на самом деле подключается New Relic для отслеживания производительности вашего приложения.
Это содержание было заказано New Relic и было написано и / или отредактировано командой Tuts +. Наша цель в отношении спонсируемого контента состоит в том, чтобы публиковать соответствующие и объективные учебные пособия, тематические исследования и вдохновляющие интервью, которые предлагают реальную образовательную ценность нашим читателям и позволяют нам финансировать создание более полезного контента.
Как New Relic отслеживает транзакции и как вы можете сделать то же самое
Это может показаться немного магическим, вы включаете драгоценный камень в свой Gemfile
:
1
|
gem ‘newrelic_rpm’
|
И так или иначе New Relic контролирует весь ваш код. Конечно, это всего лишь код, поэтому давайте посмотрим, как New Relic на самом деле оснащает ваше приложение, чтобы оно могло начать отслеживать его, когда требуется гем агента. Мы сделаем это в контексте приложения Rails 4.
Первое, что нужно посмотреть, это newrelic_rpm.rb
, в котором есть следующий соответствующий код:
01
02
03
04
05
06
07
08
09
10
11
12
|
…
if Rails::VERSION::MAJOR.to_i >= 3
module NewRelic
class Railtie < Rails::Railtie
initializer «newrelic_rpm.start_plugin» do |app|
NewRelic::Control.instance.init_plugin(:config => app.config)
end
end
end
else
…
|
Поэтому Railtie создается, когда версия Rails выше трех, получает одноэлементный экземпляр NewRelic::Control
(когда он инициализируется) и вызывает init_plugin
. Когда NewRelic::Control
экземпляр NewRelic::Control
он выясняет, какой фреймворк работает (в нашем случае Rails 4) и загружает некоторый соответствующий код; мы можем увидеть это в new_relic/control/class_methods#load_framework_class
. init_plugin
метод init_plugin
в new_relic/control/instance_methods
. Интересный код здесь:
1
2
3
4
5
6
|
…
if Agent.config[:agent_enabled] && !NewRelic::Agent.instance.started?
start_agent
install_instrumentation
load_samplers unless Agent.config[:disable_samplers]
…
|
Важным является вызов install_instrumentation
. Реализация живет в new_relic/control/instrumentation
. Пропуск шаблонных битов позволяет определить, какие файлы инструментов нужно загрузить, а затем требует их один за другим. В нашем случае, он будет загружать файлы в new_relic/agent/instrumentation/rails4
. Одним из файлов здесь является action_controller.rb
, когда это требуется, в конечном итоге он выполняет следующий код с помощью некоторой магии метапрограммирования :
1
2
3
4
5
6
7
8
|
executes do
class ActionController::Base
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
include NewRelic::Agent::Instrumentation::Rails4::ActionController
end
NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
.subscribe(/^process_action.action_controller$/)
end
|
И здесь мы ActionController::Base
к сути: ActionController::Base
(от которой наследуются все ваши контроллеры) получает несколько модулей, наиболее важным из которых является NewRelic::Agent::Instrumentation::ControllerInstrumentation
. Это начало того, как New Relic начинает отслеживать все ваши действия контроллера как «транзакции». Конечно, это несколько упрощенное представление, и мы скрываем много деталей, но оно дает вам представление о том, как New Relic контролирует ваш код. Вопрос в том, как вы можете использовать эту информацию?
Мониторинг пользовательских каркасов и фоновых заданий
Вы вряд ли окажетесь в ситуации, когда вы используете веб-фреймворк, для которого у New Relic еще нет инструментария (в мире Ruby), но, допустим, у вас есть. Зная, что мы знаем сейчас, мы можем легко вручную контролировать действия контроллера этой пользовательской платформы. Если у нас есть контроллер, как это:
1
2
3
4
5
|
class CustomController
def custom_action
…
end
end
|
Мы можем инструмент это так:
1
2
3
4
5
6
7
8
|
class CustomController
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
def custom_action
…
end
add_transaction_tracer :custom_action
end
|
Теперь ваш метод контроллера будет отслеживаться как транзакция так же, как отслеживаются действия Rails. Конечно, если вы развернули свою собственную веб-среду, которая включает в себя код обработки базы данных, вам потребуется проделать дополнительную работу, чтобы обработать большую часть этого кода, чтобы позволить New Relic контролировать не только действия контроллера. Но общая идея остается здравой.
Приведенный выше шаблон становится более полезным, когда вы хотите, чтобы New Relic отслеживал фоновые задания в вашем приложении. У вас гораздо больше шансов накатить какой-нибудь пользовательский фоновый код обработки заданий, чем на собственный веб-фреймворк. На самом деле, мы изначально делали это с Tuts +, хотя сейчас мы переходим на Sidekiq. Если вы используете одну из известных систем фоновых заданий, таких как Sidekiq , Resque или Delayed Job , в New Relic уже есть встроенные инструменты, но если вы выполнили свою собственную работу, вышеприведенный шаблон — это все, что вам нужно для мониторинга ваших задач.
Например, наши пользовательские фоновые задания Tuts + были обычными классами ruby, которые отвечали на метод execute
, поэтому все, что нам нужно сделать, это:
1
2
3
4
5
6
7
8
|
class SomeBackgroundJob
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
def execute
…
end
add_transaction_tracer :custom_action, category: :task
end
|
Последний бит, category: :task
, должен гарантировать, что New Relic не отслеживает ее как веб-транзакцию, а вместо этого обрабатывает ее как фоновую задачу и отображает ее на вкладке фоновых задач в интерфейсе New Relic. Если мы создадим базовый класс для всех наших работ, мы сможем разместить инструментарий там, и дочерние классы унаследуют его, поэтому нам не нужно беспокоиться о выполнении вышеупомянутого в каждом классе работ.
Настройка транзакции еще больше
Интересно, что даже веб-транзакции, которые New Relic автоматически отслеживает, не являются священными. Например, вы можете добавить некоторые пользовательские параметры для отправки в New Relic для транзакции, которая выполняется в данный момент (если вы включили параметры захвата).
Вы можете сделать это в любой момент во время транзакции. Все, что вам нужно сделать, это вызвать ::NewRelic::Agent.add_custom_parameters(:key => 'value')
в любое время, и передаваемые вами параметры будут добавлены к данным параметров, которые вы видите внутри New Relic. Например, если у нас был контроллер, который выглядел так:
1
2
3
4
5
|
class HelloController < ApplicationController
def index
::NewRelic::Agent.add_custom_parameters(:hello => ‘world’)
end
end
|
Медленные транзакции дали бы нам следующее:
Это не все, что мы можем сделать. Мы можем сегментировать транзакцию во время ее выполнения, переименовав ее. Допустим, мы хотим трактовать транзакцию как особенную, когда она выполняется конкретным пользователем. Вы можете сделать что-то вроде этого:
1
2
3
4
5
6
7
8
|
class HelloController < ApplicationController
def index
new_relic_name = NewRelic::Agent.get_transaction_name
if current_user.name == ‘Joe Customer’
NewRelic::Agent.set_transaction_name(«#{new_relic_name} — Joe Customer»)
end
end
end
|
Теперь эта транзакция будет обрабатываться как отдельная транзакция в интерфейсе New Relic:
Даже по умолчанию в инструментах New Relic есть место для настройки, но иногда, как и у Captain Kirk , вам просто нужно больше энергии. Это где пользовательские метрики приходят.
Новые метрики Relic Custom & как они полезны
В свое время вы бы использовали пользовательские метрики для мониторинга таких вещей, как обмен данными с внешними сервисами и использование различных распространенных инструментов, таких как Redis . В наши дни у New Relic есть лучшие способы мониторинга этого материала , так зачем нам нужны собственные метрики? Я обнаружил, что пользовательские метрики полезны в четырех ситуациях:
- контрольный код, который New Relic не видит
- контрольный код, который вы не контролируете
- скрипты мониторинга
- мониторинг абсолютно пользовательских событий
Давайте кратко рассмотрим каждый из них.
Мониторинг код новой реликвии не вижу
New Relic довольно хорошо разбивает производительность различных методов приложения в трассировке транзакций, но иногда вы можете увидеть что-то подобное в трассировке:
Кажется, есть код приложения, который New Relic по какой-то причине не смог установить. Что мы можем сделать, так это помочь New Relic (и нам самим) с помощью некоторых пользовательских метрик. Нам нужно выяснить, какой метод New Relic имел проблемы с мониторингом, и подключить некоторые пользовательские метрики, чтобы отслеживать, сколько времени потребовалось для выполнения этого метода. Это тогда появится во всех последующих следах. Допустим, у нас есть класс с методом, который мы хотим отслеживать с помощью пользовательских метрик:
1
2
3
4
5
|
class Order
def amount
…
end
end
|
Мы можем начать отслеживать метод amount
следующим образом:
01
02
03
04
05
06
07
08
09
10
|
require ‘new_relic/agent/method_tracer’
class Order
include ::NewRelic::Agent::MethodTracer
def amount
…
end
add_method_tracer :amount, ‘Custom/amount’
end
|
Второй параметр add_method_tracer
— это имя, которое эта пользовательская метрика получит в интерфейсе New Relic. Имена метрик — это разделенные косой чертой строки, и все пользовательские метрики должны начинаться с ‘Custom /’. Например, вы можете назвать свою пользовательскую метрику как «Custom / <имя_класса> / <имя_метода>». В этот момент вы начнете видеть метод amount
в следах транзакций в интерфейсе New Relic. Но что, если наш метод amount
очень сложен, и мы хотим отслеживать его части, которые, как мы подозреваем, являются медленными? Я советую вам реорганизовать свой метод — он слишком большой, но если вы не можете этого сделать, вы можете использовать произвольный код следующим образом:
01
02
03
04
05
06
07
08
09
10
11
|
class Order
extend ::NewRelic::Agent::MethodTracer
def amount
…
self.class.trace_execution_scoped([‘Custom/amount/complex_code’]) do
…complex code…
end
…
end
end
|
Теперь инструментальная часть метода будет сообщаться отдельно в ваших транзакциях. Если вы ранее инструктировали сам метод, ваша новая «внутренняя» метрика будет сгруппирована под предыдущей.
Это, безусловно, самый распространенный способ использования пользовательских метрик в вашем коде, но в любом случае давайте рассмотрим другие.
Код мониторинга, который вы не контролируете
Часто вы можете использовать библиотеку, которая, как вы подозреваете, замедляет работу вашего приложения. Новая Реликвия по умолчанию не станет инструментом для вас, так что вы можете сделать? Вы можете разветвлять гем и добавить некоторые инструменты, используя метод, который мы видели выше, но существует еще более простое решение — использовать инициализаторы. Допустим, вы используете библиотеку foobar
которой есть класс Foo
с bar
методов, которая, как вы подозреваете, содержит медленный код. Все, что вам нужно сделать, это создать инициализатор foobar_instrumentation.rb
и поместить в него следующее:
1
2
3
4
5
6
7
|
require ‘new_relic/agent/method_tracer’
Foo.class_eval do
include ::NewRelic::Agent::MethodTracer
add_method_tracer :bar
end
|
Как вы можете видеть, код очень похож на тот, что был у нас выше, New Relic разработает разумное имя для вашей новой пользовательской метрики на основе имени класса и метода, и вы начнете видеть его в следах транзакций. Используйте это, чтобы определить, действительно ли эта подозрительная библиотека приводит к тому, что ваш код работает плохо, но не держите эту инструментацию постоянно. Он спамит ненужные инициализаторы в вашем приложении Rails и загрязняет ваш пользовательский интерфейс New Relic пользовательскими метриками, которые вам не нужно постоянно отслеживать.
Скрипты мониторинга
Одна часть веб-приложений, которой часто пренебрегают, — это скрипты. Перефразируя презентацию, которую я сделал недавно — они все еще являются рабочим кодом и должны рассматриваться как таковые. Вы не хотите, чтобы производственный код работал плохо, особенно если вы выполняете его на постоянной основе с помощью заданий cron (или аналогичного метода, который не является фоновым заданием в вашей системе), поэтому мы можем использовать New Relic, чтобы выяснить, ваши сценарии медленные
Вы можете использовать свой код сценария с помощью пользовательских метрик, как описано выше. Он не будет отображаться в следах транзакций, поскольку он не будет частью транзакции. Однако вы сможете создать собственную панель мониторинга на основе собранных вами метрик, которая должна дать вам представление о том, плохо ли работает ваш скрипт.
Другая вещь, которую вы можете сделать, это обработать ваш скрипт как тип фонового задания и соответствующим образом его NewRelic::Agent::Instrumentation::ControllerInstrumentation
(включая NewRelic::Agent::Instrumentation::ControllerInstrumentation
и т. Д.). Он будет объединен с другими фоновыми заданиями в пользовательском интерфейсе, но вам не нужно беспокоиться о пользовательских панелях мониторинга.
Единственное предостережение со сценариями: New Relic периодически отправляет данные по сети. С помощью одноразового скрипта, который выполняется быстро, вам нужно будет убедиться, что собранные данные действительно будут отправлены, поэтому вам может потребоваться отключить агент New Relic вручную. Хорошее практическое правило — вручную запускать агент в начале каждого сценария и выключать его в конце:
1
2
3
4
5
6
7
|
require ‘newrelic_rpm’
::NewRelic::Agent.manual_start
… codez …
::NewRelic::Agent.shutdown
|
Таким образом, вам никогда не придется удивляться, почему ваши данные не отображаются в пользовательском интерфейсе.
Мониторинг полностью пользовательских событий
Одна из интересных особенностей New Relic заключается в том, что он позволяет использовать преимущества пользовательского интерфейса и средств агрегирования данных для показателей, которые не имеют никакого отношения к производительности (теоретически). Например, вы можете захотеть получить представление о том, как часто пользователи регистрируются в вашем приложении, частоте продаж или общей сумме, которую пользователи платят при совершении покупок. Это больше бизнес-показателей, чем показателей производительности, но если отслеживать их по отдельности слишком сложно, вы можете использовать New Relic для этого.
Новая Relic позволяет записывать пользовательские метрики напрямую с помощью двух вызовов API:
-
record_metric
-
increment_metric
Вы можете использовать record_metric
для отслеживания любой метрики, у которой есть сумма, и increment_metric
довольно record_metric
. Таким образом, мы можем, например, сделать это:
1
2
3
4
5
6
7
8
|
…
def purchase(amount)
…
::NewRelic::Agent.record_metric(‘Custom/purchase_amount’, amount)
::NewRelic::Agent.increment_metric(‘Custom/purchase_count’)
…
end
…
|
Единственный способ увидеть эти показатели в пользовательском интерфейсе — это создать несколько пользовательских панелей мониторинга. Я должен упомянуть, что это было бы несколько «творческим» использованием New Relic API, так как он разработан с учетом данных о производительности, но это, безусловно, удобная вещь, чтобы знать, когда вам нужно собрать быструю информационную панель вместе и не хочу создать кучу дополнительной инфраструктуры.
Опасности мониторинга слишком много
Конечно, вся эта сила имеет свою стоимость. Если вы соберете слишком много пользовательских метрик, это может замедлить работу вашего приложения. Это также может замедлить работу пользовательского интерфейса New Relic и затруднить интерпретацию данных, поскольку New Relic свернет аналогичные показатели в итоговые. New Relic рекомендует сохранить количество пользовательских метрик ниже 2000 . Я обнаружил, что пользовательские показатели лучше всего использовать периодически. Внесите необходимый код, воспользуйтесь инструментарием, чтобы решить возникшую проблему, а затем удалите инструментарий. Таким образом, вы решаете свои проблемы с производительностью, и количество используемых вами пользовательских показателей вряд ли будет слишком большим.
Вывод
Мы newrelic_rpm
внутреннюю часть newrelic_rpm
и узнали, как сообщить New Relic о коде, который вы рассматриваете как веб-транзакцию. Мы рассмотрели, как изменять транзакции на лету, как отслеживать фоновые задания и различные ситуации, в которых имеет смысл использовать пользовательские метрики. Вы можете многое сделать с New Relic, помимо функциональности, которую он предоставляет «из коробки», и теперь вы гораздо более способны использовать ее в полной мере. Но всегда есть чему поучиться, например, как создавать собственные панели мониторинга на основе показателей, которые вы собираете, или как отслеживать инфраструктуру с помощью плагинов . Мы рассмотрим эти и другие темы в следующих статьях, поэтому не забывайте проверять их часто. И, как всегда, если у вас есть вопрос, вы хотите поделиться своей историей New Relic или просто сказать привет, не забудьте оставить комментарий.