Article
· Août 5 9m de lecture

Configuration d'OpenTelemetry dans IRIS

Bonjour, chers membres de notre communauté de développeurs!

Dans l'article d'aujourd'hui, nous allons examiner l'une des dernières fonctionnalités de télésurveillance de nos instances IRIS qui a été ajoutée au produit. Il s'agit de la compatibilité avec OpenTelemetry.

Que qu'est-ce que OpenTelemetry?

OpenTelemetry est un framework open source qui fournit les outils nécessaires, tels que des SDK et des normes, pour mettre en œuvre l'observabilité dans les systèmes et les applications.

Cette observabilité s'étend à trois types de données:

  1. Traces : contrôle du flux d'informations circulant dans les solutions grâce à l'inclusion de traces permettant d'identifier où elles passent et sous quelles conditions.
  2. Métriques : état du système, performances, latences dans les réponses, utilisation des ressources, etc.
  3. Journaux : inclus dans les systèmes pour une meilleure compréhension des événements qui se produisent.

OpenTelemetry utilise la norme ouverte OTLP qui définit comment toute la télémétrie précédemment définie doit être sérialisée et transportée. L'envoi de cette télémétrie peut être effectué via HTTP ou gRPC.

Open Telemetry avec IRIS

InterSystems IRIS exploite les fonctionnalités disponibles via OpenTelemetry SDK pour permettre l'exportation de toutes les données de télémétrie générées par l'instance configurée. D'où proviennent ces données de télémétrie? 

  1. Métriques : elles proviennent des informations dont nous disposons via l'API REST /api/monitor ( vous pouvez consulter la documentation officielle de cette API ici ).
  2. Journaux : messages enregistrés dans le fichier messages.log et informations stockées dans la base de données d'audit (si elle est activée).
  3. Traces : traces définies par l'utilisateur dans les applications développées dans l'instance.

Voyons maintenant comment configurer OpenTelemetry dans une instance IRIS

Configuration d'IRIS avec OpenTelemetry

Pour notre exemple de configuration, j'ai utilisé un projet que j'ai téléchargé sur GitHub et qui fonctionne sous Docker, mais il ne serait pas très compliqué de le configurer sur une instance installée sur site. Ce projet est disponible sur OpenExchange, associé à cet article.

Avant de présenter les différentes configurations, nous allons expliquer quels éléments feront partie de notre "écosystème de surveillance":

InterSystems IRIS

L'instance IRIS se chargera de générer les données de télémétrie que nous devons surveiller.

OpenTelemetry Collector

Il s'agit d'un outil fourni par OpenTelemetry chargé de collecter des données télémétriques provenant de différentes sources. Dans notre exemple, il s'agira uniquement d'IRIS, mais nous pourrions en ajouter autant que nécessaire.

Prometheus

Outil open source utilisé pour la surveillance des systèmes et la génération d'alertes. Cet outil sera chargé de recevoir les métriques accumulées par OpenTelemetry Collector.

Jaeger

Plateforme open source pour la gestion et la surveillance des traces des systèmes basés sur des microservices.

Configuration en Docker

Comme je l'ai mentionné précédemment, j'ai utilisé un déploiement en Docker afin de simplifier au maximum l'exemple. Analysons le fichier docker-compose.yml par parties pour mieux le comprendre.

Image d'IRIS Docker

  iris:
    init: true
    container_name: iris
    build:
      context: .
      dockerfile: iris/Dockerfile
    ports:
      - 52774:52773
      - 51774:1972
    volumes:
    - ./iris/shared:/iris-shared
    environment:
    - ISC_DATA_DIRECTORY=/iris-shared/durable
    - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
    command: --check-caps false --ISCAgent false

Comme vous pouvez le voir, je définis l'image à utiliser dans un fichier Dockerfile qui ne présente pas grand intérêt et je ne vais donc pas m'attarder dessus. Le point intéressant de cette configuration est la définition d'une variable d'environnement appelée  OTEL_EXPORTER_OTLP_ENDPOINT  , qui sera l'URL où notre OpenTelemetry Collector attendra qu'IRIS lui envoie toutes les métriques, traces et journaux dont il dispose.

Une fois que nous aurons déployé notre instance IRIS, nous devrons la configurer pour qu'elle émette régulièrement les métriques et les journaux. Pour ce faire, nous accéderons à la configuration du moniteur depuis le portail de gestion:

Comme vous pouvez le voir, nous pouvons activer l'envoi des métriques et des journaux. Dans le cas des traces, celles-ci ne sont pas envoyées à intervalles réguliers, mais dès que la méthode "End" de l'instance de la classe %Trace.Provider est invoquée. Je n'entrerai pas plus dans les détails, mais vous pouvez consulter  the official documentation ici la documentation officielle.

Image d'OpenTelemetry Collector

otel-collector:
    build:
      context: .
      dockerfile: open-telemetry/Dockerfile
    container_name: otel-collector
    command: ["--config=/otel-local-config.yml"]
    volumes:
      - ./open-telemetry/otel-collector-config.yml:/otel-local-config.yml
    ports:
      - 4317:4317      # OTLP gRPC receiver
      - 4318:4318    # OTLP HTTP receiver
      - 9464:9464      # Metrics
    depends_on:
      - iris

Voici l'image d'OpenTelemetry Collector. J'ai à nouveau défini un fichier Dockerfile pour indiquer où obtenir l'image (ce n'est pas obligatoire). Comme vous pouvez le voir, nous rendons trois ports accessibles:

  • 4317: port pour la réception des métriques, des traces et des journaux via gRPC.
  • 4318: port pour la réception des métriques, des traces et des journaux via HTTP.
  • 9464: port ouvert pour que des outils tiers puissent consulter les informations reçues par OpenTelemetry Collector.

Nous avons également déclaré un fichier de configuration,  otel-local-config.yml  (le nom est modifiable). Jetons un œil à son contenu:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: "0.0.0.0:4317"
      http:
        endpoint: "0.0.0.0:4318"
exporters:
  otlp:
    endpoint: jaeger:4317
    tls:
      insecure: true
  prometheus:
    endpoint: "0.0.0.0:9464"
  debug: {}
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlp]
    metrics:
      receivers: [otlp]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      exporters: [debug]

Que voyons-nous ici? C'est très simple, nous avons les sections suivantes: 

  • Récepteurs de données  , que nous avons appelés otlp dans notre cas, dans lesquels nous configurons l'adresse IP et les ports sur lesquels notre récepteur va attendre les informations provenant de systèmes tiers.
  • Exporteurs de données : où nous allons envoyer ou qui va extraire les données reçues dans l'OpenTelemetry Collector. Pour notre exemple, nous avons utilisé un exporteur déjà inclus dans OpenTelemetry, à savoir, Prometheus, which  qui se chargera d'obtenir les métriques dans l'instance locale de l'OpenTelemetry Collector sur le port 9464. Dans le cas de Jaeger , nous utilisons directement la capacité d'OpenTelemetry à envoyer des données directement à une IP (jaeger est le nom de l'instance au sein du réseau monté par Docker) qui correspondra à notre instance jaeger.
  • Services , où nous indiquerons lesquels des composants que nous avons configurés comme récepteurs et exporteurs se chargeront de la réception et de l'émission des métriques, des traces et des journaux. Comme vous pouvez le voir dans notre cas OpenTelemetry Collector sera le récepteur que nous utiliserons pour tout, Prometheus sera le récepteur des métriques et Jaeger, via OpenTelemetry Collector, sera le récepteur des traces.

Image de Prometheus Docker

Let's take a look at its configuration in Docker:

prometheus:
    build:
      context: .
      dockerfile: prometheus/Dockerfile
    container_name: prometheus
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - 9090:9090

Comme vous pouvez le constater, c'est très simple: notre image est à nouveau définie dans un fichier Dockerfile qui fait uniquement référence au nom de l'image, à un port 9090 où sera déployée l'interface web à laquelle nous pourrons accéder, et enfin à un fichier de configuration appelé  prometheus.yml 

Voyons ce que nous dit ce fichier prometheus.yml:

global:
  scrape_interval: 15s
scrape_configs:
  - job_name: 'otel-collector'
    static_configs:
      - targets: ['otel-collector:9464']

Nous avons la configuration suivante:

  • Scrape interval : intervalle de temps entre deux requêtes à OpenTelemetry Collector.
  • Scrape configs : lieu où nous donnons un nom à la tâche qui effectuera la recherche, ainsi que l'adresse IP et le port auxquels elle se connectera pour cette recherche.

Image de Jaeger Docker

Pour l'image de Jaeger, j'ai directement repris un exemple disponible sur notre cher chatGPT:

jaeger:
    image: jaegertracing/all-in-one:latest
    container_name: jaeger
    environment:
      - COLLECTOR_OTLP_ENABLED=true
    ports:
      - 16686:16686    # Jaeger UI
      - 14250:14250    # OTLP gRPC receiver

Le point le plus important, outre le port 16689 que nous utiliserons pour accéder à l'interface web, est la variable d'environnement COLLECTOR_OTLP_ENABLED, qui activera les ports par défaut de Jaeger pour permettre les connexions HTTP depuis OpenTelemetry Collector.  Ici  vous pouvez voir la liste des ports utilisés, mais je vous informe que le port 4317 est utilisé pour la transmission gRCP et le port 4318 pour le HTTP. Comme vous l'avez vu dans la configuration d'OpenTelemetry Collector, nous allons utiliser la connexion via gRCP.

Maintenant que tout est prêt, voyons comment cela fonctionne en démarrant le projet.

Émission des métriques, réception dans Prometheus

Nos instances sont désormais configurées et démarrées. Accédons à l'interface web fournie par Prometheus.  Dans notre exemple, nous l'avons mappée à http://localhost:9090 . Par défaut, elle nous indique où nous pouvons lancer des requêtes sur les métriques disponibles.

Si nous avons correctement configuré la connexion entre IRIS - OpenTelemetry Collector - Prometheus, depuis l'écran de requêtes de Prometheus, nous aurons accès à toutes les métriques standard disponibles dans IRIS, comme vous pouvez le voir dans la capture d'écran suivante en recherchant "iris_"

Si nous sélectionnons l'une d'entre elles, nous pouvons voir un graphique au fil du temps

Envoi de traces à Jaeger

Pour vérifier le fonctionnement de l'envoi des traces, nous allons utiliser la ressource la plus simple mise à notre disposition par IRIS, à savoir la méthode TestTraces() de la classe SYS.Monitor.OTel que vous pouvez consulter ici . Si vous souhaitez obtenir plus de détails, n'hésitez pas à me le faire savoir dans les commentaires et je me ferai un plaisir de rédiger un article à ce sujet.

Nous se limitons à exécuter la commande depuis la console à partir de l'espace de noms SYS:

%SYS>do ##class(SYS.Monitor.OTel).TestTraces()

Cela nous renverra une trace qui devrait avoir été reçue par Jaeger. Vérifions cela depuis son interface graphique affichée sur http://localhost:1668

Dans les filtres du menu de gauche, nous pouvons voir que nous avons un service appelé  irisotel , Ce service est utilisé par IRIS pour tester l'envoi de traces de test, d'où le nom de la trace reçue test_trace .

Et voilà! Notre instance est désormais prête à envoyer toutes les données métriques et traces que nous souhaitons. Je reste à votre disposition si vous souhaitez approfondir le sujet.

Discussion (0)2
Connectez-vous ou inscrivez-vous pour continuer