すべてのプロダクト
Search
ドキュメントセンター

Managed Service for OpenTelemetry:可観測性トレースサービスを使用して Swift アプリケーションデータを送信する

最終更新日:Dec 30, 2024

Alibaba Cloud Managed Service for OpenTelemetry を使用してアプリケーションをインストルメント化し、トレースデータを Managed Service for OpenTelemetry に送信すると、アプリケーションの監視が開始されます。アプリケーショントポロジー、トレース、異常トランザクション、低速トランザクション、SQL分析など、アプリケーションの監視データを表示できます。このトピックでは、可観測性トレースサービスを使用して Swift アプリケーションをインストルメント化し、Swift アプリケーションのトレースデータを送信する方法について説明します。

始める前に

可観測性トレースサービスのエンドポイントを取得するには、次の手順を実行します。

  1. 可観測性トレースサービスコンソール にログインします。

  2. 左側のナビゲーションペインで、クラスタ設定 をクリックします。表示されるページで、アクセスポイント情報 タブをクリックします。

  3. 上部のナビゲーションバーで地域を選択します。クラスタ情報セクションで、トークンを表示 をオンにします。

  4. クライアントパラメータを OpenTelemetry に設定します。

    下部の表の関連情報列に、可観測性トレースサービスのエンドポイントが表示されます。OT接入点信息

    説明

    アプリケーションがAlibaba Cloudの本番環境にデプロイされている場合は、Virtual Private Cloud (VPC) エンドポイントを使用します。それ以外の場合は、パブリックエンドポイントを使用します。

サンプルコード

この例では、可観測性トレースサービスを使用して、Swift で記述された macOS コマンドラインアプリケーションのトレースデータを送信します。この例で使用されている方法は、iOS アプリケーションにも適用されます。

opentelemetry-swift-demo からサンプルコードをダウンロードします。

手順 1: アプリケーションを作成し、依存関係を追加する

  1. 作成するアプリケーションの種類を選択します。たとえば、macOS > コマンドラインツール を選択します。

    Command Line Tool

  2. XCode で、ファイル > パッケージを追加... を選択し、検索ボックスに https://github.com/open-telemetry/opentelemetry-swift と入力して、バージョン 1.4.1 を選択します。

    説明

    バージョンについて詳しくは、GitHub の opentelemetry-swift ページをご覧ください。

    opentelemetry-swift

  3. 必要なパッケージを選択します。

    次の図は、この例で使用されているパッケージを示しています。Package Products

手順 2: OpenTelemetry を初期化する

  1. 監視データをエクスポートするためのエクスポーターを作成します。

    次のいずれかの方法を選択して、トレースデータを送信します。

    • 方法 1: gRPC プロトコルを使用してトレースデータを送信する

      • <gRPC-endpoint><gRPC-port> を、このトピックの「始める前に」セクションで取得したエンドポイントとポート番号に置き換えます。この例では、host: "http://tracing-analysis-dc-hz.aliyuncs.com", port:8090 を使用しています。

      • <your-token> を、「始める前に」セクションで取得した認証トークンに置き換えます。

      let grpcChannel = ClientConnection(
          configuration: ClientConnection.Configuration.default(
              target: .hostAndPort("<gRPC-endpoint>", 8090), // http:// プレフィックスを含まないエンドポイントを指定します。この例では、tracing-analysis-dc-hz.aliyuncs.com を使用しています。
              eventLoopGroup: MultiThreadedEventLoopGroup(numberOfThreads: 1)
          )
      )
      
      let otlpGrpcConfiguration = OtlpConfiguration(
          timeout: OtlpConfiguration.DefaultTimeoutInterval,
          headers: [
              ("Authentication","xxxxxx")
          ]
      
      )
      let otlpGrpcTraceExporter = OtlpTraceExporter(channel: grpcChannel, config: otlpGrpcConfiguration)
    • 方法 2: HTTP プロトコルを使用してトレースデータを送信する

      <HTTP-endpoint> を、「始める前に」セクションで取得したエンドポイントに置き換えます。この例では、http://tracing-analysis-dc-hz.aliyuncs.com/adapt_xxxx@xxxx_xxxx@xxxx/api/otlp/traces を使用しています。

      let url = URL(string: "<HTTP-endpoint>")
      let otlpHttpTraceExporter = OtlpHttpTraceExporter(endpoint: url!)
    • 方法 3: コマンドラインでトレースデータを取得する

      let consoleTraceExporter = StdoutExporter(isDebug: true)
  2. スパンを作成するために使用するトレーサーを取得します。

    • <your-service-name> を、データを送信するアプリケーションの名前に置き換え、<your-host-name> をホスト名に置き換えます。

    • <trace-exporter> を、手順 1 でトレースデータを送信するために使用した方法に基づいて異なる値に置き換えます。

      • 方法 1: <trace-exporter>otlpGrpcTraceExporter に置き換えます。

      • 方法 2: <trace-exporter>otlpHttpTraceExporter に置き換えます。

      • 方法 3: <trace-exporter>consoleTraceExporter に置き換えます。

    // アプリケーション名とホスト名を指定します。
    let resource = Resource(attributes: [
        ResourceAttributes.serviceName.rawValue: AttributeValue.string("<your-service-name>"),
        ResourceAttributes.hostName.rawValue: AttributeValue.string("<your-host-name>")
    ])
    
    // TracerProvider を設定します。
    OpenTelemetry.registerTracerProvider(tracerProvider: TracerProviderBuilder()
                                         .add(spanProcessor: BatchSpanProcessor(spanExporter: <trace-exporter>)) // 可観測性トレースサービスにデータを送信します。
                                         .with(resource: resource)
                                         .build())
    
    // スパンを作成するために使用するトレーサーを取得します。
    let tracer = OpenTelemetry.instance.tracerProvider.get(instrumentationName: "instrumentation-library-name", instrumentationVersion: "1.0.0")

手順 3: トレースデータを追跡するためのスパンを作成する

  1. スパンを作成し、スパンの属性とイベントを設定し、スパンのトレース ID を取得します。

    let span = tracer.spanBuilder(spanName: "first span").startSpan()
    // 属性を設定します。
    span.setAttribute(key: "http.method", value: "GET")
    span.setAttribute(key: "http.url", value: "www.aliyun.com")
    let attributes = [
        "key": AttributeValue.string("value"),
        "result": AttributeValue.int(100)
    ]
    
    // コードを記述します...
    
    // イベントを設定します。
    span.addEvent(name: "computation complete", attributes: attributes)
    
    // トレース ID を表示します。
    print(span.context.traceId.hexString)
    
    // コードを記述します...
    
    // 現在のスパンを終了します。
    span.end()
  2. ネストされたスパンを作成します。

    let parentSpan = tracer.spanBuilder(spanName: "parent span").startSpan()
    
    // コードを記述します...
    
    let childSpan = tracer.spanBuilder(spanName: "child span").setParent(parentSpan).startSpan()
    
    // コードを記述します...
    
    childSpan.end()
    
    // コードを記述します...
    
    parentSpan.end()
  3. アプリケーションを起動します。

    可観測性トレースサービスコンソールアプリケーションページで、アプリケーションの名前をクリックします。表示されるページで、トレースデータを確認します。

手順 4: クライアントアプリケーションとサーバーアプリケーションを接続する

  1. HTTP リクエストヘッダーでトレースデータを渡す形式を変更します。

    • プロトコルによって、トレースコンテキストを渡すために使用される HTTP リクエストヘッダーが異なります。たとえば、OpenTelemetry はデフォルトで W3C Trace Context 形式を使用し、他の形式もサポートしています。Zipkin は B3 または B3 Multi 形式を使用します。詳しくは、トレースデータを渡す形式を指定する をご覧ください。

    • サーバーアプリケーションで使用されているプロトコルに基づいて、クライアントアプリケーションのトレースデータを渡す形式を設定します。これにより、iOS クライアントアプリケーションとサーバーアプリケーションを接続できます。

      • サーバーアプリケーションが OpenTelemetry の W3C Trace Context 形式を使用している場合は、クライアントアプリケーションの textPropagators パラメータと baggagePropagator パラメータを指定する必要はありません。

      • サーバーアプリケーションが Zipkin の B3 または B3 Multi 形式を使用している場合は、クライアントアプリケーションの textPropagators パラメータを B3Propagator に、baggagePropagator パラメータを ZipkinBaggagePropagator に設定します。

        // トレースデータを渡すために B3 形式を指定します。
        OpenTelemetry.registerPropagators(textPropagators: [B3Propagator()],
                                          baggagePropagator: ZipkinBaggagePropagator())
      • サーバーアプリケーションが Jaeger プロトコルを使用している場合は、クライアントアプリケーションの textPropagators パラメータを JaegerPropagator に、baggagePropagator パラメータを JaegerBaggagePropagator に設定する必要があります。

        // トレースデータを渡すために Jaeger 形式を指定します。
        OpenTelemetry.registerPropagators(textPropagators: [JaegerPropagator()],
                                          baggagePropagator: JaegerBaggagePropagator())
      • 複数の形式を指定してトレースデータを渡すこともできます。

        // トレースデータを渡すために W3C Trace Context、B3、Jaeger 形式を指定します。
        OpenTelemetry.registerPropagators(textPropagators: [W3CTraceContextPropagator(), 
                                                            B3Propagator(), 
                                                            JaegerPropagator()],
                                          baggagePropagator: W3CBaggagePropagator())
  2. URLSessionInstrumentation プラグインをインポートします。

    URLSessionInstrumentation は、OpenTelemetry が URLSession クラスに提供する自動インストルメンテーションプラグインです。URLSession クラスから送信されるすべてのネットワークリクエストを自動的にインターセプトし、トレースを作成します。

    import URLSessionInstrumentation
    
    ...
    let networkInstrumentation = URLSessionInstrumentation(configuration: URLSessionInstrumentationConfiguration())
  3. URLSession クラスを使用して、サーバーアプリケーションにアクセスするためのリクエストを送信します。

    let url = URL(string: "<サーバーアドレス>")!
    let request = URLRequest(url: url)
    let semaphore = DispatchSemaphore(value: 0)
    
    let task = URLSession.shared.dataTask(with: request) { data, _, _ in
        if let data = data {
            let string = String(decoding: data, as: UTF8.self)
            print(string)
        }
        semaphore.signal()
    }
    task.resume()
    
    semaphore.wait()

    完全なサンプルコードを表示する

    OpenTelemetryUtil.swift

    import Foundation
    
    import GRPC
    import NIO
    import OpenTelemetryApi
    import OpenTelemetrySdk
    import OpenTelemetryProtocolExporter
    import StdoutExporter
    
    class OpenTelemetryUtil {
        
        private static let tracerProvider: TracerProvider = {
            // gRPC プロトコルを使用してトレースデータを送信します。
            let grpcChannel = ClientConnection(
                configuration: ClientConnection.Configuration.default(
                    target: .hostAndPort("tracing-analysis-dc-hz.aliyuncs.com", 8090),
                    eventLoopGroup: MultiThreadedEventLoopGroup(numberOfThreads: 1)
                )
            )
            
    
            let otlpGrpcConfiguration = OtlpConfiguration(
                timeout: OtlpConfiguration.DefaultTimeoutInterval,
                headers: [
                    ("Authentication","${認証トークン}") // 認証トークン
                ]
    
            )
            let otlpGrpcTraceExporter = OtlpTraceExporter(channel: grpcChannel, config: otlpGrpcConfiguration)
            let consoleTraceExporter = StdoutExporter(isDebug: true)
            
            // アプリケーション名とホスト名を指定します。
            let resource = Resource(attributes: [
                ResourceAttributes.serviceName.rawValue: AttributeValue.string("otel-swift-demo-grpc"),
                ResourceAttributes.hostName.rawValue: AttributeValue.string("adam.mac")
            ])
    
            let tracerProvider = TracerProviderBuilder()
                .add(spanProcessor: BatchSpanProcessor(spanExporter: otlpGrpcTraceExporter))
    //            .add(spanProcessor: BatchSpanProcessor(spanExporter: consoleTraceExporter)) // デバッグ用にコンソールにトレースデータを表示します。
                .with(resource: resource)
                .build()
            
            
            // TracerProvider を設定します。
            OpenTelemetry.registerTracerProvider(tracerProvider: tracerProvider)
            // トレースデータを渡す形式を変更します。
            OpenTelemetry.registerPropagators(textPropagators: [W3CTraceContextPropagator(),
                                                                B3Propagator(),
                                                                JaegerPropagator()],
                                              baggagePropagator: W3CBaggagePropagator())
            
            return tracerProvider
            
        }()
        
        
        // スパンを作成するために使用するトレーサーを取得します。
        static func getTracer(name: String, version: String) -> Tracer {
            return tracerProvider.get(instrumentationName: name, instrumentationVersion: version)
        }
    
    }
    

    main.swift

    import Foundation
    
    
    import OpenTelemetryApi
    import OpenTelemetrySdk
    // ネットワークリクエストの自動インストルメンテーションを実行します。
    import URLSessionInstrumentation
    
    let tracer = OpenTelemetryUtil.getTracer(name: "ios-demo", version: "1.0.0")
    
    // ネストされたスパンを作成します。
    let parentSpan = tracer.spanBuilder(spanName: "parent span").startSpan()
    
    let childSpan = tracer.spanBuilder(spanName: "child span").setParent(parentSpan).startSpan()
    
    // 属性を設定します。
    childSpan.setAttribute(key: "http.method", value: "GET")
    childSpan.setAttribute(key: "http.url", value: "www.aliyun.com")
    let attributes = [
        "stringKey": AttributeValue.string("value"),
        "intKey": AttributeValue.int(100)
    ]
    // イベントを設定します。
    childSpan.addEvent(name: "event", attributes: attributes)
    // トレース ID を表示します。
    print(childSpan.context.traceId.hexString)
    
    // サーバーアプリケーションにアクセスするためのネットワークリクエストを送信します。
    let networkInstrumentation = URLSessionInstrumentation(configuration: URLSessionInstrumentationConfiguration())
    
    let url = URL(string: "${サーバーアドレス}")! // サーバーアドレス
    let request = URLRequest(url: url)
    let semaphore = DispatchSemaphore(value: 0)
    
    let task = URLSession.shared.dataTask(with: request) { data, _, _ in
        if let data = data {
            let string = String(decoding: data, as: UTF8.self)
            print(string)
        }
        semaphore.signal()
    }
    task.resume()
    
    semaphore.wait()
    
    
    // 作成されたスパンを手動で終了します。
    childSpan.end()
    parentSpan.end()
    
    sleep(60)
    
    print("end")
    
  4. アプリケーションを起動し、トレースエクスプローラーページでクライアントアプリケーションとサーバーアプリケーション間のトレースを確認します。

    次の図は例を示しています。この例では、HTTP GET は iOS アプリケーション、zipkin-demo-server はサーバーアプリケーションです。

    image