OpenTelemetry를 사용하여 트레이스 수집 설정

이 문서에서는 OpenTelemetry를 사용하여 클라이언트 측 및 엔드 투 엔드 trace를 설정하는 방법을 설명합니다. 엔드 투 엔드 trace를 선택하려면 먼저 클라이언트 측 trace를 설정해야 합니다. 자세한 내용은 Trace 컬렉션 개요를 참조하세요.

시작하기 전에

  • 애플리케이션에서 사용하는 서비스 계정에 trace 수집을 설정하는 데 필요한 권한이 있는지 확인하려면 관리자에게 애플리케이션에서 사용하는 서비스 계정에 프로젝트에 대한 Cloud Trace 에이전트(roles/cloudtrace.agent) IAM 역할을 부여해 달라고 요청하세요.

클라이언트 측 trace 구성

클라이언트 측 trace를 구성하려면 trace를 내보내야 합니다. 수집기로 내보내거나 관측 가능성 백엔드로 trace를 직접 내보낼 수 있습니다. OpenTelemetry API를 사용하여 trace를 구성할 수 있습니다.

OpenTelemetry API를 사용하여 수집기로 trace 내보내기

OpenTelemetry API를 사용하여 수집기로 trace를 내보내려면 OpenTelemetry SDK 및 OLTP 내보내기 도구를 구성합니다.

  1. 다음 코드를 사용하여 애플리케이션에 필요한 종속 항목을 추가합니다.

    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

  2. OpenTelemetry 객체를 구성하고 trace를 사용 설정합니다.

    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)

OpenTelemetry API를 사용하여 관측 가능성 백엔드로 직접 내보내기

Cloud Trace 또는 다른 관측 가능성 서비스 제공업체 백엔드로 trace 스팬을 직접 내보내도록 Spanner 클라이언트 라이브러리를 구성하려면 다음 단계를 따르세요.

  1. 다음 코드를 사용하여 애플리케이션에 필요한 종속 항목을 추가합니다.

    Java

    <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-spanner</artifactId>
    </dependency>
    <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-api</artifactId>
    </dependency>
    <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk</artifactId>
    </dependency>
    <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk-common</artifactId>
    </dependency>
    <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk-trace</artifactId>
    </dependency>
    <dependency>
    <groupId>com.google.cloud.opentelemetry</groupId>
    <artifactId>exporter-trace</artifactId>
    <version>0.30.0</version>
    </dependency>

    Go

    go.opentelemetry.io/otel v1.28.0
    go.opentelemetry.io/otel/sdk v1.28.0
    github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace v1.24.1

  2. OpenTelemetry 객체를 구성하고 trace를 사용 설정합니다.

    Java

    Resource resource = Resource
        .getDefault().merge(Resource.builder().put("service.name", "My App").build());
    
    SpanExporter traceExporter = TraceExporter.createWithConfiguration(
        TraceConfiguration.builder().setProjectId(projectId).build()
    );
    
    // Using a batch span processor
    // You can use `.setScheduleDelay()`, `.setExporterTimeout()`,
    // `.setMaxQueueSize`(), and `.setMaxExportBatchSize()` to further customize.
    BatchSpanProcessor otlpGrpcSpanProcessor =
        BatchSpanProcessor.builder(traceExporter).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 it as global object.
    // To register as the global OpenTelemetry object,
    // use "OpenTelemetrySdk.builder()....buildAndRegisterGlobal()".
    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.
    
    // 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 cloud trace exporter
    exporter, err := traceExporter.New(traceExporter.WithProjectID(projectID))
    if err != nil {
    	log.Fatal(err)
    }
    
    // Create a new tracer provider
    tracerProvider := sdktrace.NewTracerProvider(
    	sdktrace.WithResource(res),
    	sdktrace.WithBatcher(exporter),
    	sdktrace.WithSampler(sdktrace.TraceIDRatioBased(0.1)),
    )
    
    // Register tracer provider as global
    otel.SetTracerProvider(tracerProvider)

엔드 투 엔드 trace 구성

이 섹션에서는 Spanner 클라이언트 라이브러리에서 엔드 투 엔드 trace(미리보기)를 구성하는 방법을 안내합니다.

  1. 다음 코드를 사용하여 애플리케이션에 필요한 종속 항목을 추가합니다.

    Java

    기존 클라이언트 측 trace 종속 항목은 엔드 투 엔드 trace를 구성하는 데 충분합니다. 추가 종속 항목은 필요하지 않습니다.

    Go

    클라이언트 측 trace에 필요한 종속 항목 외에도 다음 종속 항목도 필요합니다.

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

  2. 엔드 투 엔드 trace를 선택합니다.

    Java

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

    Go

    클라이언트 구성에서 EnableEndToEndTracing 옵션을 사용하여 선택합니다.

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

  3. OpenTelemetry에서 trace 컨텍스트 전파를 설정합니다.

    Java

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

    Go

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

엔드 투 엔드 trace 속성

엔드 투 엔드 trace에는 다음 정보가 포함될 수 있습니다.

속성 이름 설명
service.name 속성 값은 항상 spanner_api_frontend입니다.
cloud.region 애플리케이션 요청을 처리하는 Spanner API 프런트엔드의 Google Cloud 리전입니다.
gcp.spanner.query.fingerprint 속성 값은 쿼리 지문입니다. 이 쿼리를 추가로 디버그하려면 쿼리 통계 표에서 TEXT_FINGERPRINT 열을 참고하세요.
gcp.spanner.participants.count 거래에 참여한 당사자 수입니다. 자세한 내용은 Spanner 읽기 및 쓰기 수명을 참고하세요.

샘플 trace

엔드 투 엔드 trace를 사용하면 다음 세부정보를 확인할 수 있습니다.

  • 애플리케이션과 Spanner 간의 지연 시간입니다. 네트워크 지연 시간을 계산하여 네트워크 문제가 있는지 확인할 수 있습니다.
  • 애플리케이션 요청이 제공되는 Spanner API 프런트엔드 클라우드 리전입니다. 이를 사용하여 애플리케이션과 Spanner 간의 교차 리전 호출을 확인할 수 있습니다.

다음 예에서 애플리케이션 요청은 us-west1 리전의 Spanner API 프런트엔드에서 처리되고 있으며 네트워크 지연 시간은 8.542밀리초(55.47밀리초 - 46.928밀리초)입니다.

엔드 투 엔드 trace 보기

다음 단계