Trace-Erfassung mit OpenTelemetry einrichten

In diesem Dokument wird beschrieben, wie Sie clientseitiges und End-to-End-Tracing mit OpenTelemetry einrichten. Bevor Sie die End-to-End-Tracerstellung aktivieren können, müssen Sie die clientseitige Tracerstellung einrichten. Weitere Informationen finden Sie unter Übersicht über die Erfassung von Traces.

Hinweis

  • Damit das Dienstkonto, das von Ihrer Anwendung verwendet wird, die erforderlichen Berechtigungen zum Einrichten der Trace-Erfassung hat, bitten Sie Ihren Administrator, dem Dienstkonto, das von Ihrer Anwendung verwendet wird, die folgenden IAM-Rollen für Ihr Projekt zu gewähren:

  • Prüfen Sie, ob Cloud Trace und die Telemetry API für Ihr Projekt aktiviert sind. Weitere Informationen zum Aktivieren von APIs finden Sie unter APIs aktivieren.

Clientseitiges Tracing konfigurieren

Wenn Sie Traces mit dem OpenTelemetry Protocol (OTLP) exportieren möchten, müssen Sie Ihre Anwendung konfigurieren. Sie können Daten entweder an einen OpenTelemetry Collector oder direkt an Cloud Trace über die Telemetry API senden. Beide Methoden verwenden dieselben Abhängigkeiten und dieselbe Konfiguration. Sie unterscheiden sich nur im OTLP-Endpunkt, den der Exporter verwendet.

Traces mit dem OpenTelemetry-Protokoll exportieren

Wenn Sie Traces mit dem OpenTelemetry-Protokoll exportieren möchten, konfigurieren Sie das OpenTelemetry SDK und den OTLP-Exporter:

  1. Fügen Sie Ihrer Anwendung mit dem folgenden Code die erforderlichen Abhängigkeiten hinzu:

    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>

    Go

    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. Konfigurieren Sie das OpenTelemetry-Objekt und aktivieren Sie das Tracing.

    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),
    )

End-to-End-Tracing konfigurieren

In diesem Abschnitt finden Sie eine Anleitung zum Konfigurieren der End-to-End-Ablaufverfolgung in Spanner-Clientbibliotheken:

  1. Fügen Sie Ihrer Anwendung mit dem folgenden Code die erforderlichen Abhängigkeiten hinzu:

    Java

    Die vorhandenen clientseitigen Tracing-Abhängigkeiten reichen für die Konfiguration von End-to-End-Tracing aus. Sie benötigen keine zusätzlichen Abhängigkeiten.

    Go

    Zusätzlich zu den Abhängigkeiten, die Sie für das clientseitige Tracing benötigen, ist auch die folgende Abhängigkeit erforderlich:

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

    Node.js

    Die vorhandenen clientseitigen Tracing-Abhängigkeiten reichen für die Konfiguration von End-to-End-Tracing aus. Sie benötigen keine zusätzlichen Abhängigkeiten.

    Python

    Die vorhandenen clientseitigen Tracing-Abhängigkeiten reichen für die Konfiguration von End-to-End-Tracing aus. Sie benötigen keine zusätzlichen Abhängigkeiten.

  2. Aktivieren Sie das End-to-End-Tracing.

    Java

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

    Go

    Verwenden Sie die Option EnableEndToEndTracing in der Clientkonfiguration, um die Funktion zu aktivieren.

    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. Legen Sie die Trace-Kontextweitergabe in OpenTelemetry fest.

    Java

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

    Go

    // 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())

Attribute für End-to-End-Tracing

End-to-End-Traces können die folgenden Informationen enthalten:

Attributname Beschreibung
service.name Der Attributwert ist immer spanner_api_frontend.
cloud.region Die Google Cloud -Cloud-Region des Spanner API-Front-Ends, das die Anfrage Ihrer Anwendung verarbeitet.
gcp.spanner.server.query.fingerprint Der Attributwert ist der Fingerabdruck der Anfrage. Weitere Informationen zum Debuggen dieser Abfrage finden Sie in der Spalte TEXT_FINGERPRINT in den Abfragestatistiktabellen.
gcp.spanner.server.paxos.participantcount Die Anzahl der an der Transaktion beteiligten Teilnehmer. Weitere Informationen finden Sie unter Lebensdauer von Lese- und Schreibvorgängen in Cloud Spanner.
gcp.spanner.isolation_level Der Attributwert ist die Isolationsebene der Transaktion. Mögliche Werte sind SERIALIZABLE und REPEATABLE_READ. Weitere Informationen finden Sie unter Isolationsebenen – Übersicht.

Beispiel-Trace

Mit einem End-to-End-Trace können Sie die folgenden Details aufrufen:

  • Die Latenz zwischen Ihrer Anwendung und Spanner. Sie können die Netzwerklatenz berechnen, um festzustellen, ob Netzwerkprobleme vorliegen.
  • Die Cloud-Region des Spanner API-Front-Ends, aus der die Anfragen Ihrer Anwendung bedient werden. Damit können Sie regionenübergreifende Aufrufe zwischen Ihrer Anwendung und Spanner prüfen.

Im folgenden Beispiel wird die Anforderung Ihrer Anwendung vom Spanner API-Frontend in der Region us-west1 verarbeitet. Die Netzwerklatenz beträgt 8,542 ms (55,47 ms – 46,928 ms).

End-to-End-Trace ansehen

Nächste Schritte