Utilisation de nouvelles métriques personnalisées Relic pour tout contrôler

Lorsque vous vous familiarisez avec New Relic, il est facile d’être submergé par toutes les fonctionnalités. Mais comme avec la plupart des outils, alors que vous montez lentement dans la courbe d’apprentissage et que vous vous familiarisiez avec les fonctions fournies, vous commencez à vous demander comment tout cela se tient sous le capot. main.

Aujourd'hui, je vais voir comment New Relic surveille réellement les transactions et comment vous pouvez vous en servir. Nous examinerons rapidement l'assistance fournie par New Relic pour la surveillance des tâches en arrière-plan. Nous étudierons également les métriques personnalisées de New Relic, leur utilisation et les avantages qui en découlent. À la fin, vous comprendrez mieux le fonctionnement de New Relic et pourrez l’utiliser plus pleinement. En d’autres termes, nous aurons une connaissance plus approfondie de nos outils, ce que chaque développeur devrait rechercher..

Commençons par examiner rapidement comment New Relic s’installe pour suivre les performances de votre application..

Contenu sponsorisé

Ce contenu a été commandé par New Relic et a été écrit et / ou édité par l'équipe de Tuts +. Notre objectif avec le contenu sponsorisé est de publier des tutoriels pertinents et objectifs, des études de cas et des interviews inspirantes qui offrent une véritable valeur éducative à nos lecteurs et nous permettent de financer la création de contenu plus utile..


Comment New Relic suit les transactions et comment vous pouvez en faire autant

Cela peut sembler un peu magique, vous incluez un joyau dans votre Gemfile:

gem 'newrelic_rpm'

Et en quelque sorte, New Relic surveille tout votre code. Bien sûr, il ne s'agit que de code. Voyons donc comment New Relic instrumente réellement votre application afin qu'elle puisse commencer à la surveiller lorsque la gemme de l'agent est requise. Nous ferons cela dans le contexte d'une application Rails 4.

Le premier endroit à regarder est newrelic_rpm.rb, qui contient le code pertinent suivant:

… Si Rails :: VERSION :: MAJOR.to_i> = 3 module Nouvelle classe Railtie deRelic < Rails::Railtie initializer "newrelic_rpm.start_plugin" do |app| NewRelic::Control.instance.init_plugin(:config => app.config) end end end else… 

Donc, un Railtie est créé lorsque la version de Rails est supérieure à trois, cela donne une NewRelic :: Control instance singleton (quand elle est initialisée) et appelle init_plugin. Quand le NewRelic :: Control Par exemple, il est créé qui détermine quel framework est en cours d’exécution (Rails 4 dans notre cas) et charge du code pertinent; on peut le voir dans new_relic / control / class_methods # load_framework_class. le init_plugin méthode qui est exécutée vit dans new_relic / control / instance_methods. Le code intéressant ici est:

… Si Agent.config [: agent_enabled] &&! NewRelic :: Agent.instance.started? start_agent install_instrumentation load_samplers à moins que Agent.config [: disable_samplers]… 

le install_instrumentation L'appel est l'important. La mise en œuvre vit dans new_relic / control / instrumentation. En sautant les bits de passe-partout, cela détermine quels fichiers d'instrumentation il doit charger puis les exige un par un. Dans notre cas, il chargera des fichiers sous nouveau_relique / agent / instrumentation / rails4. Un des fichiers ici est action_controller.rb, quand cela devient nécessaire, il exécute finalement le code suivant via une magie de métaprogrammation:

exécute la classe ActionController :: Base include NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation include NewRelic :: Agent :: Instrumentation :: Rails4 :: ActionController et NewRelic :: Agent :: Instrumentation :: ActionControllerSubscriber \ .subscribe (/ ^ process_action .action_controller $ /) end

Et nous arrivons au coeur de celui-ci: ActionController :: Base (dont tous vos contrôleurs héritent) obtient deux modules inclus, le plus important étant NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation. C’est le début de la manière dont New Relic commence à surveiller toutes les actions de votre contrôleur en tant que «transactions». Bien sûr, il s’agit d’une vue quelque peu simplifiée et nous dissimulons beaucoup de détails, mais cela vous donne une idée de la façon dont New Relic surveille votre code. La question est, comment pouvez-vous utiliser cette information?

Surveillance des cadres personnalisés et des travaux en arrière-plan

Il est très peu probable que vous vous retrouviez dans une situation où vous utilisiez un framework Web pour lequel New Relic ne dispose pas déjà d'instrumentation (dans le monde Ruby), mais supposons que vous en possédiez une. Sachant ce que nous savons maintenant, nous pouvons facilement instrumenter manuellement les actions du contrôleur de ce cadre personnalisé. Si nous avons un contrôleur comme celui-ci:

class CustomController def custom_action… end end

Nous pouvons l'instrumenter comme suit:

La classe CustomController inclut NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation de custom_action… end add_transaction_tracer: custom_action end

Désormais, votre méthode de contrôleur sera suivie comme une transaction de la même manière que les actions Rails. Bien sûr, si vous avez créé votre propre framework Web incluant du code de gestion de base de données, vous devrez effectuer un travail supplémentaire pour instrumenter une grande partie de ce code, afin de permettre à New Relic de surveiller davantage que les actions du contrôleur. Mais l'idée générale reste bonne.

Le modèle ci-dessus devient plus utile lorsque vous souhaitez que New Relic assure le suivi des tâches en arrière-plan dans votre application. Il est beaucoup plus probable que vous ayez obtenu du code de traitement de tâche en arrière-plan personnalisé que d'avoir écrit votre propre framework Web. En fait, c'est ce que nous avons fait avec Tuts + au départ, bien que nous passions maintenant à Sidekiq. Si vous utilisez l'un des systèmes de tâches d'arrière-plan bien connus tels que Sidekiq, Resque ou Delayed Job, New Relic a déjà une instrumentation intégrée, mais si vous lancez la vôtre, le modèle ci-dessus est tout ce dont vous avez besoin pour surveiller vos tâches..

Par exemple, nos tâches d’arrière-plan personnalisées Tuts + étaient des cours de rubis standard répondant au exécuter méthode, donc tout ce que nous devons faire est la suivante:

la classe SomeBackgroundJob inclut NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation de def execute… end add_transaction_tracer: custom_action, catégorie:: task end

Le dernier bit, catégorie:: tâche, est de s'assurer que New Relic ne la suit pas comme une transaction Web, mais la traite plutôt comme une tâche en arrière-plan et la fait apparaître sous l'onglet Tâches en arrière-plan de l'interface utilisateur de New Relic. Si nous créons une classe de base pour tous nos emplois, nous pouvons y placer l'instrumentation et les classes enfants en hériteront, afin que nous n'ayons pas à nous soucier de faire ce qui précède dans chaque classe d'emploi..

Personnaliser une transaction encore plus

Chose intéressante, même les transactions Web que New Relic surveille automatiquement ne sont pas sacro-saintes. Vous pouvez, par exemple, ajouter des paramètres personnalisés à envoyer à New Relic pour la transaction en cours d'exécution (si vous avez activé la capture de paramètres)..

Vous pouvez le faire à tout moment de la transaction. Il suffit d'appeler :: NewRelic :: Agent.add_custom_parameters (: key => 'value') à tout moment et les paramètres que vous transmettez seront ajoutés aux données de paramètres que vous voyez dans New Relic. Par exemple, si nous avions un contrôleur qui ressemblait à ceci:

classe HelloController < ApplicationController def index ::NewRelic::Agent.add_custom_parameters(:hello => 'monde') fin fin

Les transactions lentes nous donneraient ce qui suit:

Ce n'est pas tout ce que nous pouvons faire. Nous pouvons segmenter une transaction en cours en la renommant. Supposons que nous voulions traiter une transaction comme spéciale lorsqu'elle est effectuée par un utilisateur particulier. Vous pouvez faire quelque chose comme ça:

classe 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

Maintenant, cette transaction sera traitée comme une transaction séparée dans la nouvelle interface utilisateur de Relic:

Même l'instrumentation New Relic par défaut peut encore être personnalisée, mais parfois, à l'instar du capitaine Kirk, vous avez simplement besoin de plus de puissance. C'est là qu'interviennent les métriques personnalisées.


Nouvelles métriques personnalisées Relic et leur utilité

De retour dans la journée, vous auriez utilisé des métriques personnalisées pour surveiller des éléments tels que la communication de service externe et l'utilisation de divers outils courants tels que Redis. De nos jours, New Relic dispose de meilleurs moyens de surveillance de ces éléments. Pourquoi avons-nous besoin de statistiques personnalisées? J'ai trouvé que les métriques personnalisées étaient utiles dans quatre situations:

  • code de surveillance que New Relic ne peut pas voir
  • code de surveillance que vous ne contrôlez pas
  • scripts de surveillance
  • surveillance d'événements totalement personnalisés

Jetons un coup d'oeil à chacun d'eux.

Code de surveillance Nouvelle relique impossible à voir

New Relic est très efficace pour décomposer les performances de vos différentes méthodes d'application dans une trace de transaction, mais vous verrez parfois quelque chose comme ceci dans une trace:

Il semble qu'il existe un code d'application que New Relic n'a pas pu instrumenter pour une raison quelconque. Ce que nous pouvons faire, c'est aider New Relic (et nous-mêmes) avec des métriques personnalisées. Nous devons déterminer quelle méthode New Relic a eu du mal à surveiller et ajouter des métriques personnalisées pour suivre le temps nécessaire à l’exécution de cette méthode. Ceci apparaîtra dans toutes les traces suivantes. Disons que nous avons une classe avec une méthode que nous voulons surveiller via des métriques personnalisées:

classe Ordre def montant… fin fin

Nous pouvons commencer à suivre la montant méthode comme suit:

Requiert la classe 'new_relic / agent / method_tracer'. Ordre include include: NewRelic :: Agent :: MethodTracer def montant… end add_method_tracer: amount, 'Custom / amount'

Le deuxième paramètre à add_method_tracer est le nom que cette métrique personnalisée obtiendra dans la nouvelle interface utilisateur Relic. Les noms de métriques sont des chaînes séparées par des barres obliques et toutes les métriques personnalisées doivent commencer par «Personnalisé /». Vous pouvez, par exemple, nommer votre métrique personnalisée comme "Personnalisé //'. À ce stade, vous commencerez à voir le montant méthode dans vos traces de transaction, dans l'interface utilisateur de New Relic. Mais, si notre montant La méthode est très complexe et nous voulons en surveiller les parties que nous soupçonnons être lentes? Mon conseil est que vous devriez refactoriser votre méthode - elle est trop grosse, mais si vous ne pouvez pas faire ça, vous pouvez instrumenter du code au hasard de la manière suivante:

class Ordre étendre :: NewRelic :: Agent :: MethodTracer par défaut… self.class.trace_execution_scoped (['Custom / amount / complex_code']) do… code complexe… fin… fin fin

Maintenant, la partie instrumentée de la méthode sera rapportée séparément dans vos traces de transaction. Si vous avez déjà instrumenté la méthode elle-même, votre nouvelle métrique «interne» sera regroupée sous la précédente..

C’est de loin le moyen le plus courant d’utiliser des métriques personnalisées dans votre code, mais examinons quand même les autres..

Code de surveillance que vous ne contrôlez pas

Vous utilisez souvent une bibliothèque qui, vous le soupçonnez, ralentit votre application. New Relic n'instrumentera par défaut aucune gemme aléatoire. Que pouvez-vous faire? Vous pouvez utiliser la méthode décrite ci-dessus pour ajouter une instrumentation et ajouter une instrumentation, mais une solution encore plus simple existe: les initialiseurs d’utilisation. Disons que vous utilisez le foobar bibliothèque qui a une classe Foo avec une méthode bar que vous soupçonnez d'avoir un code lent. Tout ce que vous avez à faire est de créer un initialiseur foobar_instrumentation.rb, et y mettre le texte suivant:

require 'new_relic / agent / method_tracer' Foo.class_eval n'inclut pas :: NewRelic :: Agent :: MethodTracer add_method_tracer: fin de barre

Comme vous pouvez voir que le code est très similaire à ce que nous avons eu ci-dessus, New Relic établira un nom judicieux pour votre nouvelle métrique personnalisée en fonction du nom de la classe et de la méthode et vous commencerez à le voir dans vos traces de transaction. Utilisez ceci pour déterminer si cette bibliothèque suspecte nuit réellement à votre code, mais ne conservez pas cette instrumentation de manière permanente. Il envoie des initialiseurs inutiles dans votre application Rails et pollue votre interface utilisateur New Relic avec des métriques personnalisées que vous n'avez pas vraiment besoin de suivre en permanence..

Scripts de surveillance

Les scripts sont une partie des applications Web souvent négligée. Pour paraphraser une présentation que j'ai faite récemment, il s'agit toujours d'un code de production et doit être traité comme tel. Vous ne voulez pas que le code de production fonctionne mal, surtout si vous l'exécutez de manière continue via des tâches cron (ou une méthode similaire qui n'est pas une tâche d'arrière-plan dans votre système), afin que nous puissions utiliser New Relic pour déterminer si vos scripts sont lents.

Vous pouvez instrumenter votre code de script en utilisant des métriques personnalisées, comme décrit ci-dessus. Cela n'apparaîtra pas dans les traces de transaction, car cela ne fera pas partie d'une transaction. Ce que vous pourrez cependant faire, c’est créer un tableau de bord personnalisé à partir des métriques que vous collectez, ce qui devrait vous donner une idée de la mauvaise performance de votre script..

Vous pouvez également traiter votre script comme un type de travail d’arrière-plan et l’instrumenter en conséquence (inclure NewRelic :: Agent :: Instrumentation :: ControllerInstrumentation etc). Il sera regroupé avec d'autres tâches d'arrière-plan dans l'interface utilisateur, mais vous n'avez pas à vous soucier des tableaux de bord personnalisés..

La seule réserve avec les scripts est la suivante: New Relic n'envoie que des données sur le réseau périodiquement. Avec un script unique qui s'exécute rapidement, vous devez vous assurer que les données collectées sont réellement envoyées. Vous devrez donc peut-être arrêter l'agent New Relic manuellement. En règle générale, démarrez manuellement l'agent au début de chaque script et fermez-le à la fin:

nécessite 'newrelic_rpm' :: NewRelic :: Agent.manual_start… codez… :: NewRelic :: Agent.shutdown

De cette façon, vous n'aurez plus jamais à vous demander pourquoi vos données n'apparaissent pas dans l'interface utilisateur..

Surveillance des événements totalement personnalisés

Un des aspects intéressants de New Relic est qu’elle vous permet de tirer parti de son interface utilisateur et de ses fonctions d’agrégation de données pour des mesures qui n’ont rien à voir avec les performances (en théorie). Par exemple, vous souhaiterez peut-être avoir une certaine visibilité sur la fréquence à laquelle les utilisateurs s'inscrivent à votre application, la fréquence des ventes ou le montant total des achats effectués par les utilisateurs. Ce sont plus des indicateurs commerciaux que des indicateurs de performance, mais si vous avez trop de mal à les suivre séparément, vous pouvez utiliser New Relic pour le faire..

New Relic vous permet d’enregistrer des métriques personnalisées directement via deux appels d’API:

  • record_metric
  • increment_metric

Vous pouvez utiliser record_metric pour suivre toute métrique qui a un montant et increment_metric est assez explicite. Ainsi, nous pouvons, par exemple, faire ceci:

… Def achat (montant)… :: NewRelic :: Agent.record_metric ('Custom / purchase_amount', montant) :: NewRelic :: Agent.increment_metric ('Custom / purchase_count')… end… 

La seule façon pour vous de voir ces métriques dans l'interface utilisateur serait de créer des tableaux de bord personnalisés. Je dois mentionner que ce serait une utilisation quelque peu "créative" de l'API New Relic, car elle est conçue pour les données de performance, mais c'est certainement une chose pratique de savoir quand vous devez créer un tableau de bord rapide sans le vouloir. vouloir mettre en place un tas d'infrastructure supplémentaire.


Les dangers d'une surveillance excessive

Bien sûr, tout ce pouvoir a un coût. Si vous collectez trop de métriques personnalisées, cela peut ralentir votre application. Cela peut également ralentir l’interface utilisateur de New Relic et rendre difficile l’interprétation des données, car New Relic transformera des métriques similaires en données de synthèse. New Relic recommande de conserver le nombre de métriques personnalisées que vous collectez en dessous de 2000. J'ai constaté que les métriques personnalisées sont mieux utilisées périodiquement. Instrumentez le code dont vous avez besoin, utilisez l'instrumentation pour résoudre le problème que vous rencontrez, puis supprimez l'instrumentation. De cette façon, vous résolvez vos problèmes de performances et le nombre de métriques personnalisées que vous utilisez ne risque pas de devenir trop élevé..


Conclusion

Nous avons creusé dans les internes de la newrelic_rpm gem et ont appris comment expliquer à New Relic le code que vous considérez comme une transaction Web. Nous avons examiné comment modifier les transactions à la volée, comment surveiller les tâches en arrière-plan et dans les différentes situations où il est judicieux d'utiliser des métriques personnalisées. New Relic a beaucoup à faire avec la fonctionnalité prête à l'emploi et vous êtes maintenant beaucoup plus capable de l'exploiter pleinement. Toutefois, il reste toujours beaucoup à apprendre, par exemple sur la création de tableaux de bord personnalisés à partir des métriques que vous capturez ou sur la surveillance d'une infrastructure à l'aide de plug-ins. Nous aborderons ces sujets et d'autres dans des articles ultérieurs, alors revenez souvent. Et comme toujours si vous avez une question, si vous voulez partager votre propre histoire de Nouvelle Relique ou si vous voulez juste dire bonjour, n'oubliez pas de laisser un commentaire..