Guida Pratica all'Integrazione di OpenTelemetry in Spring Boot per il Tracciamento Distribuito

Introduzione

L'integrazione di OpenTelemetry in Spring Boot è un passo cruciale per migliorare l'osservabilità delle tue applicazioni. Con il tracciamento distribuito e le metriche custom, puoi ottenere una visione completa delle prestazioni e del comportamento del tuo sistema. In questa guida, ti accompagneremo passo dopo passo nell'integrazione di OpenTelemetry in un progetto Spring Boot, dalla configurazione iniziale alla creazione di metriche personalizzate.

Prerequisiti

Prima di iniziare, assicurati di avere i seguenti prerequisiti:

  • Un progetto Spring Boot funzionante
  • Conoscenza base di Maven o Gradle
  • Un ambiente di sviluppo configurato

Configurazione Iniziale

Aggiunta delle Dipendenze

Il primo passo è aggiungere le dipendenze necessarie per OpenTelemetry al tuo progetto Spring Boot. Se stai usando Maven, aggiungi le seguenti dipendenze al tuo file pom.xml:

<dependencies>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-api</artifactId>
        <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk</artifactId>
        <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-exporter-jaeger</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

Se stai usando Gradle, aggiungi le seguenti dipendenze al tuo file build.gradle:

dependencies {
    implementation 'io.opentelemetry:opentelemetry-api:1.0.0'
    implementation 'io.opentelemetry:opentelemetry-sdk:1.0.0'
    implementation 'io.opentelemetry:opentelemetry-exporter-jaeger:1.0.0'
}

Configurazione del Tracciamento

Una volta aggiunte le dipendenze, è necessario configurare il tracciamento. Crea una classe di configurazione per OpenTelemetry:

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

@Configuration
public class OpenTelemetryConfig {

    @Bean
    public OpenTelemetry openTelemetry() {
        Resource resource = Resource.create(Attributes.of(
            "service.name", "your-service-name",
            "service.version", "1.0.0"
        ));

        SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
            .addSpanProcessor(BatchSpanProcessor.builder(JaegerGrpcSpanExporter.builder().build()).build())
            .setResource(resource)
            .build();

        return OpenTelemetrySdk.builder()
            .setTracerProvider(tracerProvider)
            .build();
    }
}

Integrazione con Spring Boot

Configurazione dell'Auto-configurazione

Spring Boot offre un supporto automatico per OpenTelemetry. Aggiungi la seguente dipendenza al tuo file pom.xml o build.gradle:

<dependency>
    <groupId>io.opentelemetry.instrumentation</groupId>
    <artifactId>opentelemetry-spring-boot-autoconfigure</artifactId>
    <version>1.0.0</version>
</dependency>

Configurazione delle Metriche Custom

Per configurare le metriche custom, crea una classe di configurazione per le metriche:

import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MetricsConfig {

    @Autowired
    private Meter meter;

    @Bean
    public ObservableLongMeasurement customMetric() {
        return meter.gaugeBuilder("custom.metric")
            .setDescription("Descrizione della metrica custom")
            .ofLongs()
            .buildWithCallback(measurement -> {
                measurement.record(100, Attributes.of(
                    "key", "value"
                ));
            });
    }
}

Tracciamento Distribuito

Configurazione del Tracciamento Distribuito

Per configurare il tracciamento distribuito, è necessario aggiungere un esporter per le tracce. In questo esempio, useremo Jaeger come esporter:

import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;

@Bean
public SdkTracerProvider sdkTracerProvider() {
    JaegerGrpcSpanExporter jaegerExporter = JaegerGrpcSpanExporter.builder()
        .setEndpoint("http://localhost:14250")
        .build();

    return SdkTracerProvider.builder()
        .addSpanProcessor(BatchSpanProcessor.builder(jaegerExporter).build())
        .build();
}

Visualizzazione delle Tracce

Una volta configurato il tracciamento distribuito, puoi visualizzare le tracce utilizzando Jaeger. Avvia Jaeger localmente e accedi all'interfaccia web all'indirizzo http://localhost:16686.

Metriche Custom

Creazione di Metriche Custom

Per creare metriche custom, puoi utilizzare la classe Meter di OpenTelemetry. Ecco un esempio di come creare una metrica custom:

import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongMeasurement;

@Bean
public ObservableLongMeasurement customMetric(Meter meter) {
    return meter.gaugeBuilder("custom.metric")
        .setDescription("Descrizione della metrica custom")
        .ofLongs()
        .buildWithCallback(measurement -> {
            measurement.record(100, Attributes.of(
                "key", "value"
            ));
        });
}

Utilizzo delle Metriche Custom

Una volta create le metriche custom, puoi utilizzarle nel tuo codice per tracciare eventi specifici. Ecco un esempio di come utilizzare una metrica custom:

import io.opentelemetry.api.metrics.Meter;

@Service
public class MyService {

    @Autowired
    private Meter meter;

    public void myMethod() {
        meter.counterBuilder("my.counter")
            .setDescription("Descrizione del contatore")
            .build()
            .add(1);
    }
}

Conclusione

In questa guida, abbiamo visto come integrare OpenTelemetry in un progetto Spring Boot per il tracciamento distribuito e le metriche custom. Con queste configurazioni, puoi ottenere una visione completa delle prestazioni e del comportamento del tuo sistema, migliorando l'osservabilità e facilitando il debug.

Per approfondire, la documentazione di Lescopr descrive la configurazione passo dopo passo.