Google Cloud Platformに戻る

Cloud Trace

Cloud Traceとは

Cloud Traceは、Google Cloud Platform (GCP) が提供する分散トレーシングシステムです。マイクロサービスアーキテクチャやクラウドネイティブアプリケーションにおいて、リクエストがシステム全体をどのように通過するかを追跡し、パフォーマンスのボトルネックを特定するためのツールです。Cloud Traceを使用することで、アプリケーションのレイテンシを分析し、パフォーマンスの問題を迅速に特定して解決することができます。

Cloud Traceの主な特徴

Cloud Traceのアーキテクチャ

Cloud Traceは以下の主要コンポーネントで構成されています:

コンポーネント 説明
Trace API トレースデータの送信、取得、管理のためのAPI
トレースコレクター アプリケーションからトレースデータを収集するコンポーネント
トレースストア トレースデータを保存するためのデータベース
トレースビューア トレースデータを視覚化するためのインターフェース
分析エンジン トレースデータを分析してパフォーマンスインサイトを生成

Cloud Trace と他のトレーシングサービスの違い

Cloud Traceと他のトレーシングサービスには以下のような違いがあります:

トレースの基本概念

Cloud Traceでは、以下の基本概念が重要です:

トレースとスパン

トレースとスパンの関係図

トレース
|
|-- スパンA (フロントエンド)
|   |
|   |-- スパンB (認証サービス)
|   |
|   |-- スパンC (データベースクエリ)
|       |
|       |-- スパンD (キャッシュ検索)
|
|-- スパンE (バックエンド処理)
    |
    |-- スパンF (外部APIコール)

Cloud Traceの使用方法

Cloud Traceは、Google Cloud Console、クライアントライブラリ、またはRESTful APIを使用して利用できます。

自動トレース収集

以下のGCPサービスでは、トレースが自動的に収集されます:

アプリケーションからのトレース出力

アプリケーションからCloud Traceにトレースを出力するには、各言語用のクライアントライブラリを使用します:

Node.jsでのトレース出力例

const { TraceExporter } = require('@google-cloud/opentelemetry-cloud-trace-exporter');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { trace } = require('@opentelemetry/api');

// トレースプロバイダーの設定
const provider = new NodeTracerProvider();
const exporter = new TraceExporter();
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();

// トレーサーの取得
const tracer = trace.getTracer('my-service');

// トレースの作成
async function performOperation() {
  const span = tracer.startSpan('operation');
  try {
    // 操作の実行
    span.setAttributes({
      'operation.name': 'example-operation',
      'operation.status': 'success'
    });
    
    // 子スパンの作成
    const childSpan = tracer.startSpan('child-operation', {
      parent: span
    });
    try {
      // 子操作の実行
      childSpan.addEvent('processing-item', {
        itemId: '12345'
      });
    } finally {
      childSpan.end();
    }
  } catch (error) {
    span.setStatus({
      code: SpanStatusCode.ERROR,
      message: error.message
    });
    throw error;
  } finally {
    span.end();
  }
}

performOperation();

Pythonでのトレース出力例

from opentelemetry import trace
from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# トレースプロバイダーの設定
tracer_provider = TracerProvider()
cloud_trace_exporter = CloudTraceSpanExporter()
tracer_provider.add_span_processor(BatchSpanProcessor(cloud_trace_exporter))
trace.set_tracer_provider(tracer_provider)

# トレーサーの取得
tracer = trace.get_tracer("my-service")

# トレースの作成
def perform_operation():
    with tracer.start_as_current_span("operation") as span:
        # 操作の実行
        span.set_attribute("operation.name", "example-operation")
        span.set_attribute("operation.status", "success")
        
        # 子スパンの作成
        with tracer.start_as_current_span("child-operation") as child_span:
            # 子操作の実行
            child_span.add_event("processing-item", {
                "itemId": "12345"
            })

perform_operation()

Javaでのトレース出力例

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.exporter.cloud.trace.CloudTraceExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;

public class TraceExample {
    public static void main(String[] args) {
        // トレースプロバイダーの設定
        SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
            .addSpanProcessor(BatchSpanProcessor.builder(CloudTraceExporter.builder().build()).build())
            .build();
        
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
            .setTracerProvider(tracerProvider)
            .build();
        
        // トレーサーの取得
        Tracer tracer = openTelemetry.getTracer("my-service");
        
        // トレースの作成
        performOperation(tracer);
    }
    
    private static void performOperation(Tracer tracer) {
        Span span = tracer.spanBuilder("operation")
            .setSpanKind(SpanKind.INTERNAL)
            .startSpan();
        
        try (Scope scope = span.makeCurrent()) {
            // 操作の実行
            span.setAttribute("operation.name", "example-operation");
            span.setAttribute("operation.status", "success");
            
            // 子スパンの作成
            Span childSpan = tracer.spanBuilder("child-operation")
                .setParent(span.getSpanContext())
                .startSpan();
            
            try (Scope childScope = childSpan.makeCurrent()) {
                // 子操作の実行
                childSpan.addEvent("processing-item", Attributes.of(
                    AttributeKey.stringKey("itemId"), "12345"
                ));
            } catch (Exception e) {
                childSpan.setStatus(StatusCode.ERROR, e.getMessage());
                throw e;
            } finally {
                childSpan.end();
            }
        } catch (Exception e) {
            span.setStatus(StatusCode.ERROR, e.getMessage());
            throw e;
        } finally {
            span.end();
        }
    }
}

トレースの表示と分析

Google Cloud Consoleのトレースエクスプローラーを使用して、トレースを表示、分析できます:

トレースの検索

// トレースIDによる検索
traceId:6aa74edf3077381279ba9eb291e7b8f8

// サービス名による検索
service:frontend

// 時間範囲による検索
start_time:2023-01-15T00:00:00Z end_time:2023-01-16T00:00:00Z

// レイテンシによる検索
latency:>100ms

// 複合検索
service:frontend latency:>100ms start_time:2023-01-15T00:00:00Z

トレースのサンプリング

すべてのリクエストをトレースするとオーバーヘッドが大きくなるため、サンプリングを使用して一部のリクエストのみをトレースすることが一般的です:

サンプリング設定の例

// Node.jsでのサンプリング設定
const { TraceExporter } = require('@google-cloud/opentelemetry-cloud-trace-exporter');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { ParentBasedSampler, TraceIdRatioBased } = require('@opentelemetry/sdk-trace-base');

// 10%のリクエストをサンプリング
const sampler = new ParentBasedSampler({
  root: new TraceIdRatioBased(0.1)
});

const provider = new NodeTracerProvider({
  sampler
});
const exporter = new TraceExporter();
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();

Cloud Traceのベストプラクティス

Cloud Traceを効果的に活用するためのベストプラクティス:

トレース設計のベストプラクティス

運用のベストプラクティス

コスト最適化のヒント

Cloud Traceのユースケース

Cloud Traceは以下のようなユースケースに適しています:

ユースケース例:マイクロサービスのパフォーマンス分析

マイクロサービスアーキテクチャのトレース分析

eコマースアプリケーションの注文処理フローにおけるパフォーマンス分析:

1. フロントエンドサービス (200ms)
   |
   |-- 認証サービス (50ms)
   |
   |-- 商品カタログサービス (100ms)
   |   |
   |   |-- 商品データベース (80ms)
   |   |
   |   |-- 在庫サービス (15ms)
   |
   |-- 注文サービス (150ms)
       |
       |-- 支払いサービス (120ms)
       |   |
       |   |-- 外部決済API (100ms)
       |
       |-- 配送サービス (30ms)

このトレース分析から、外部決済APIの呼び出しが全体のレイテンシの大部分を占めていることがわかります。この情報を基に、決済処理の最適化や非同期処理の導入などの改善策を検討できます。

Cloud Traceとの統合サービス

Cloud Traceは他のGoogle Cloudサービスと統合して、より強力なソリューションを構築できます:

サービス 統合の利点
Cloud Logging トレースとログを関連付けて、詳細なコンテキスト情報を提供
Cloud Monitoring トレースデータに基づいたメトリクスとアラートの設定
Error Reporting エラーとトレースを関連付けて、エラーの根本原因を特定
Cloud Profiler コードレベルのパフォーマンスボトルネックの特定
Cloud Debugger 本番環境でのコードのデバッグ

Cloud Loggingとの統合例

トレースIDをログに含める

// Node.jsでのトレースIDをログに含める例
const { trace } = require('@opentelemetry/api');

function logWithTraceId(message) {
  const currentSpan = trace.getSpan(trace.getActiveSpanContext());
  const traceId = currentSpan ? currentSpan.spanContext().traceId : 'no-trace-id';
  
  console.log(`[TraceID: ${traceId}] ${message}`);
}

// 使用例
logWithTraceId('ユーザー認証を開始');

まとめ

Cloud Trace は、Google Cloud Platform上での分散トレーシングサービスとして、マイクロサービスアーキテクチャやクラウドネイティブアプリケーションのパフォーマンス分析と最適化を支援します。リクエストがシステム全体をどのように通過するかを追跡し、パフォーマンスのボトルネックを特定するための強力なツールです。

Cloud Traceの主な利点は以下の通りです:

Cloud Traceを効果的に活用するには、重要な操作のトレース、適切なスパン粒度の設定、コンテキスト情報の追加、適切なサンプリングレートの設定などのベストプラクティスを適用することが重要です。また、トレースとログの関連付けや定期的なパフォーマンスレビューを行うことで、システムの可観測性を向上させることができます。