クライアントサイドのトレースでパフォーマンスをモニタリングする

Firestore リクエストをエンドツーエンドでモニタリングしてデバッグするには、クライアント ライブラリでトレースを有効にします。クライアントサイドのトレースでは、アプリケーションで発生したパフォーマンスに関するシグナルと、問題のデバッグに役立つ分析情報を提供できます。

クライアントサイドのトレースでは、クライアントからの RPC の実行によって収集され、次の情報を提供します。

  • クライアントが RPC リクエストを送信した時点やクライアントが RPC レスポンスを受信した時点のタイムスタンプを含むスパンで、ネットワークとクライアント システムによって発生するレイテンシが含まれます。
  • クライアントとその構成に関する情報を表示する属性(Key-Value ペア)
  • スパンのキーイベントに関連付けられたログ
  • クライアントでクラッシュが発生した場合のスタック トレース

OpenTelemetry

クライアント ライブラリのトレースには、OpenTelemetry API が使用されます。OpenTelemetry は、業界標準のオープンソース化されたオブザーバビリティ フレームワークです。OpenTelemetry には、計測 API や SDK、コレクタ、バックエンド固有のエクスポータなど、さまざまなツールが用意されています。また、サンプリング制御やスパン上限などの柔軟な構成オプションも用意されています。

エクスポータとコレクタを使用してトレースをエクスポートする

構成の一環として、トレースのオブザーバビリティ バックエンドへのエクスポートを行うことができます。ほとんどのオブザーバビリティ サービス プロバイダは、Cloud Trace などのエクスポータを用意しています。

OpenTelemetry では、エクスポータに加えて、Collector を設定することをおすすめします。Collector により、サービスがデータを迅速にオフロードできるようになります。また、Collector が再試行、バッチ処理、暗号化などの追加処理を行うことができます。Collector はアプリケーションとともに実行されます。Collector は OTLP メッセージを受信して処理し、オブザーバビリティ バックエンドにエクスポートします。

制限事項

クライアントサイド トレースには次の制限があります。

  • トレーススパンは、Java クライアント ライブラリと Node.js クライアント ライブラリで使用できます。
  • クライアント ライブラリは、リアルタイム リスナーのトレース スパンを生成しません。

課金

クライアントサイド トレースでは、Firestore の使用量に加えて費用が発生する場合があります。

トレースの収集や OpenTelemetry フレームワークの使用に料金は発生しません。

トレーススパンのオブザーバビリティ バックエンドへの取り込みに料金が発生する可能性があります。たとえば、バックエンドとして Cloud Trace を使用する場合は、Cloud Trace の料金に従って課金されます。別のオブザーバビリティ サービス プロバイダを使用している場合は、その請求モデルと関連費用を確認します。

課金について把握するには、トラフィックに基づいて小さなトレース サンプリング比率(RPC のごく一部をトレース)から始めます。

始める前に

始める前に:

  • アプリがオブザーバビリティ バックエンドにトレースを書き込むサービス アカウントを、必要な Identity and Access Management ロールで設定します。

    トレース オペレーション IAM ロール
    トレースを読み取る roles/cloudtrace.user
    トレースに書き込む roles/cloudtrace.agent
    読み取り/書き込みトレース roles/cloudtrace.admin
  • このプロジェクトで Trace API が有効になっていることを確認します。

クライアント側トレースを構成する

このセクションでは、クライアントサイド トレースの構成例について説明します。Collector にエクスポートすることも、オブザーバビリティ バックエンドに直接エクスポートすることもできます。クライアントサイド トレースを構成するには、次のオプションもあります。

OpenTelemetry API を使用してコレクタにトレースをエクスポートする

次のコードは、サンプリング率 10% でスパンを OpenTelemetry Collector にエクスポートするようにクライアント ライブラリを構成します。

Java(管理)

Resource resource = Resource
  .getDefault().merge(Resource.builder().put(SERVICE_NAME, "My App").build());

OtlpGrpcSpanExporter otlpGrpcSpanExporter =
  OtlpGrpcSpanExporter
  .builder()
  .setEndpoint("http://localhost:4317") // Replace with your OTLP endpoint
  .build();

// Using a batch span processor
// You can also use other `BatchSpanProcessorBuilder` methods
// to further customize.
BatchSpanProcessor otlpGrpcSpanProcessor =
  BatchSpanProcessor.builder(otlpGrpcSpanExporter).build();

// Export to a collector that is expecting OTLP using gRPC.
OpenTelemetrySdk otel = OpenTelemetrySdk.builder()
        .setTracerProvider(
          SdkTracerProvider.builder()
            .setResource(resource)
            .addSpanProcessor(otlpGrpcSpanProcessor)
            .setSampler(Sampler.traceIdRatioBased(0.1))
            .build())
          .build();

Firestore firestore = FirestoreOptions
  .newBuilder()
  .setOpenTelemetryOptions(
    FirestoreOpenTelemetryOptions.newBuilder()
      .setTracingEnabled(true)
      .setOpenTelemetry(otel)
      .build())
  .build().getService();

    
Node.js(管理)

import { trace } from "@opentelemetry/api";
import {GrpcInstrumentation} from '@opentelemetry/instrumentation-grpc';

import pkg1 from "@opentelemetry/sdk-trace-node";
import pkg2 from "@opentelemetry/instrumentation";
import pkg3 from "@opentelemetry/exporter-trace-otlp-grpc";

const { NodeTracerProvider, BatchSpanProcessor, TraceIdRatioBasedSampler } = pkg1;
const { registerInstrumentations } = pkg2;
const { OTLPTraceExporter } =  pkg3;

const provider = new NodeTracerProvider(
  // Provide your chosen NodeTracerConfig such as sampler and span limit
  {
    sampler: new TraceIdRatioBasedSampler(0.1),
  }
);
provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter()));
provider.register();

// If you'd like to see gRPC spans (recommended), enable GrpcInstrumentation
registerInstrumentations({
  instrumentations: [
    new GrpcInstrumentation(
      // (optional): you can add GrpcInstrumentationConfig here
    ),
  ],
});


const settings: Settings = {
  projectId: 'my-project-id',
  preferRest: false,
  openTelemetry: {
    tracerProvider: trace.getTracerProvider()
  }
};

// Initialize Firestore
const firestore = new Firestore(settings);
// Add app code here

// Make sure to shut down your TracerProvider to flush any traces left in memory.
process.on('SIGINT', async () => {
  await provider
        .shutdown()
        .catch(error => console.error('Error terminating NodeTracerProvider:', error));
});
    

OpenTelemetry API を使用してオブザーバビリティ バックエンドに直接エクスポートする

オブザーバビリティ サービス プロバイダが OTLP 取り込みをサポートしている場合は、OpenTelemetry エクスポータを使用して、トレースをバックエンドに直接エクスポートできます。次のコードは、トレース スパンを Cloud Trace に直接エクスポートし、トレース サンプリング比率を 10% に設定するようにクライアント ライブラリを構成します。

Java(管理)

// TraceExporter needed for this use case
import com.google.cloud.opentelemetry.trace.TraceExporter;

Resource resource = Resource
  .getDefault().merge(Resource.builder().put(SERVICE_NAME, "My App").build());
SpanExporter gcpTraceExporter = TraceExporter.createWithDefaultConfiguration();

// Using a batch span processor
// You can also use other `BatchSpanProcessorBuilder` methods
// to further customize.
SpanProcessor gcpBatchSpanProcessor =
  BatchSpanProcessor.builder(gcpTraceExporter).build();

// Export directly to Cloud Trace with 10% trace sampling ratio
OpenTelemetrySdk otel = OpenTelemetrySdk.builder()
        .setTracerProvider(SdkTracerProvider.builder()
            .setResource(resource)
            .addSpanProcessor(gcpBatchSpanProcessor)
            .setSampler(Sampler.traceIdRatioBased(0.1))
            .build())
        .build();

Firestore firestore = FirestoreOptions
  .newBuilder()
  .setOpenTelemetryOptions(
    FirestoreOpenTelemetryOptions.newBuilder()
      .setTracingEnabled(true)
      .setOpenTelemetry(otel)
      .build())
  .build().getService();

    
Node.js(管理)

import { trace } from "@opentelemetry/api";
import {GrpcInstrumentation} from '@opentelemetry/instrumentation-grpc';
import { TraceExporter } from "@google-cloud/opentelemetry-cloud-trace-exporter";

import pkg1 from "@opentelemetry/sdk-trace-node";
import pkg2 from "@opentelemetry/instrumentation";

const { NodeTracerProvider, BatchSpanProcessor, TraceIdRatioBasedSampler } = pkg1;
const { registerInstrumentations } = pkg2;

const provider = new NodeTracerProvider(
  // Provide your chosen NodeTracerConfig such as sampler and span limits
  {
    sampler: new TraceIdRatioBasedSampler(0.1),
  }
);
provider.addSpanProcessor(new BatchSpanProcessor(new TraceExporter()));
provider.register();

// If you'd like to see gRPC spans (recommended), enable GrpcInstrumentation
registerInstrumentations({
  instrumentations: [
    new GrpcInstrumentation(
      // (optional): you can add GrpcInstrumentationConfig here
    ),
  ],
});


const settings: Settings = {
  projectId: 'my-project-id',
  preferRest: false,
  openTelemetry: {
    tracerProvider: trace.getTracerProvider()
  }
};

// Initialize Firestore
const firestore = new Firestore(settings);
// ...

// Make sure to shut down your TracerProvider to flush any traces left in memory.
process.on('SIGINT', async () => {
  await provider
        .shutdown()
        .catch(error => console.error('Error terminating NodeTracerProvider:', error));
});
    

ノーコード計測

コードを変更せずにトレースを構成するには、次の手順を行います。

Java(管理)
自動エージェントを使用すると、コードを変更せずにトレースを構成できます。環境変数 FIRESTORE_ENABLE_TRACING=ON を設定する必要があります。また、エージェントの構成で説明されているように、他の構成設定も設定する必要があります。次の例をご覧ください。

Auto Agent を使用してコレクタにエクスポートする

OTLP gRPC レシーバーを有効にして OpenTelemetry Collector を実行します。エージェントのエクスポータを otlp に設定し、エージェントがデータをエクスポートするエンドポイントを指定します。次の例では、サンプリング率を 10% にして、localhost ポート 4317 でリッスンしているコレクタにトレースを送信します。


FIRESTORE_ENABLE_TRACING=ON                            \
java                                                   \
-javaagent:path/to/opentelemetry-javaagent.jar         \
-Dotel.traces.exporter=otlp                            \
-Dotel.exporter.otlp.endpoint="http://localhost:4317"  \
-Dotel.traces.sampler=traceidratio                     \
-Dotel.traces.sampler.arg=0.1                          \
-Dotel.service.name="My App"                           \
-jar myapp.jar

Auto エージェントを使用してオブザーバビリティ バックエンドに直接エクスポートする

環境変数 FIRESTORE_ENABLE_TRACING=ON を設定するだけでなく、特定のバックエンド用の OpenTelemetry Java エージェント拡張機能を追加する必要があります。次の例では、Trace エクスポータ拡張機能と 10% のトレース サンプリング率を使用します。


FIRESTORE_ENABLE_TRACING=ON                                                \
java                                                                       \
-javaagent:path/to/opentelemetry-javaagent.jar                             \
-Dotel.javaagent.extensions=/path/to/exporter-auto-0.26.0-alpha-shaded.jar \
-Dotel.traces.exporter=google_cloud_trace                                  \
-Dotel.traces.sampler=traceidratio                                         \
-Dotel.traces.sampler.arg=0.1                                              \

    
Node.js(管理)

ゼロコード計測を設定するには、JavaScript 計測用の OpenTelemetry の手順に沿って操作します。次のコード スニペットは、インストルメンテーションを有効にして、OpenTelemetry コレクタにトレースを送信します。


npm install --save @opentelemetry/api
npm install --save @opentelemetry/auto-instrumentations-node


env \
FIRESTORE_ENABLE_TRACING=ON \
OTEL_TRACES_EXPORTER=otlp \
OTEL_NODE_ENABLED_INSTRUMENTATIONS="http,grpc" \
OTEL_NODE_RESOURCE_DETECTORS="none" \
node --require @opentelemetry/auto-instrumentations-node/register my_app.js

    

トレースの例

次の例は、Cloud Trace でトレース情報がどのように表示されるかを示しています。使用可能な属性と値の詳細については、トレーススパンの属性とイベントをご覧ください。

トレーススパンの例

Cloud Trace から表示されたトレーススパン

イベントログの例

Cloud Trace から表示されたトレーススパンのログ

属性値の例

Cloud Trace から表示されたトレーススパンの属性値

スタック トレースおよび例外イベントの例

Cloud Trace から表示されたスタック トレース

Cloud Trace から表示された例外イベント

次のステップ