En tant que professionnels de l’observabilité, nous avons naturellement des questions auxquelles seules les données télémétriques peuvent réellement répondre. Lorsque l'on examine un système, il est utile d'avoir une vue d'ensemble (comment fonctionne le service de paiement, par exemple) et de pouvoir également répondre à des questions plus précises (quels clients ont des réponses de paiement lentes, par exemple). J’aime appeler ce processus « zoom avant » car nous examinons les données de haut niveau, puis avançons dans les détails. 

En utilisant le langage de requête New Relic (NRQL) sur les données MELT (métriques, événements, logs et traces collectés à partir des agents New Relic, OpenTelemetry, Prometheus et bien d'autres), nous pouvons rapidement obtenir des informations détaillées sur les systèmes en cours d'exécution. En utilisant la puissance d’un langage de requête unique, nous pouvons adopter une vue d’ensemble, puis affiner davantage la requête pour examiner un angle particulier des données.

Examinons un exemple de système pour montrer comment nous pouvons recueillir des insights à l’aide de cette technique.

Vues de haut niveau

Aujourd’hui, je vais utiliser la télémétrie de traçage générée à partir d’une application OpenTelemetry comme base de mon analyse. L'application est une application de commerce électronique dotée d'un service frontend et de certains microservices backend, comme indiqué dans l'image ci-dessous. 

Les pages de monitoring des performances des applications (APM) donnent un aperçu de haut niveau axé sur le service, mais nous pouvons obtenir des informations plus spécifiques en écrivant notre propre requête NRQL sur les mêmes données qui alimentent les graphiques dans l'APM.

Des connaissances approfondies avec le générateur de requêtes et NRQL

Pour commencer à explorer le service en cours d’exécution, il nous faut un aperçu des traces. Je pourrais commencer par une requête de base comme celle-ci pour avoir une idée des données de résumé de trace existantes pour le service frontend à l'aide du générateur de requêtes:

FROM DistributedTraceSummary SELECT * 
WHERE root.entity.name = 'frontend-otel'

Les requêtes SELECT *, comme dans l'image suivante, donnent un bon aperçu des attributs susceptibles d'exister en sélectionnant les 100 lignes de données les plus récentes. Je vois que duration.ms est un attribut qui pourrait me dire combien de temps ces transactions frontend ont pris en millisecondes. 

Lors du traçage des données de latence, il est préférable d'examiner la distribution des valeurs plutôt que la moyenne, par exemple. Je vais choisir les centiles 50, 90, 95 et 99 à examiner en plus du nombre de traces au cours du dernier jour de données :

FROM DistributedTraceSummary SELECT percentile(duration.ms, 50, 90, 95, 99), count(*) 
WHERE root.entity.name = 'frontend-otel'
SINCE 1 day ago

Le graphique résultant montre les percentiles pour duration.ms et le nombre de traces au cours du dernier jour. 

Il s’agit d’un résumé de haut niveau acceptable. Il y a beaucoup de transactions en cours. Cela pourrait être une bonne cible pour un dashboard d'aperçu, mais je voudrais peut-être aller un peu plus loin.

Zoom sur les données

Dans notre exemple d'application, nous avons un résumé du service frontend mais nous ne savons pas comment fonctionnent les dépendances du service. 

Les premières choses à rechercher sont les autres services qui contribuent à la latence du service frontal. Pour atteindre ce niveau de détail, nous utiliserons l'événement de traçage Span, qui est l'un des « atomes » d'une trace distribuée.

Pour accéder à l'ensemble des services impliqués dans la gestion du frontend, nous pouvons obtenir un échantillon de traces, puis rechercher les noms des services dans les données Span. Utilisez le NRQL suivant pour le faire :

FROM Span SELECT uniques(service.name) 
WHERE trace.id in (FROM DistributedTraceSummary SELECT trace.id  WHERE root.entity.name = 'frontend-otel' LIMIT MAX) 

L'image suivante montre une répartition des services impliqués dans la gestion du frontend.

Vous remarquerez que cela inclut tous les services de la chaîne d’appels, et non le groupe de services immédiat. Ces informations sont utiles pour tout type d’enquête sur la latence. 

Nous pouvons rassembler des statistiques de haut niveau sur ce groupe de spans pour voir lesquels sont peut-être les plus lents en termes de latence et peuvent avoir un impact sur le frontend. Je peux utiliser la clause FACET pour regrouper les spans en fonction de leur nom de service :

FROM Span SELECT percentile(duration.ms, 99), count(*)
WHERE trace.id in (FROM DistributedTraceSummary SELECT trace.id  WHERE root.entity.name = 'frontend-otel' LIMIT MAX) 
FACET service.name

L'image suivante montre la distribution de la durée de chaque service.

Le résultat de cette requête nous indique que le service de paiement est un service clé à surveiller. D'après nos connaissances du système, c'est également un élément essentiel pour l'activité, puisque c'est au moment du paiement que le site de commerce électronique gagne de l'argent. 

Reprenons notre zoom et examinons simplement les intervalles/spans du service de paiement pour voir si nous trouvons d'autres informations sur ce qui pourrait révéler la latence la plus élevée :

FROM Span SELECT *
WHERE service.name = 'checkoutservice-otel'

La requête ci-dessus isole les spans du service de paiement, comme indiqué dans l'image suivante.

J'ai remarqué que l'attribut name a le point de terminaison au sein du service qui est appelé. Regardons ceux qui utilisent FACET.

FROM Span SELECT percentile(duration.ms, 95, 99)
WHERE service.name = 'checkoutservice-otel'
FACET name

Cette requête affiche les durées de transaction en fonction du point de terminaison au sein du service de paiement.

Avant d’aller plus loin, ces noms peuvent être un peu affinés pour n’inclure que la partie après le préfixe « oteldemo. » avec TIMESERIES MAX afin que les percentiles de latence soient indiqués dans le temps :

WITH aparse(name, 'oteldemo.*') as sanitizedName
FROM Span SELECT percentile(duration.ms, 95, 99)
WHERE service.name = 'checkoutservice-otel'
FACET sanitizedName TIMESERIES MAX

Avec des noms simplifiés et des percentiles affichés au fil du temps, la requête ci-dessus permet de repérer facilement les points de terminaison avec les tendances de durée à noter.

D'après ce graphique, il apparaît clairement que « PlaceOrder » se démarque du lot. Limitons nos requêtes à ce seul point de terminaison et examinons une plage de temps plus longue avec p95 uniquement :

WITH aparse(name, 'oteldemo.*') as sanitizedName
FROM Span SELECT percentile(duration.ms, 95)
WHERE service.name = 'checkoutservice-otel' and sanitizedName = 'CheckoutService/PlaceOrder'
TIMESERIES MAX since 1 week ago

La requête renvoie la tendance du point de terminaison « PlaceOrder » pendant une semaine, comme indiqué dans l'image suivante.

Cela nous donne un signal intéressant. Il semblerait qu'il y ait eu un pic de latence le 18 octobre à 17h30. Je peux utiliser le générateur de requêtes pour zoomer sur cette période :

Si nous voulons vraiment savoir pourquoi cela se produit, les spans lents spécifiques nous donnent les détails. Regardons simplement les intervalles qui ont une durée supérieure à 1 seconde (1 000 millisecondes) :

WITH aparse(name, 'oteldemo.*') as sanitizedName
FROM Span SELECT duration.ms, *
WHERE service.name = 'checkoutservice-otel' AND sanitizedName = 'CheckoutService/PlaceOrder' AND duration.ms > 1000
since '2024-10-18 01:25:00+0530' UNTIL '2024-10-18 09:52:00+0530'

Cette requête isole les intervalles dont la durée dépasse 1 seconde, ce qui vous permet d'inspecter plus en détail les éventuels goulots d'étranglement.

De là, il peut y avoir un signal dans le montant de la commande ou d'autres informations qui peuvent indiquer une autre possibilité pour laquelle cet appel a pu être lent et ce qu'il faut faire à ce sujet dans le code de service. 

Conclusion

Le fait de pouvoir naviguer dans les données, de faire des zooms avant et arrière afin de mieux comprendre ce qui se passe est une compétence essentielle des professionnels de l'observabilité, qui les aide à comprendre comment un système se comporte et à identifier où des problèmes peuvent exister. La possibilité de commencer avec un petit snippet de NRQL pour obtenir un aperçu de haut niveau des données, puis de zoomer sur les détails en utilisant les attributs importants de vos données, est l'un des aspects puissants et très pratiques, de l'exploration des données avec New Relic.