Um herauszufinden, welche spezifischen Teile des Codes Performance-Probleme verursachen, ist es nützlich, Ihrer Anwendung benutzerdefinierte Instrumentierung hinzuzufügen. Dies ermöglicht es uns, bessere Aufschlüsselungen darüber zu erstellen, welcher Code am langsamsten läuft und auf welche Art von Action die meiste Zeit verwendet wurde.
Wenn Sie gespeicherte Samples langsamer Requests in AppSignal anzeigen, sehen Sie alle Instrumentierungen, die Ihre Anwendung intern verwendet. Template-Rendering, ActiveRecord-Abfragen und Caching werden instrumentiert und im Sample angezeigt.
Das ist bereits sehr nützlich, aber wäre es nicht großartig, wenn wir
Messungen spezifischer Codeteile sehen könnten, von denen Sie vermuten, dass sie Ihre
Performance beeinflussen? Nun, das können Sie!
Durch das Hinzufügen benutzerdefinierter Instrumentierung können wir detailliertere Aufschlüsselungen eines Requests und eines Hintergrundjobs erstellen. Es gibt zwei Möglichkeiten, Ihren Code zu instrumentieren. Mit AppSignal-Instrumentierungs-Helpern oder mit ActiveSupport-Notifications-Instrumentierung, wie sie von Rails verwendet wird.
Hinweis: Diese Seite beschreibt nur, wie Sie Performance-Instrumentierung zu
Ihrem Code hinzufügen. Um Fehler zu verfolgen, lesen Sie bitte unseren Leitfaden zur Exception-Handhabung.
Instrumentierungs-Helper
Wenn Sie Ihrem Code benutzerdefinierte Instrumentierung hinzufügen, können Sie noch
mehr Einblicke in Ihre Anwendung erhalten. Beispielsweise müssen Sie mit einer
externen API arbeiten, die Artikel für Ihre Homepage abruft:
class ArticleFetcher
def self.fetch(category)
Appsignal.instrument('fetch.article_fetcher') do
# Download and process the articles
end
end
end
ArticleFetcher.fetch('Latest news')
Sobald Sie solche benutzerdefinierten Instrumente hinzufügen, beginnt AppSignal, sie aufzugreifen
und zeigt Ihnen, wie viel Zeit sowohl eine Event-Gruppe (article_fetcher in diesem
Fall) als auch einzelne Events benötigt haben.
In diesem Fall werden Sie feststellen, dass dieser API-Aufruf einen großen Einfluss auf die
Performance unserer Homepage hat, was zuvor verborgen war. Wir könnten in Betracht ziehen,
die Artikel zu cachen.
Hinweis: Der Name des Events, das Sie instrumentieren, ist für unseren
Processor wichtig. Mehr über die Event-Benennung erfahren Sie hier.
Verschachtelte Instrumentierung
Sie können beliebig viele Instrumente in beliebiger Kombination verwenden. Sie können
instrument-Aufrufe verschachteln, und AppSignal verarbeitet die Verschachtelung und Aggregate
der Messungen sauber. Sie müssen nur das letzte Segment (nach dem letzten
Punkt) des Schlüssels konsistent halten.
Appsignal.instrument('fetch.article_fetcher') do
10.times do
Appsignal.instrument('fetch_single_article.article_fetcher') do
# Fetch single article
end
end
end
Mehr Daten pro Event erfassen
Standardmäßig erfasst AppSignal die Dauer eines Events und sendet sie an unsere
Server. Da benutzerdefinierte Instrumentierung nicht mit Framework-Internas verbunden ist,
müssen Sie möglicherweise mehr Daten mitschicken, wenn Sie möchten, dass Event-Details
in AppSignal erscheinen. Das kann ein beschreibender Titel sein oder spezifischere
Informationen wie die Abfrage aus einem Datenbankaufruf. Wir tun dies bereits für
ActiveRecord, Sequel, Redis, MongoDB, Sinatra, Grape,
und mehr.
Es gibt zwei Helper, mit denen Sie Ihren Code mit AppSignal instrumentieren können.
Appsignal.instrument(name, title = nil, body = nil, body_format = Appsignal::EventFormatter::DEFAULT, &block)
# and
Appsignal.instrument_sql(name, title = nil, body = nil, &block)
name-Argument
Der Name des Events, der im Event-Baum in AppSignal erscheint.
Mehr über die Benennung von Event-Schlüsseln erfahren Sie hier.
title-Argument
Ein beschreibenderer Titel eines Events, wie z. B. "Fetch current user" oder "Fetch blog post comments". Er erscheint neben dem Event-Namen im Event-Baum
auf der Performance-Sample-Seite, um etwas mehr Kontext zu dem zu liefern, was
gerade passiert.
Appsignal.instrument('fetch.custom_database', 'Fetch current user') do
# ...
end
body-Argument
Weitere Details, wie z. B. eine Datenbankabfrage, die vom Event verwendet wurde.
sql = 'SELECT * FROM posts ORDER BY created_at DESC LIMIT 1'
Appsignal.instrument('fetch.custom_database', 'Fetch latest post', sql) do
# ...
end
Warnung: Bitte stellen Sie sicher, dass die Body-Payloads bereinigt
(sensible/dynamische Daten entfernt) sind. Nicht bereinigte Body-Events werden
verworfen, wenn sie ein bestimmtes Limit erreichen.
Gut:
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do
# ...
end
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/?') do
# ...
end
Schlecht:
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/123') do
# ...
end
Appsignal.instrument('custom.instrument', 'Instrument stuff', 'command/dynamic/234') do
# ...
end
Wenn Sie eine SQL-Abfrage als Body übergeben, können Sie dafür body_format = Appsignal::EventFormatter::SQL_BODY_FORMAT verwenden.
body_format-Argument
Body-Format unterstützt Formatter, um die im body-Argument angegebenen Daten zu bereinigen
und sensible Daten aus dem Wert zu entfernen. Es gibt derzeit zwei unterstützte
Werte für das body_format-Argument.
Wert Appsignal::EventFormatter::DEFAULT
Appsignal::EventFormatter::DEFAULT ist der Standardwert dieses
Arguments. Standardmäßig lässt AppSignal den Wert unverändert und bereinigt keine
Daten daraus.
Wert Appsignal::EventFormatter::SQL_BODY_FORMAT
Der Wert Appsignal::EventFormatter::SQL_BODY_FORMAT führt Ihre Daten
durch den SQL-Sanitizer und bereinigt alle Werte in SQL-Abfragen.
Wir empfehlen, stattdessen den Appsignal.instrument_sql-Helper dafür zu verwenden.
SELECT * FROM users WHERE email = 'hector@appsignal.com' AND password = 'iamabot'
-- becomes
SELECT * FROM users WHERE email = ? AND password = ?
ActiveSupport::Notifications
In älteren Versionen des AppSignal-Gems (1.2 und niedriger) ist
Appsignal.instrument nicht verfügbar. Wenn Sie kein Upgrade durchführen können, ist es weiterhin
möglich, stattdessen ActiveSupport::Notifications zu verwenden. Wenn Sie nicht
den Appsignal.instrument-Helper, sondern stattdessen
ActiveSupport::Notifications verwenden möchten, können Sie dies auch in AppSignal für Ruby-Gem
1.3 und höher tun.
Die Methode zur Instrumentierung Ihres Codes mit ActiveSupport::Notifications
ähnelt sehr der von AppSignal. Mit dem Article-Fetcher-Beispiel
können Sie wieder erkennen, dass die Unterschiede ziemlich gering sind.
Siehe auch unsere Dokumentation zu AppSignal-Event-Formattern bei Verwendung von ActiveSupport::Notifications.
Weitere Informationen zur ActiveSupport::Notifications-Instrumentierung finden Sie in der offiziellen Rails-ActiveSupport::Notifications-Dokumentation.
require "active_support"
class ArticleFetcher
def self.fetch(category)
ActiveSupport::Notifications.instrument("fetch.article_fetcher") do
# Download and process the articles
end
end
end
ArticleFetcher.fetch("Latest news")
Es funktioniert auch bei verschachtelten Instrumentierungs-Aufrufen.
require "active_support"
ActiveSupport::Notifications.instrument("fetch.article_fetcher") do
10.times do
ActiveSupport::Notifications.instrument("fetch_single_article.article_fetcher") do
# Fetch single article
end
end
end
ActiveSupport::Notifications ist sehr flexibel, Sie können Ihren Code
auf jede gewünschte Weise instrumentieren. Weitere Informationen zu ActiveSupport::Notifications finden Sie in den
Rails-API-Dokumenten.
Warnung: Wir verfolgen keine privaten ActiveSupport::Notifications-Events,
die mit einem Ausrufezeichen (!) beginnen. Diese Events sind überwiegend private
Events, die von Rails erzeugt werden.