Configurare la raccolta delle tracce utilizzando OpenTelemetry

Questo documento mostra come configurare il monitoraggio lato client ed end-to-end utilizzando OpenTelemetry. Prima di poter attivare il monitoraggio end-to-end, devi configurare il monitoraggio lato client. Per saperne di più, consulta Panoramica della raccolta di tracce.

Prima di iniziare

  • Per assicurarti che il account di servizio utilizzato dalla tua applicazione disponga delle autorizzazioni necessarie per configurare la raccolta di tracce, chiedi all'amministratore di concedere i seguenti ruoli IAM al account di servizio utilizzato dalla tua applicazione nel tuo progetto:

  • Verifica che le API Cloud Trace e Telemetry siano abilitate nel tuo progetto. Per saperne di più sull'abilitazione delle API, consulta Abilitare le API.

Configurare il monitoraggio lato client

Per esportare le tracce utilizzando OpenTelemetry Protocol (OTLP), configura la tua applicazione. Puoi inviare i dati a un OpenTelemetry Collector o direttamente a Cloud Trace tramite l'API Telemetry API. Entrambi i metodi utilizzano le stesse dipendenze e la stessa configurazione. Differiscono solo nell'endpoint OTLP utilizzato dall'esportatore.

Esportare le tracce utilizzando OpenTelemetry Protocol

Per esportare le tracce utilizzando OpenTelemetry Protocol, configura l'SDK OpenTelemetry e l'esportatore OTLP:

  1. Aggiungi le dipendenze necessarie alla tua applicazione utilizzando il seguente codice:

    Java

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-spanner</artifactId>
    </dependency>
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-sdk</artifactId>
    </dependency>
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-sdk-trace</artifactId>
    </dependency>
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-otlp</artifactId>
    </dependency>

    Vai

    go.opentelemetry.io/otel v1.28.0
    go.opentelemetry.io/otel/sdk v1.28.0
    go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0

    Node.js

    "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.0",
    "@opentelemetry/sdk-trace-base": "^1.26.0",
    "@opentelemetry/sdk-trace-node": "^1.26.0",

    Python

    pip install opentelemetry-api opentelemetry-sdk
    pip install opentelemetry-exporter-otlp

  2. Configura l'oggetto OpenTelemetry e abilita il monitoraggio.

    Java

    Resource resource = Resource
        .getDefault().merge(Resource.builder().put("service.name", "My App").build());
    
    OtlpGrpcSpanExporter otlpGrpcSpanExporter =
        OtlpGrpcSpanExporter
            .builder()
            .setEndpoint(otlpEndpoint) // Replace with your OTLP endpoint
            .build();
    
    // Using a batch span processor
    // You can use `.setScheduleDelay()`, `.setExporterTimeout()`,
    // `.setMaxQueueSize`(), and `.setMaxExportBatchSize()` to further customize.
    BatchSpanProcessor otlpGrpcSpanProcessor =
        BatchSpanProcessor.builder(otlpGrpcSpanExporter).build();
    
    // Create a new tracer provider
    sdkTracerProvider = SdkTracerProvider.builder()
        // Use Otlp exporter or any other exporter of your choice.
        .addSpanProcessor(otlpGrpcSpanProcessor)
        .setResource(resource)
        .setSampler(Sampler.traceIdRatioBased(0.1))
        .build();
    
    // Export to a collector that is expecting OTLP using gRPC.
    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
        .setTracerProvider(sdkTracerProvider).build();
    
    // Enable OpenTelemetry traces before Injecting OpenTelemetry
    SpannerOptions.enableOpenTelemetryTraces();
    
    // Inject OpenTelemetry object via Spanner options or register as GlobalOpenTelemetry.
    SpannerOptions options = SpannerOptions.newBuilder()
        .setOpenTelemetry(openTelemetry)
        .build();
    Spanner spanner = options.getService();

    Go

    
    // Ensure that your Go runtime version is supported by the OpenTelemetry-Go
    // compatibility policy before enabling OpenTelemetry instrumentation.
    
    // Enable OpenTelemetry traces by setting environment variable GOOGLE_API_GO_EXPERIMENTAL_TELEMETRY_PLATFORM_TRACING
    // to the case-insensitive value "opentelemetry" before loading the client library.
    
    ctx := context.Background()
    
    // Create a new resource to uniquely identify the application
    res, err := resource.Merge(resource.Default(),
    	resource.NewWithAttributes(semconv.SchemaURL,
    		semconv.ServiceName("My App"),
    		semconv.ServiceVersion("0.1.0"),
    	))
    if err != nil {
    	log.Fatal(err)
    }
    
    // Create a new OTLP exporter.
    defaultOtlpEndpoint := "http://localhost:4317" // Replace with the endpoint on which OTLP collector is running
    traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint(defaultOtlpEndpoint))
    if err != nil {
    	log.Fatal(err)
    }
    
    // Create a new tracer provider
    tracerProvider := sdktrace.NewTracerProvider(
    	sdktrace.WithResource(res),
    	sdktrace.WithBatcher(traceExporter),
    	sdktrace.WithSampler(sdktrace.TraceIDRatioBased(0.1)),
    )
    
    // Register tracer provider as global
    otel.SetTracerProvider(tracerProvider)

    Node.js

    const {NodeTracerProvider} = require('@opentelemetry/sdk-trace-node');
    const {
      OTLPTraceExporter,
    } = require('@opentelemetry/exporter-trace-otlp-grpc');
    const {
      BatchSpanProcessor,
      TraceIdRatioBasedSampler,
    } = require('@opentelemetry/sdk-trace-base');
    const {Resource} = require('@opentelemetry/resources');
    const {Spanner} = require('@google-cloud/spanner');
    
    // Define a Resource with service metadata
    const resource = new Resource({
      'service.name': 'my-service',
      'service.version': '1.0.0',
    });
    
    // Create an OTLP gRPC trace exporter
    const traceExporter = new OTLPTraceExporter({
      url: 'http://localhost:4317', // Default OTLP gRPC endpoint
    });
    
    // Create a provider with a custom sampler
    const provider = new NodeTracerProvider({
      sampler: new TraceIdRatioBasedSampler(1.0), // Sample 100% of traces
      resource,
      spanProcessors: [new BatchSpanProcessor(traceExporter)],
    });
    
    // Uncomment following line to register tracerProvider globally or pass it in Spanner object
    // provider.register();
    
    // Create the Cloud Spanner Client.
    const spanner = new Spanner({
      projectId: projectId,
      observabilityOptions: {
        tracerProvider: provider,
        enableExtendedTracing: true,
        enableEndToEndTracing: true,
      },
    });
    

    Python

    # Setup OpenTelemetry, trace and OTLP exporter.
    tracer_provider = TracerProvider(sampler=ALWAYS_ON)
    otlp_exporter = OTLPSpanExporter(endpoint="http://localhost:4317")
    tracer_provider.add_span_processor(BatchSpanProcessor(otlp_exporter))
    
    # Setup the Cloud Spanner Client.
    spanner_client = spanner.Client(
        project_id,
        observability_options=dict(tracer_provider=tracer_provider, enable_extended_tracing=True, enable_end_to_end_tracing=True),
    )

Configurare il monitoraggio end-to-end

Questa sezione fornisce istruzioni per configurare il monitoraggio end-to-end nelle librerie client di Spanner:

  1. Aggiungi le dipendenze necessarie alla tua applicazione utilizzando il seguente codice:

    Java

    Le dipendenze di monitoraggio lato client esistenti sono sufficienti per configurare il monitoraggio end-to-end. Non sono necessarie dipendenze aggiuntive.

    Vai

    Oltre alle dipendenze necessarie per il monitoraggio lato client, devi avere anche la seguente dipendenza:

    go.opentelemetry.io/otel/propagation v1.28.0

    Node.js

    Le dipendenze di monitoraggio lato client esistenti sono sufficienti per configurare il monitoraggio end-to-end. Non sono necessarie dipendenze aggiuntive.

    Python

    Le dipendenze di monitoraggio lato client esistenti sono sufficienti per configurare il monitoraggio end-to-end. Non sono necessarie dipendenze aggiuntive.

  2. Attiva il monitoraggio end-to-end.

    Java

    SpannerOptions options = SpannerOptions.newBuilder()
      .setOpenTelemetry(openTelemetry)
      .setEnableEndToEndTracing(/* enableEndtoEndTracing= */ true)
      .build();

    Vai

    Utilizza l'opzione EnableEndToEndTracing nella configurazione del client per attivare la funzionalità.

    client, _ := spanner.NewClientWithConfig(ctx, "projects/test-project/instances/test-instance/databases/test-db", spanner.ClientConfig{
    SessionPoolConfig: spanner.DefaultSessionPoolConfig,
    EnableEndToEndTracing:      true,
    }, clientOptions...)

    Node.js

    const spanner = new Spanner({
    projectId: projectId,
    observabilityOptions: {
    tracerProvider: openTelemetryTracerProvider,
    enableEndToEndTracing: true,
    }
    })

    Python

    observability_options={
    "tracer_provider": tracer_provider,
    "enable_end_to_end_tracing": True,
    }
    spanner = spanner.Client(project_id, observability_options=observability_options)

  3. Imposta la propagazione del contesto di traccia in OpenTelemetry.

    Java

    OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
      .setTracerProvider(sdkTracerProvider)
      .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
      .buildAndRegisterGlobal();

    Vai

    // Register the TraceContext propagator globally.
    otel.SetTextMapPropagator(propagation.TraceContext{})

    Node.js

    const {propagation} = require('@opentelemetry/api');
    const {W3CTraceContextPropagator} = require('@opentelemetry/core');
    propagation.setGlobalPropagator(new W3CTraceContextPropagator());

    Python

    from opentelemetry.propagate import set_global_textmap
    from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
    set_global_textmap(TraceContextTextMapPropagator())

Attributi di monitoraggio end-to-end

Le tracce end-to-end possono includere le seguenti informazioni:

Nome dell'attributo Descrizione
service.name Il valore dell'attributo è sempre spanner_api_frontend.
cloud.region La regione cloud del frontend dell'API Spanner che gestisce la richiesta dell'applicazione. Google Cloud
gcp.spanner.server.query.fingerprint Il valore dell'attributo è l'impronta digitale della query. Per eseguire il debug di questa query ulteriormente, consulta la colonna TEXT_FINGERPRINT nelle tabelle delle statistiche delle query.
gcp.spanner.server.paxos.participantcount Il numero di partecipanti coinvolti nella transazione. Per saperne di più, consulta Durata di letture e scritture di Spanner.
gcp.spanner.isolation_level Il valore dell'attributo è il livello di isolamento della transazione. I valori possibili sono SERIALIZABLE e REPEATABLE_READ. Per saperne di più, consulta Panoramica dei livelli di isolamento.

Traccia di esempio

Una traccia end-to-end consente di visualizzare i seguenti dettagli:

  • La latenza tra l'applicazione e Spanner. Puoi calcolare la latenza di rete per verificare se ci sono problemi di rete.
  • La regione cloud del frontend dell'API Spanner da cui vengono gestite le richieste dell'applicazione. Puoi utilizzare questa opzione per verificare le chiamate tra regioni tra l'applicazione e Spanner.

Nell'esempio seguente, la richiesta dell'applicazione viene gestita dal frontend dell'API Spanner nella regione us-west1 e la latenza di rete è di 8,542 ms (55,47 ms - 46,928 ms).

Visualizza una traccia end-to-end.

Passaggi successivi