Technique

Elastic APM gratuit et ouvert dans votre déploiement Elastic Observability

Dans un article récent, nous vous avons expliqué comment vous lancer avec le niveau gratuit et ouvert d'Elastic Observability. Aujourd'hui, nous allons voir comment étendre votre déploiement pour pouvoir collecter des indicateurs à partir du monitoring des performances applicatives (APM) et "suivre" les données dans votre cluster d'observabilité, le tout gratuitement.

Qu'est-ce que l'APM ?

Le monitoring des performances applicatives vous permet de déterminer où vos applications passent du temps, ce qu'elles font, quels services ou autres applications elles appellent, et quelles sont les erreurs ou exceptions qu'elles rencontrent.

distributed-trace.png

L'APM vous permet également de voir l'historique et les tendances des indicateurs clés de performance, tels que la latence et le débit, ainsi que des informations relatives aux transactions et aux dépendances :

ruby-overview.png

Configuration d'alertes en cas de non-respect des SLA, évaluation de l'impact de votre dernière version, prise de décision quant aux améliorations à apporter... Quel que soit le cas de figure, l'APM vous aide à analyser votre environnement pour que vous puissiez améliorer l'expérience des utilisateurs et réduire au maximum le temps moyen de résolution (MTTR).

Une architecture logique

Elastic APM s'appuie sur l'intégration APM qui se trouve dans Elastic Agent, un outil qui transfère les données de traces d'applications et d'indicateurs depuis des applications instrumentées avec des agents APM vers un cluster Elastic Observability. Elastic APM prend différents types d'agents en charge :

  • des agents Elastic APM natifs, disponibles pour plusieurs langages, dont Java, .NET, Go, Ruby, Python, Node.js,  PHP et JavaScript côté client ;
  • tout code instrumenté avec OpenTelemetry ;
  • tout code instrumenté avec OpenTracing ;
  • tout code instrumenté avec Jaeger.

Dans ce blog, nous allons voir comment instrumenter le code avec un agent Elastic APM natif pour Python. Sachez néanmoins que la procédure est la même pour les autres langages.

Attention : faites bien la distinction entre un agent Elastic APM et une instance Elastic Agent. Il s'agit de composants très différents, comme vous pouvez le voir dans le diagramme ci-dessus. Il est donc important de ne pas les confondre.

Installation d'Elastic Agent

La première étape consiste à installer Elastic Agent. Pour cela, il faut que Fleet soit installé au préalable, mais vous pouvez aussi installer l'instance Elastic Agent de façon autonome. Installez Elastic Agent conformément à ce guide. Vous obtiendrez ainsi un point de terminaison pour l'intégration APM dont vous pourrez vous servir. Remarque : dans Elastic Cloud, cette étape n'est pas nécessaire étant donné que nous hébergeons l'intégration APM pour vous. Vérifiez que l'instance Elastic Agent est opérationnelle en exécutant la commande suivante :

curl <ELASTIC_AGENT_HOSTNAME>:8200

Instrumentation d'un exemple de code dans un agent Elastic APM

Les instructions des différents agents de langage varient selon le langage de programmation, mais dans l'ensemble, elles ont un déroulement général similaire. Tout d'abord, vous ajoutez la dépendance de l'agent dans la spécification native du langage, puis vous configurez l'agent pour lui indiquer comment trouver l'intégration APM.

Vous pouvez tester autant de langages que vous le souhaitez. Pour ma part, je vais suivre les instructions pour Python avec cet exemple en Python que j'ai créé.

Obtention de l'exemple de code (ou utilisation de votre propre code)

Pour commencer, je clone le référentiel GitHub, puis je modifie le répertoire :

git clone https://github.com/davidgeorgehope/PythonElasticAPMExample
cd PythonElasticAPMExample

Ajout d'une dépendance

Pour ajouter une dépendance Elastic APM, c'est simple. Consultez le fichier app.py dans le référentiel github : vous remarquerez les lignes de code ci-dessous.

import elasticapm
from elasticapm import Client

app = Flask(__name__)
app.config["ELASTIC_APM"] = { "SERVICE_NAME": os.environ.get("APM_SERVICE_NAME", "flask-app"), "SECRET_TOKEN": os.environ.get("APM_SECRET_TOKEN", ""), "SERVER_URL": os.environ.get("APM_SERVER_URL", "http://localhost:8200"),}
elasticapm.instrumentation.control.instrument()
client = Client(app.config["ELASTIC_APM"])

La bibliothèque Python pour Flask est capable de détecter automatiquement les transactions, mais vous pouvez également démarrer les transactions dans le code comme ci-dessous (voir dans l'exemple) :

@app.route("/")
def hello():
client.begin_transaction('demo-transaction')
client.end_transaction('demo-transaction', 'success')

Configuration de l'agent

Les agents doivent envoyer des données de traces d'application à l'intégration APM, et pour cela, celle-ci doit être accessible. J'ai configuré Elastic Agent pour qu'il écoute l'IP de mon hôte local, afin que n'importe quel élément de mon sous-réseau puisse y envoyer des données. Comme vous pouvez le voir dans le code ci-dessous, nous utilisons docker-compose.yml pour appliquer la configuration via des variables d'environnement. Modifiez ces variables pour qu'elles soient adaptées à votre propre installation Elastic.

# docker-compose.yml
version: "3.9"
services:
flask_app:
build: .
ports:
- "5001:5001"
environment:
- PORT=5001
- APM_SERVICE_NAME=flask-app
- APM_SECRET_TOKEN=your_secret_token
- APM_SERVER_URL=http://host.docker.internal:8200

Quelques commentaires par rapport à l'exemple ci-dessus :

  • service_name : si vous laissez cet élément vide, le nom de l'application sera indiqué par défaut, mais vous pouvez le remplacer.
  • secret_token : les tokens secrets vous permettent d'autoriser des demandes pour le serveur APM, mais celui-ci doit être configuré avec un protocole SSL/TLS et un token secret doit également être défini. Nous n'utilisons pas le protocole HTTPS entre les agents et le serveur APM, aussi nous ne commenterons pas celui-ci.
  • server_url : c'est grâce à cet élément que l'agent peut accéder à l'intégration APM dans Elastic Agent. Remplacez cet élément par le nom ou l'IP de votre hôte qui s'exécute sur Elastic Agent.

Maintenant qu'Elastic APM est configuré, nous allons simplement suivre les étapes indiquées dans le fichier README pour nous lancer.

docker-compose up --build -d

La mise en place prendra quelques minutes.

Vous pouvez accéder à l'exemple d'application que j'exécute sur http://localhost:5001. L'exemple ne contient pas beaucoup d'éléments, mais il en contient suffisamment pour générer des données APM. Pour générer un semblant de charge, vous pouvez recharger ces données plusieurs fois ou exécuter un petit script rapide:

#!/bin/bash
# load_test.sh
url="http://localhost:5001"
for i in {1..1000}
do
curl -s -o /dev/null $url
sleep 1
done

Ce script rechargera les pages à chaque seconde.

De retour dans Kibana, accédez de nouveau à l'application APM (avec l'icône en forme de hamburger, puis sélectionnez APM). Vous devriez voir apparaître notre nouveau service flask-app (j'ai laissé le mien s'exécuter, ce qui explique pourquoi il affiche un historique un peu plus long) :

La page Service Overview (Aperçu du service) fournit un récapitulatif de l'intégrité d'un service en un coup d'œil dans un emplacement centralisé. Si vous êtes développeur ou ingénieur SRE, c'est cette page qui vous permettra de répondre à des questions telles que : 

  • Quel impact un nouveau déploiement a-t-il eu sur les performances ?
  • Quelles ont été les principales transactions touchées ?
  • Quelle est la corrélation entre les performances et l'infrastructure sous-jacente ?

Cette vue fournit une liste de toutes les applications qui ont envoyé des données de trace à Elastic APM sur la période indiquée (dans le cas présent, les 15 dernières minutes). Il y a également des sparklines présentant des mini-graphiques sur la latence, le débit et le taux d'erreurs. Lorsque nous cliquons sur flask-app, nous sommes redirigés vers la page Service Overview (Aperçu du service), qui affiche les différentes transactions qui ont lieu dans le service (rappelez-vous que mon script accède au point de terminaison /, comme nous l'avons vu dans la section Transactions). Nous obtenons des graphiques plus grands pour la latence, le débit, les erreurs et les taux d'erreurs.

Lorsque vous instrumentez des applications réelles soumises à des charges réelles, vous constaterez que la connectivité est plus importante (tout comme le nombre d'erreurs !).

En cliquant sur une transaction dans la vue Transactions, ici la transaction demo-transaction de notre exemple d'application, nous pouvons voir avec précision quelles opérations ont été appelées :

Vous trouverez aussi des informations détaillées sur les appels à des services externes, comme des requêtes de base de données :

Et ensuite ?

Maintenant que vous avez un cluster Elastic Observability qui est opérationnel et qui collecte des données de traces d'application exploitables, explorez les API publiques pour les langages que vos applications utilisent, afin de franchir un nouveau cap dans l'utilisation des données APM. Les API vous permettent d'ajouter des métadonnées personnalisées, de définir des transactions, de créer des intervalles personnalisés, et bien plus encore. Vous pouvez trouver les spécifications des API publiques des différents agents APM (tels que Java, Ruby, Python et bien d'autres) dans la documentation des agents APM. 

Si vous souhaitez en savoir plus sur Elastic APM, regardez notre webinar sur la transition d'Elastic APM vers une approche cloud-native pour découvrir l'aide supplémentaire qu'Elastic APM peut apporter à votre écosystème.

Si vous préférez que ce soit nous qui hébergions votre cluster d'observabilité, vous pouvez vous inscrire pour bénéficier d'un essai gratuit d'Elasticsearch Service on Elastic Cloud et modifier vos agents de sorte qu'ils pointent vers votre nouveau cluster.

Publication initiale : 5 mai 2021, mise à jour : 6 avril 2023.