Background Image
TECHNOLOGIE

Ajouter une application Spring Boot à la plateforme d'observabilité Grafana

Headshot - Scott Bock
Scott Bock
Vice-président du service de conseil

May 9, 2023 | 5 Lecture minute

Il existe de nombreux vecteurs d'augmentation de la complexité d'une API. Par exemple : Au fur et à mesure qu'elle ajoute des capacités, elle peut devenir un monolithe complexe ou se transformer en un ensemble de microservices. Au fur et à mesure que son utilisation augmente, elle peut dépasser les capacités du matériel ou devenir distribuée. Ce ne sont là que quelques-uns des problèmes et des solutions possibles. Chacun de ces choix ou de ces changements rend plus difficile le suivi de la santé, le débogage des erreurs et l'identification des goulets d'étranglement. C'est pourquoi l'observabilité est importante.

Malheureusement, il peut être coûteux d'externaliser cette responsabilité ; cependant, il existe des solutions open-source, et l'une des meilleures est la plateforme Grafana. Grafana est l'outil de visualisation d'une variété de sources de données, mais l'équipe Grafana a également ses propres sources de données pour les journaux (Loki), les métriques (Mimir) et les traces (Tempo). Dans cet article, nous allons voir comment connecter une application Spring Boot à cet écosystème.

Notre première étape est de mettre en place notre environnement d'observabilité. Nous allons utiliser docker compose pour créer cet environnement avec ce fichier docker-compose.yaml :

version: "3.9"

networks:
telemetry:

volumes:
influxdb-storage:
grafana-storage:

services:

grafana:
image: grafana/grafana:9.3.1
depends_on:
- influxdb
volumes:
- ./docker/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
- grafana-storage:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin1
- GF_SERVER_HTTP_PORT=3000
- INFLUXDB_HOST=influxdb
- INFLUXDB_PORT=8086
- INFLUXDB_NAME=db0
- INFLUXDB_USER=influxuser
- INFLUXDB_PASS=influxuser1
ports:
- "3000:3000"
networks:
- telemetry

influxdb:
image: influxdb:latest
ports:
- '8086:8086'
volumes:
- influxdb-storage:/var/lib/influxdb
environment:
- INFLUXDB_URL=http://influxdb:8086
- INFLUXDB_ADMIN_USER=influxuser
- INFLUXDB_ADMIN_PASSWORD=influxuser1

loki:
image: grafana/loki:2.7.1
ports:
- "3100:3100"
command: -config.file=/etc/loki/loki.yaml
volumes:
- ./docker/loki.yaml:/etc/loki/loki.yaml
networks:
- telemetry

tempo:
image: grafana/tempo:1.5.0
command: [ "-config.file=/etc/tempo.yaml" ]
volumes:
- ./docker/tempo.yaml:/etc/tempo.yaml
- ./data/tempo:/tmp/tempo
ports:
- "14268:14268" # jaeger ingest
- "3200:3200" # tempo
- "55680:55680" # otlp grpc
- "55681:55681" # otlp http
- "9411:9411" # zipkin
- "4318:4318" # new http
- "4317:4317" # new grpc

networks:
- telemetry

mimir:
image: grafana/mimir:2.5.0
command: "-config.file=/etc/mimir/mimir.yaml"
ports:
- "9009:9009"
volumes:
- "./docker/mimir.yaml:/etc/mimir/mimir.yaml"
- "/tmp/mimir/rules:/tmp/mimir/rules"
networks:
- telemetry

Ici, vous pouvez voir que nous mettons en place une instance Grafana soutenue par un Influxdb ainsi que des instances de Loki, Tempo, et Mimir. Nous exposons les ports appropriés pour configurer chaque instance avec les fichiers correspondants de notre dossier docker. Le plus intéressant est le fichier grafana-datasources.yaml qui configure grafana pour se connecter à Loki, Mimir et Tempo.

apiVersion: 1

datasources:

- name: Tempo
type: tempo
access: proxy
orgId: 1
url: http://tempo:3200
basicAuth: false
isDefault: true
version: 1
editable: false
apiVersion: 1
uid: tempo

- name: Loki
type: loki
access: proxy
orgId: 1
url: http://loki:3100
basicAuth: false
isDefault: false
version: 1
editable: false
apiVersion: 1
jsonData:
derivedFields:
- datasourceUid: tempo
matcherRegex: (?:traceID|trace_id)=(\w+)
name: TraceID
url: $${__value.raw}

- name: Mimir
type: prometheus
access: proxy
orgId: 1
url: http://mimir:9009/prometheus
isDefault: false
version: 1
editable: true

Une fois que nous avons lancé "docker compose up", nous pouvons accéder à localhost:9000 et nous connecter à Grafana avec nos identifiants admin/admin1 définis dans le fichier docker compose. Travaillons maintenant à obtenir des données de notre application Spring Boot. Nous allons commencer par ajouter des logs à loki.

Les logs

Par défaut, Spring Boot inclut slf4j, nous n'avons donc pas besoin d'ajouter quoi que ce soit à notre build.gradle. Cependant, dans cet exemple, nous utiliserons Grafana Agent pour récupérer nos logs et les exporter vers Loki. Nous devons donc mettre à jour notre fichier application.properties pour écrire nos logs dans un fichier et définir un niveau de logging root comme ceci :

logging.file.name=logs/app.log
logging.level.root=INFO

Ensuite, nous ajoutons l'agent Grafana à notre fichier docker-compose.yaml :

grafana-agent:
image: grafana/agent:v0.22.0
volumes:
- ./docker/grafana-agent.yaml:/etc/agent-config/grafana-agent.yaml
- ./logs/:/var/log/
entrypoint:
- /bin/agent
- -config.file=/etc/agent-config/grafana-agent.yaml
- -prometheus.wal-directory=/tmp/agent/wal
ports:
- "12345:12345"
networks:
- telemetry
extra_hosts:
- "host.docker.internal:host-gateway"

Et nous indiquons à Grafana Agent comment récupérer nos logs en définissant son fichier de configuration (grafana-agent.yaml).

server:
 log_level: debug
 http_listen_port: 12345
 
logs:
 configs:
 - name: default
 positions:
 filename: /tmp/localhost-positions.yaml
 clients:
 - url: http://loki:3100/loki/api/v1/push
 scrape_configs:
- job_name: system
 static_configs:
- labels:
 job: localhostlogs 
__path__: /var/log/*log
 env: "local"
 app: "observability-example"

Métriques

Pour envoyer nos métriques, nous devons inclure quelques dépendances dans notre gradle.build

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'

//enable /actuator/prometheus
runtimeOnly 'io.micrometer:micrometer-registry-prometheus'

//for timed aspect
implementation 'org.springframework:spring-aspects'
}

Maintenant, nous allons activer les endpoints de métriques dans notre application en ajoutant quelques propriétés à l'application.properties :

management.endpoint.health.show-details=always management.endpoints.web.exposure.include=health,info,prometheus

Enfin, nous indiquons à Grafana Agent où lire nos métriques et où les écrire en mettant à jour le fichier de configuration grafana-agent.yaml :

management.endpoint.health.show-details=always management.endpoints.web.exposure.include=health,info,prometheus

Notre Spring Boot app acutaor endpoint contient un tas d'excellentes métriques, si vous voulez voir un exemple de métriques personnalisées, vous pouvez regarder le FactorService dans mon application d'exemple.

Traces

Pour ajouter des données de trace à notre application, nous devons inclure quelques dépendances supplémentaires dans notre gradle.build

dependencies {
implementation("io.micrometer:micrometer-tracing")
implementation("io.micrometer:micrometer-tracing-bridge-otel")
implementation("io.opentelemetry:opentelemetry-exporter-zipkin")
}

Maintenant, activons l'ajout de nos informations de trace dans nos logs et activons le traçage et les endpoints dans notre application en ajoutant quelques propriétés à l'application.properties :

logging.pattern.level="trace_id=%mdc{traceId} span_id=%mdc{spanId} trace_flags=%mdc{traceFlags} %p"

management.tracing.enabled=true
management.tracing.sampling.probability=1.0
management.zipkin.tracing.endpoint=http://localhost:9411

C'est tout ! Démarrez l'application et relancez votre docker compose pour que nous récupérions tous les changements. Vous pouvez trouver l'ensemble du repo de l'application d'exemple ici https://github.com/scottbock/observability-example

Technologie
Ingénierie des plates-formes

Vous avez besoin d'aide pour créer votre prochaine application Go ?

Dernières réflexions

Explorez nos articles de blog et laissez-vous inspirer par les leaders d'opinion de nos entreprises.
Asset - Unlock the Value Thumbnail
Nuage

Transformer la planification financière : De SAP BPC à SAP Analytics Cloud (SAC)

Découvrez les avantages et les défis de la transition de SAP BPC à SAP Analytics Cloud (SAC) pour la planification financière.