German (Deutsch) translation by Alex Grigorovich (you can also view the original English article)
Wenn Sie New Relic zum ersten Mal kennenlernen, können Sie sich leicht von allen Funktionen überwältigen lassen. Aber wie bei den meisten Werkzeugen fragen Sie sich, wenn Sie langsam die Lernkurve erklimmen und sich mit den sofort einsatzbereiten Funktionen vertraut machen, wie alles unter der Haube zusammenhängt und ob Sie mit dem, was Sie haben, mehr anfangen können Hand.
Heute werde ich untersuchen, wie New Relic tatsächlich Transaktionen überwacht und wie Sie sich in den Prozess einbinden können. Wir werden einen kurzen Blick auf die Unterstützung werfen, die New Relic für die Überwachung von Hintergrundjobs bietet, und wir werden uns auch mit den benutzerdefinierten Metriken von New Relic befassen, wie Sie sie verwenden würden und welche Vorteile Sie daraus ziehen. Am Ende haben Sie ein tieferes Verständnis für die Funktionsweise von New Relic und können es besser nutzen. Mit anderen Worten, wir werden ein tieferes Wissen über unsere Tools haben - etwas, das jeder Entwickler anstreben sollte.
Lassen Sie uns zunächst einen kurzen Blick darauf werfen, wie sich New Relic tatsächlich einbindet, um die Leistung Ihrer Anwendung zu verfolgen.
Dieser Inhalt wurde von New Relic in Auftrag gegeben und vom Tuts+ -Team geschrieben und/oder bearbeitet. Unser Ziel mit gesponserten Inhalten ist es, relevante und objektive Tutorials, Fallstudien und inspirierende Interviews zu veröffentlichen, die unseren Lesern einen echten pädagogischen Wert bieten und es uns ermöglichen, die Erstellung nützlicherer Inhalte zu finanzieren.
Wie New Relic Transaktionen verfolgt und wie Sie dasselbe tun können
Es mag ein bisschen wie Magie erscheinen, Sie fügen einen Edelstein in Ihre Gemfile
ein:
1 |
gem 'newrelic_rpm' |
Und irgendwie überwacht New Relic Ihren gesamten Code. Natürlich ist es nur Code. Lassen Sie uns also sehen, wie New Relic Ihre App tatsächlich instrumentiert, damit sie sie überwachen kann, wenn der Agent Gem benötigt wird. Wir werden dies im Rahmen einer Rails 4-App tun.
Der erste Ort, an dem Sie suchen müssen, ist newrelic_rpm.rb
, der den folgenden relevanten Code enthält:
1 |
...
|
2 |
if Rails::VERSION::MAJOR.to_i >= 3 |
3 |
module NewRelic |
4 |
class Railtie < Rails::Railtie |
5 |
|
6 |
initializer "newrelic_rpm.start_plugin" do |app| |
7 |
NewRelic::Control.instance.init_plugin(:config => app.config) |
8 |
end
|
9 |
end
|
10 |
end
|
11 |
else
|
12 |
...
|
Wenn die Rails-Version über drei liegt, wird ein Railtie erstellt. Dadurch wird eine NewRelic::Control
-Singleton-Instanz (bei der Initialisierung) abgerufen und init_plugin
aufgerufen. Wenn die NewRelic::Control
-Instanz erstellt wird, wird ermittelt, welches Framework ausgeführt wird (in unserem Fall Rails 4), und es wird relevanter Code geladen. Wir können dies in new_relic/control/class_methods#load_framework_class
sehen. Die ausgeführte init_plugin
-Methode befindet sich in new_relic/control/instance_methods
. Der interessante Code hier ist:
1 |
...
|
2 |
if Agent.config[:agent_enabled] && !NewRelic::Agent.instance.started? |
3 |
start_agent
|
4 |
install_instrumentation
|
5 |
load_samplers unless Agent.config[:disable_samplers] |
6 |
...
|
Der Aufruf install_instrumentation
ist wichtig. Die Implementierung befindet sich in new_relic/control/instrumentation
. Wenn Sie die Boilerplate-Bits überspringen, wird ermittelt, welche Instrumentendateien geladen werden müssen, und diese werden dann einzeln benötigt. In unserem Fall werden Dateien unter new_relic/agent/instrumentation/rails4
geladen. Eine der Dateien hier ist action_controller.rb
. Wenn dies erforderlich wird, führt es schließlich den folgenden Code über eine Metaprogrammier-Magie aus:
1 |
executes do |
2 |
class ActionController::Base |
3 |
include NewRelic::Agent::Instrumentation::ControllerInstrumentation |
4 |
include NewRelic::Agent::Instrumentation::Rails4::ActionController |
5 |
end
|
6 |
NewRelic::Agent::Instrumentation::ActionControllerSubscriber \ |
7 |
.subscribe(/^process_action.action_controller$/) |
8 |
end
|
Und hier kommen wir zum Kern: ActionController::Base
(von dem alle Ihre Controller erben) enthält einige Module, von denen das wichtigste NewRelic::Agent::Instrumentation::ControllerInstrumentation
ist. Dies ist der Beginn, wie New Relic beginnt, alle Ihre Controller-Aktionen als "transactions" zu überwachen. Natürlich ist es eine etwas vereinfachte Ansicht und wir beschönigen viele Details, aber es gibt Ihnen eine Vorstellung davon, wie New Relic Ihren Code überwacht. Die Frage ist, wie können Sie diese Informationen verwenden?
Überwachen von benutzerdefinierten Frameworks und Hintergrundjobs
Vielleicht befinden Sie sich in einer Situation, in der Sie ein Webframework verwenden, für das New Relic (in der Ruby-Welt) noch keine Instrumente hat, aber sagen wir, Sie haben es getan. Wenn wir wissen, was wir jetzt wissen, können wir die Controller-Aktionen dieses benutzerdefinierten Frameworks einfach manuell instrumentieren. Wenn wir einen Controller wie diesen haben:
1 |
class CustomController |
2 |
def custom_action |
3 |
...
|
4 |
end
|
5 |
end
|
Wir können es so instrumentieren:
1 |
class CustomController |
2 |
include NewRelic::Agent::Instrumentation::ControllerInstrumentation |
3 |
|
4 |
def custom_action |
5 |
...
|
6 |
end
|
7 |
add_transaction_tracer :custom_action |
8 |
end
|
Jetzt wird Ihre Controller-Methode wie eine Transaktion auf die gleiche Weise verfolgt, wie Rails-Aktionen verfolgt werden. Wenn Sie ein eigenes Webframework erstellt haben, das Code für die Datenbankverarbeitung enthält, müssen Sie natürlich zusätzliche Arbeit leisten, um einen Großteil dieses Codes zu instrumentieren, damit New Relic mehr als nur Controller-Aktionen überwachen kann. Die allgemeine Idee bleibt jedoch stichhaltig.
Das obige Muster wird nützlicher, wenn New Relic Hintergrundjobs in Ihrer Anwendung verfolgen soll. Es ist viel wahrscheinlicher, dass Sie einen benutzerdefinierten Code für die Bearbeitung von Hintergrundjobs gerollt haben, als dass Sie Ihr eigenes Webframework geschrieben haben. Tatsächlich haben wir dies zunächst mit Tuts+ getan, obwohl wir jetzt auf Sidekiq migrieren. Wenn Sie eines der bekannten Hintergrundjobsysteme wie Sidekiq, Resque oder Delayed Job verwenden, ist in New Relic bereits eine Instrumentierung integriert. Wenn Sie jedoch Ihre eigenen Rollen erstellt haben, ist das obige Muster alles, was Sie zur Überwachung Ihrer Aufgaben benötigen.
Zum Beispiel waren unsere benutzerdefinierten Tuts+ Hintergrundjobs reguläre Ruby-Klassen, die auf die execute
methode reagierten. Alles, was wir tun müssen, ist Folgendes:
1 |
class SomeBackgroundJob |
2 |
include NewRelic::Agent::Instrumentation::ControllerInstrumentation |
3 |
|
4 |
def execute |
5 |
...
|
6 |
end
|
7 |
add_transaction_tracer :custom_action, category: :task |
8 |
end
|
Das letzte Bit, category: :task
, soll sicherstellen, dass New Relic es nicht als Webtransaktion verfolgt, sondern als Hintergrundaufgabe behandelt und auf der Registerkarte Hintergrundaufgaben in der Benutzeroberfläche von New Relic angezeigt wird. Wenn wir für alle unsere Jobs eine Basisklasse erstellen, können wir die Instrumentierung dort ablegen, und untergeordnete Klassen erben sie, sodass wir uns nicht in jeder Jobklasse darum kümmern müssen.
Anpassen einer Transaktion noch mehr
Interessant sind selbst die Webtransaktionen, die New Relic automatisch überwacht, nicht unantastbar. Sie können beispielsweise einige benutzerdefinierte Parameter hinzufügen, die für die aktuell ausgeführte Transaktion an New Relic gesendet werden sollen (wenn Sie die Erfassung von Parametern aktiviert haben).



Sie können dies jederzeit während der Transaktion tun. Alles, was Sie tun müssen, ist, jederzeit ::NewRelic::Agent.add_custom_parameters(:key => 'value')
aufzurufen, und die von Ihnen übergebenen Parameter werden zu den Parameterdaten hinzugefügt, die Sie in New Relic sehen. Wenn wir zum Beispiel einen Controller hätten, der so aussieht:
1 |
class HelloController < ApplicationController |
2 |
def index |
3 |
::NewRelic::Agent.add_custom_parameters(:hello => 'world') |
4 |
end
|
5 |
end
|
Langsame Transaktionen würden uns Folgendes geben:



Das ist nicht alles, was wir tun können. Wir können eine Transaktion während der Ausführung segmentieren, indem wir sie umbenennen. Angenommen, wir möchten eine Transaktion als etwas Besonderes behandeln, wenn sie von einem bestimmten Benutzer ausgeführt wird. Sie können so etwas tun:
1 |
class HelloController < ApplicationController |
2 |
def index |
3 |
new_relic_name = NewRelic::Agent.get_transaction_name |
4 |
if current_user.name == 'Joe Customer' |
5 |
NewRelic::Agent.set_transaction_name("#{new_relic_name} - Joe Customer") |
6 |
end
|
7 |
end
|
8 |
end
|
Jetzt wird diese Transaktion in der New Relic-Benutzeroberfläche als separate Transaktion behandelt:



Selbst die Standardinstrumente von New Relic können angepasst werden, aber manchmal, genau wie bei Captain Kirk, benötigen Sie einfach mehr Leistung. Hier kommen benutzerdefinierte Metriken ins Spiel.
New Relic Custom Metrics und wie sie nützlich sind
Früher hätten Sie benutzerdefinierte Metriken verwendet, um Dinge wie die Kommunikation externer Dienste und die Verwendung verschiedener gängiger Tools wie Redis zu überwachen. Heutzutage bietet New Relic bessere Möglichkeiten zur Überwachung dieses Materials. Wofür benötigen wir also benutzerdefinierte Metriken? Ich habe festgestellt, dass benutzerdefinierte Metriken in vier Situationen nützlich sind:
- Überwachungscode, den New Relic nicht sehen kann
- Überwachungscode, den Sie nicht kontrollieren
- Überwachungsskripte
- Überwachung vollständig benutzerdefinierter Ereignisse
Werfen wir einen kurzen Blick auf jeden von ihnen.
Überwachungscode Neues Relikt kann nicht sehen
New Relic ist ziemlich gut darin, die Leistung Ihrer verschiedenen Anwendungsmethoden in einem Transaktions-Trace zu beeinträchtigen, aber manchmal sehen Sie so etwas in einem Trace:



Es scheint, dass es einen Anwendungscode gibt, den New Relic aus irgendeinem Grund nicht instrumentieren konnte. Was wir tun können, ist New Relic (und uns selbst) mit einigen benutzerdefinierten Metriken zu helfen. Wir müssen herausfinden, welche Methode New Reli Probleme bei der Überwachung hatte, und einige benutzerdefinierte Metriken einbinden, um zu verfolgen, wie lange die Ausführung dieser Methode gedauert hat. Dies wird dann in allen nachfolgenden Spuren angezeigt. Angenommen, wir haben eine Klasse mit einer Methode, die wir über benutzerdefinierte Metriken überwachen möchten:
1 |
class Order |
2 |
def amount |
3 |
...
|
4 |
end
|
5 |
end
|
Wir können beginnen, die amount
methode folgendermaßen zu verfolgen:
1 |
require 'new_relic/agent/method_tracer' |
2 |
|
3 |
class Order |
4 |
include ::NewRelic::Agent::MethodTracer |
5 |
|
6 |
def amount |
7 |
...
|
8 |
end
|
9 |
add_method_tracer :amount, 'Custom/amount' |
10 |
end
|
Der zweite Parameter zu add_method_tracer
ist der Name, den diese benutzerdefinierte Metrik in der New Relic-Benutzeroberfläche erhält. Metriknamen sind durch Schrägstriche getrennte Zeichenfolgen, und alle benutzerdefinierten Metriken sollten mit "Custom/" beginnen. Sie können Ihre benutzerdefinierte Metrik beispielsweise als "Custom/<class_name>/<method_name>" bezeichnen. An diesem Punkt wird die amount
methode in Ihren Transaktionsspuren in der New Relic-Benutzeroberfläche angezeigt. Was aber, wenn unsere amount
methode sehr komplex ist und wir Teile davon überwachen möchten, von denen wir vermuten, dass sie langsam sind? Mein Rat ist, dass Sie Ihre Methode überarbeiten sollten - sie ist zu groß, aber wenn Sie das nicht können, können Sie zufälligen Code wie folgt instrumentieren:
1 |
class Order |
2 |
extend ::NewRelic::Agent::MethodTracer |
3 |
|
4 |
def amount |
5 |
...
|
6 |
self.class.trace_execution_scoped(['Custom/amount/complex_code']) do |
7 |
...complex code... |
8 |
end
|
9 |
...
|
10 |
end
|
11 |
end
|
Jetzt wird der instrumentierte Teil der Methode in Ihren Transaktionsspuren separat gemeldet. Wenn Sie zuvor die Methode selbst instrumentiert haben, wird Ihre neue "innere" Metrik unter der vorherigen gruppiert.
Dies ist bei weitem die häufigste Methode, mit der Sie benutzerdefinierte Metriken in Ihrem Code verwenden. Schauen wir uns jedoch die anderen an.
Überwachungscode, den Sie nicht kontrollieren
Oft verwenden Sie eine Bibliothek, die, wie Sie vermuten, Ihre Anwendung verlangsamt. New Relic instrumentiert standardmäßig keinen zufälligen Edelstein für Sie. Was können Sie also tun? Sie können den Edelstein mit der oben beschriebenen Methode teilen und einige Instrumente hinzufügen. Es gibt jedoch eine noch einfachere Lösung: Verwenden Sie Initialisierer. Angenommen, Sie verwenden die foobar
-Bibliothek, die eine Klasse Foo
mit einer Methoden bar
enthält, von der Sie vermuten, dass sie langsamen Code enthält. Sie müssen lediglich einen Initialisierer foobar_instrumentation.rb
erstellen und Folgendes einfügen:
1 |
require 'new_relic/agent/method_tracer' |
2 |
|
3 |
Foo.class_eval do |
4 |
include ::NewRelic::Agent::MethodTracer |
5 |
|
6 |
add_method_tracer :bar |
7 |
end
|
Wie Sie sehen können, ist der Code dem oben beschriebenen sehr ähnlich. New Relic ermittelt anhand des Klassen- und Methodennamens einen sinnvollen Namen für Ihre neue benutzerdefinierte Metrik, den Sie in Ihren Transaktionsspuren sehen. Verwenden Sie diese Option, um herauszufinden, ob diese verdächtige Bibliothek tatsächlich zu einer schlechten Leistung Ihres Codes führt. Bewahren Sie diese Instrumentierung jedoch nicht dauerhaft auf. Es spammt unnötige Initialisierer in Ihrer Rails-App und verschmutzt Ihre New Relic-Benutzeroberfläche mit benutzerdefinierten Metriken, die Sie nicht wirklich dauerhaft verfolgen müssen.
Skripte überwachen
Ein Teil von Webanwendungen, der häufig vernachlässigt wird, sind Skripte. Um eine Präsentation zu paraphrasieren, die ich kürzlich gemacht habe - sie sind immer noch Produktionscode und sollten als solche behandelt werden. Sie möchten nicht, dass der Produktionscode eine schlechte Leistung erbringt, insbesondere wenn Sie ihn fortlaufend über Cron-Jobs (oder eine ähnliche Methode, die kein Hintergrundjob in Ihrem System ist) ausführen. Daher können wir New Relic verwenden, um herauszufinden, ob Ihre Skripte sind langsam.
Sie können Ihren Skriptcode mithilfe der oben beschriebenen benutzerdefinierten Metriken instrumentieren. Es wird nicht in Transaktionsspuren angezeigt, da es nicht Teil einer Transaktion ist. Sie können jedoch aus den von Ihnen erfassten Metriken ein benutzerdefiniertes Dashboard erstellen, das Ihnen eine Vorstellung davon geben soll, ob Ihr Skript eine schlechte Leistung erbringt.
Sie können Ihr Skript auch als eine Art Hintergrundjob behandeln und entsprechend instrumentieren (einschließlich NewRelic::Agent::Instrumentation::ControllerInstrumentatio
n usw.). Es wird mit anderen Hintergrundjobs in der Benutzeroberfläche zusammengefasst, aber Sie müssen sich nicht um benutzerdefinierte Dashboards kümmern.
Die einzige Einschränkung bei Skripten ist folgende: New Relic sendet nur regelmäßig Daten über das Kabel. Mit einem einmaligen Skript, das schnell ausgeführt wird, müssen Sie sicherstellen, dass die gesammelten Daten tatsächlich gesendet werden. Daher müssen Sie den New Relic-Agenten möglicherweise manuell herunterfahren. Eine gute Faustregel ist, den Agenten am Anfang jedes Skripts manuell zu starten und am Ende herunterzufahren:
1 |
require 'newrelic_rpm' |
2 |
|
3 |
::NewRelic::Agent.manual_start |
4 |
|
5 |
... codez ... |
6 |
|
7 |
::NewRelic::Agent.shutdown |
Auf diese Weise müssen Sie sich nie fragen, warum Ihre Daten nicht in der Benutzeroberfläche angezeigt werden.
Überwachen vollständig benutzerdefinierter Ereignisse
Eines der interessanten Dinge an New Relic ist, dass Sie die Benutzeroberfläche und die Datenaggregationsfunktionen für Metriken nutzen können, die (theoretisch) nichts mit Leistung zu tun haben. Beispielsweise möchten Sie möglicherweise einen Überblick darüber erhalten, wie oft Benutzer sich bei Ihrer Anwendung anmelden, wie häufig Verkäufe getätigt werden oder wie viel Benutzer beim Kauf insgesamt zahlen. Dies sind mehr Geschäftsmetriken als Leistungsmetriken. Wenn es jedoch zu schwierig ist, diese separat zu verfolgen, können Sie New Relic verwenden, um dies zu tun.
Mit New Relic können Sie benutzerdefinierte Metriken direkt über zwei API-Aufrufe aufzeichnen:
record_metric
increment_metric
Sie können record_metric
verwenden, um jede Metrik zu verfolgen, die einen Betrag hat, und increment_metric
ist ziemlich selbsterklärend. So können wir zum Beispiel Folgendes tun:
1 |
...
|
2 |
def purchase(amount) |
3 |
...
|
4 |
::NewRelic::Agent.record_metric('Custom/purchase_amount', amount) |
5 |
::NewRelic::Agent.increment_metric('Custom/purchase_count') |
6 |
...
|
7 |
end
|
8 |
...
|
Die einzige Möglichkeit, diese Metriken in der Benutzeroberfläche anzuzeigen, besteht darin, einige benutzerdefinierte Dashboards zu erstellen. Ich muss erwähnen, dass dies eine etwas "kreative" Verwendung der New Relic-API wäre, da sie unter Berücksichtigung von Leistungsdaten entwickelt wurde, aber es ist sicherlich eine praktische Sache zu wissen, wann Sie ein schnelles Dashboard zusammenfügen müssen und nicht Ich möchte eine Reihe zusätzlicher Infrastrukturen einrichten.
Die Gefahren einer zu großen Überwachung
Natürlich hat all diese Kraft Kosten. Wenn Sie zu viele benutzerdefinierte Metriken erfassen, kann dies Ihre Anwendung verlangsamen. Dies kann auch die Benutzeroberfläche von New Relic verlangsamen und die Interpretation der Daten erschweren, da New Relic ähnliche Metriken zu einer Zusammenfassung zusammenfasst. New Relic empfiehlt, die Anzahl der von Ihnen erfassten benutzerdefinierten Metriken unter 2000 zu halten. Ich habe festgestellt, dass benutzerdefinierte Metriken am besten regelmäßig verwendet werden. Instrumentieren Sie den Code, den Sie benötigen, verwenden Sie die Instrumentierung, um das Problem zu lösen, und entfernen Sie dann die Instrumentierung. Auf diese Weise können Sie Ihre Leistungsprobleme lösen, und es ist unwahrscheinlich, dass die Anzahl der von Ihnen verwendeten benutzerdefinierten Metriken zu hoch wird.
Abschluss
Wir haben uns mit den Interna des Edelsteins newrelic_rpm
befasst und gelernt, wie Sie New Relic über Code informieren, den Sie als Webtransaktion betrachten. Wir haben uns angesehen, wie Transaktionen im laufenden Betrieb geändert werden können, wie Hintergrundjobs überwacht werden und in welchen verschiedenen Situationen es sinnvoll ist, benutzerdefinierte Metriken zu verwenden. Mit New Relic können Sie viel tun, das über die sofort einsatzbereiten Funktionen hinausgeht, und Sie können es jetzt viel besser nutzen. Es gibt jedoch immer mehr zu lernen, z.B. das Erstellen benutzerdefinierter Dashboards aus den von Ihnen erfassten Metriken oder das Überwachen der Infrastruktur mit Plugins. Wir werden diese und weitere Themen in den folgenden Artikeln behandeln. Schauen Sie also regelmäßig vorbei. Und wie immer, wenn Sie eine Frage haben, Ihre eigene New Relic-Geschichte teilen oder einfach nur Hallo sagen möchten, vergessen Sie nicht, einen Kommentar zu hinterlassen.