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

Application Real-Time Monitoring Service:OpenTelemetry を使用した C++ アプリケーションのトレースデータのレポート

最終更新日:Mar 12, 2026

分散トレーシングは、マイクロサービス全体でレイテンシーのボトルネックや障害を特定するのに役立ちます。OpenTelemetry C++ SDK を使用して C++ アプリケーションをインストルメント化することで、HTTP または gRPC 経由で OpenTelemetry 向けマネージドサービスにトレースデータをエクスポートできます。接続が完了すると、ARMS コンソールに、ご利用のアプリケーションのアプリケーショントポロジー、トレース、異常および低速なトランザクション、SQL 分析が表示されます。

仕組み

OpenTelemetry C++ SDK は、3 つのコアコンポーネントを使用してトレースデータを収集し、エクスポートします。

コンポーネント役割
TracerProviderトレーサーを作成および管理します。各トレーサーは、作業単位を表すスパンを生成します。
SpanProcessor完了したスパンを受信し、エクスポーターに転送します。SimpleSpanProcessor は各スパンを即座にエクスポートするため、デモに適しています。本番環境では、スループットを向上させるために BatchSpanProcessor を使用してください。
OTLP エクスポーターHTTP または gRPC 経由でバックエンドにスパンを送信します。このガイドでは、バックエンドとして OpenTelemetry 向けマネージドサービスを使用します。

前提条件

エンドポイントと認証トークンの取得

  1. OpenTelemetry 向けマネージドサービスコンソールにログインします。

  2. 左側のナビゲーションウィンドウで、[クラスター設定] をクリックし、[アクセスポイント情報] タブをクリックします。

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

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

  5. [関連情報] 列で、ご利用のネットワーク環境に一致するエンドポイントとトークンをコピーします。gRPC の場合は、同じ行に表示される認証トークンもコピーします。

    デプロイメント使用するエンドポイント
    Alibaba Cloud 上 (ECS、ACK、またはその他の Alibaba Cloud サービス)VPC エンドポイント
    Alibaba Cloud 外部またはローカル開発パブリックエンドポイント

    Access point information

環境要件

  • C++ 11 以降

  • サポートされている C++ コンパイラのバージョンとプラットフォームについては、「opentelemetry-cpp supported versions」をご参照ください。

サンプルコード

完全なサンプルコードは alibabacloud-observability/cpp-demo で入手できます。

環境の準備

  1. (任意) GCC ツールチェーンを使用して Docker コンテナを起動します。

       docker pull gcc                               # Debian ベースのイメージ
       docker run -it --name otel-cpp-demo gcc bash
  2. システム依存関係 (protobuf、gRPC、およびビルドツール) をインストールします。

       apt-get update
       apt-get install sudo
    
       sudo apt-get install git cmake g++ libcurl4-openssl-dev
       # protobuf
       sudo apt-get install protobuf-compiler libprotobuf-dev
       # gRPC
       sudo apt-get install -y libgrpc++-dev libgrpc-dev protobuf-compiler-grpc

OpenTelemetry C++ SDK のビルドとインストール

リポジトリをクローンし、OTLP エクスポーターのサポートを有効にしてビルドし、/usr/local にインストールします。

git clone --recurse-submodules https://github.com/open-telemetry/opentelemetry-cpp

cd opentelemetry-cpp
mkdir build && cd build
cmake -DBUILD_TESTING=OFF -DWITH_OTLP_GRPC=ON -DWITH_OTLP_HTTP=ON ..

cmake --build . --target all

# /usr/local (推奨されるデフォルトパス) にインストールします
cmake --install .

# 代わりにカスタムパスにインストールするには、次の行のコメントを解除します
# cmake --install . --prefix /opentelemetry-cpp-lib

トレースデータのレポート

トランスポートプロトコルを選択します。HTTP と gRPC の両方で、スパンを OpenTelemetry 向けマネージドサービスにエクスポートします。「前提条件」セクションから、一致するエンドポイントを使用してください。

プロトコル使用する状況認証
HTTPセットアップが簡単で、ほとんどのプロキシやファイアウォールを通過できますエンドポイント URL に埋め込みの認証情報が含まれています
gRPC大量のトレースデータに対してオーバーヘッドが少ないです個別の認証トークンが必要です

HTTP 経由でのデータレポート

  1. プロジェクトディレクトリを作成します。

       mkdir otel-http-export-demo
       cd otel-http-export-demo
  2. CMakeLists.txt ファイルを作成します。

       cmake_minimum_required(VERSION 3.25.1)
       project(otel-http-export-demo)
    
       add_executable(otel-http-export-demo http_exporter.cc)
    
       find_package(opentelemetry-cpp CONFIG REQUIRED)
       find_package(protobuf)
       find_package(gRPC)
       find_package(CURL)
       find_package(nlohmann_json)
    
       include_directories("${OPENTELEMETRY_CPP_INCLUDE_DIRS}")
    
       target_link_libraries(
           otel-http-export-demo
           opentelemetry_trace
           opentelemetry_common
           opentelemetry_http_client_curl
           opentelemetry_exporter_otlp_http
           opentelemetry_exporter_otlp_grpc
           opentelemetry_exporter_otlp_http_client
           opentelemetry_otlp_recordable
           opentelemetry_resources
       )
  3. http_exporter.cc ファイルを作成します。次のプレースホルダーを実際の値に置き換えてください。

    プレースホルダー説明
    <your-service-name>ARMS コンソールでアプリケーションを識別するための名前my-cpp-service
    <your-host-name>アプリケーションを実行しているマシンのホスト名prod-server-01
       // Copyright The OpenTelemetry Authors
       // SPDX-License-Identifier: Apache-2.0
    
       #include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h"
       #include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h"
       #include "opentelemetry/context/propagation/global_propagator.h"
       #include "opentelemetry/context/propagation/text_map_propagator.h"
       #include "opentelemetry/exporters/ostream/span_exporter_factory.h"
       #include "opentelemetry/nostd/shared_ptr.h"
       #include "opentelemetry/sdk/trace/simple_processor_factory.h"
       #include "opentelemetry/sdk/trace/tracer_context.h"
       #include "opentelemetry/sdk/trace/tracer_context_factory.h"
       #include "opentelemetry/sdk/trace/tracer_provider_factory.h"
       #include "opentelemetry/trace/propagation/http_trace_context.h"
       #include "opentelemetry/trace/provider.h"
       #include "opentelemetry/ext/http/client/http_client_factory.h"
       #include "opentelemetry/sdk/resource/semantic_conventions.h"
       #include "opentelemetry/sdk/common/global_log_handler.h"
    
       #include <string>
    
    
       namespace trace     = opentelemetry::trace;
       namespace trace_sdk = opentelemetry::sdk::trace;
       namespace otlp      = opentelemetry::exporter::otlp;
       namespace internal_log = opentelemetry::sdk::common::internal_log;
       namespace resource = opentelemetry::sdk::resource;
    
       namespace nostd = opentelemetry::nostd;
    
       namespace
       {
           opentelemetry::exporter::otlp::OtlpHttpExporterOptions opts;
           void InitTracer()
           {
               // 設定されたエンドポイントにスパンを送信する OTLP/HTTP エクスポーターを作成します。
               auto exporter  = otlp::OtlpHttpExporterFactory::Create(opts);
               // SimpleSpanProcessor は各スパンを即座にエクスポートします。本番環境では、
               // ネットワークのオーバーヘッドを削減するために BatchSpanProcessor の使用を検討してください。
               auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
    
               // ARMS がこのアプリケーションを識別できるようにリソース属性を設定します。
               resource::ResourceAttributes attributes = {
                       {resource::SemanticConventions::kServiceName, "<your-service-name>"},
                       {resource::SemanticConventions::kHostName, "<your-host-name>"}
               };
               auto resource = opentelemetry::sdk::resource::Resource::Create(attributes);
    
               std::shared_ptr<opentelemetry::trace::TracerProvider> provider =
                       trace_sdk::TracerProviderFactory::Create(std::move(processor), std::move(resource));
    
               // グローバルなトレーサープロバイダーとして登録します。
               trace::Provider::SetTracerProvider(provider);
           }
    
           void CleanupTracer()
           {
               std::shared_ptr<opentelemetry::trace::TracerProvider> none;
               trace::Provider::SetTracerProvider(none);
           }
    
           nostd::shared_ptr<trace::Tracer> get_tracer()
           {
               auto provider = trace::Provider::GetTracerProvider();
               return provider->GetTracer("library name to trace", OPENTELEMETRY_SDK_VERSION);
           }
    
           void f1()
           {
               auto scoped_span = trace::Scope(get_tracer()->StartSpan("f1"));
           }
    
           void f2()
           {
               auto scoped_span = trace::Scope(get_tracer()->StartSpan("f2"));
    
               f1();
               f1();
           }
    
           void foo_library()
           {
               auto scoped_span = trace::Scope(get_tracer()->StartSpan("library"));
    
               f2();
           }
       }  // namespace
    
       /*
         使用方法:
         - example_otlp_http
         - example_otlp_http <URL>
         - example_otlp_http <URL> <DEBUG>
         - example_otlp_http <URL> <DEBUG> <BIN>
         <DEBUG> = yes|no、コンソールデバッグをオンまたはオフにします
         <BIN> = bin、バイナリ形式でエクスポートします
       */
       int main(int argc, char *argv[])
       {
           if (argc > 1)
           {
               opts.url = argv[1];
               if (argc > 2)
               {
                   std::string debug  = argv[2];
                   opts.console_debug = debug != "" && debug != "0" && debug != "no";
               }
    
               if (argc > 3)
               {
                   std::string binary_mode = argv[3];
                   if (binary_mode.size() >= 3 && binary_mode.substr(0, 3) == "bin")
                   {
                       opts.content_type = otlp::HttpRequestContentType::kBinary;
                   }
               }
           }
    
           if (opts.console_debug)
           {
               internal_log::GlobalLogHandler::SetLogLevel(internal_log::LogLevel::Debug);
           }
    
           InitTracer();
    
           foo_library();
    
           CleanupTracer();
       }
  4. プロジェクトをビルドします。

       mkdir build && cd build && cmake .. && make
  5. デモを実行します。「前提条件」セクションの HTTP エンドポイントを最初の引数として渡します。例:デバッグログを有効にしてスパンがエクスポートされたことを確認するには、2 番目の引数として yes を渡します。プログラムがエラーなく終了した場合、スパンはエクスポートされています。「トレースデータの検証」に進み、コンソールに表示されることを確認してください。

       ./otel-http-export-demo <http-endpoint>
       ./otel-http-export-demo http://tracing-analysis-dc-hz.aliyuncs.com/adapt_xxxxx_xxxxx/api/otlp/traces
       ./otel-http-export-demo <http-endpoint> yes

gRPC 経由でのデータレポート

  1. プロジェクトディレクトリを作成します。

       mkdir otel-grpc-export-demo
       cd otel-grpc-export-demo
  2. CMakeLists.txt ファイルを作成します。

       cmake_minimum_required(VERSION 3.25.1)
       project(otel-grpc-export-demo)
    
       add_executable(otel-grpc-export-demo grpc_exporter.cc)
    
       find_package(opentelemetry-cpp CONFIG REQUIRED)
       find_package(protobuf)
       find_package(gRPC)
       find_package(CURL)
       find_package(nlohmann_json)
    
       include_directories("${OPENTELEMETRY_CPP_INCLUDE_DIRS}")
    
       target_link_libraries(
           otel-grpc-export-demo ${OPENTELEMETRY_CPP_LIBRARIES}
           opentelemetry_trace
           opentelemetry_common
           opentelemetry_http_client_curl
           opentelemetry_exporter_otlp_http
           opentelemetry_exporter_otlp_grpc
           opentelemetry_exporter_otlp_http_client
           opentelemetry_otlp_recordable
           opentelemetry_resources
       )
  3. grpc_exporter.cc ファイルを作成します。次のプレースホルダーを実際の値に置き換えてください。

    プレースホルダー説明
    <your-service-name>ARMS コンソールでアプリケーションを識別するための名前my-cpp-service
    <your-host-name>アプリケーションを実行しているマシンのホスト名prod-server-01
       // Copyright The OpenTelemetry Authors
       // SPDX-License-Identifier: Apache-2.0
    
       #include "opentelemetry/exporters/otlp/otlp_grpc_exporter_factory.h"
       #include "opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h"
       #include "opentelemetry/context/propagation/global_propagator.h"
       #include "opentelemetry/context/propagation/text_map_propagator.h"
       #include "opentelemetry/exporters/ostream/span_exporter_factory.h"
       #include "opentelemetry/nostd/shared_ptr.h"
       #include "opentelemetry/sdk/trace/simple_processor_factory.h"
       #include "opentelemetry/sdk/trace/tracer_context.h"
       #include "opentelemetry/sdk/trace/tracer_context_factory.h"
       #include "opentelemetry/sdk/trace/tracer_provider_factory.h"
       #include "opentelemetry/trace/propagation/http_trace_context.h"
       #include "opentelemetry/trace/provider.h"
       #include "opentelemetry/ext/http/client/http_client_factory.h"
       #include "opentelemetry/sdk/resource/semantic_conventions.h"
       #include "opentelemetry/sdk/common/global_log_handler.h"
    
       #include <string>
    
    
       namespace trace     = opentelemetry::trace;
       namespace trace_sdk = opentelemetry::sdk::trace;
       namespace otlp      = opentelemetry::exporter::otlp;
       namespace internal_log = opentelemetry::sdk::common::internal_log;
       namespace resource = opentelemetry::sdk::resource;
    
       namespace nostd = opentelemetry::nostd;
    
       namespace
       {
           opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts;
           void InitTracer()
           {
               // 設定されたエンドポイントにスパンを送信する OTLP/gRPC エクスポーターを作成します。
               auto exporter  = otlp::OtlpGrpcExporterFactory::Create(opts);
               // SimpleSpanProcessor は各スパンを即座にエクスポートします。本番環境では、
               // ネットワークのオーバーヘッドを削減するために BatchSpanProcessor の使用を検討してください。
               auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
    
               // ARMS がこのアプリケーションを識別できるようにリソース属性を設定します。
               resource::ResourceAttributes attributes = {
                       {resource::SemanticConventions::kServiceName, "<your-service-name>"},
                       {resource::SemanticConventions::kHostName, "<your-host-name>"}
               };
               auto resource = opentelemetry::sdk::resource::Resource::Create(attributes);
    
               std::shared_ptr<opentelemetry::trace::TracerProvider> provider =
                       trace_sdk::TracerProviderFactory::Create(std::move(processor), std::move(resource));
    
               // グローバルなトレーサープロバイダーとして登録します。
               trace::Provider::SetTracerProvider(provider);
           }
    
           void CleanupTracer()
           {
               std::shared_ptr<opentelemetry::trace::TracerProvider> none;
               trace::Provider::SetTracerProvider(none);
           }
    
           nostd::shared_ptr<trace::Tracer> get_tracer()
           {
               auto provider = trace::Provider::GetTracerProvider();
               return provider->GetTracer("library name to trace", OPENTELEMETRY_SDK_VERSION);
           }
    
           void f1()
           {
               auto scoped_span = trace::Scope(get_tracer()->StartSpan("f1"));
           }
    
           void f2()
           {
               auto scoped_span = trace::Scope(get_tracer()->StartSpan("f2"));
    
               f1();
               f1();
           }
    
           void foo_library()
           {
               auto scoped_span = trace::Scope(get_tracer()->StartSpan("library"));
    
               f2();
           }
       }  // namespace
    
       /*
         使用方法:
         - example_otlp_grpc
         - example_otlp_grpc <URL> <TOKEN>
       */
       int main(int argc, char *argv[])
       {
           if (argc > 1)
           {
               opts.endpoint = argv[1];
               if (argc > 2)
               {
                   opts.metadata.insert(std::pair<std::string, std::string>("authentication",argv[2]));
               }
    
               if (argc > 3)
               {
                   opts.use_ssl_credentials         = true;
                   opts.ssl_credentials_cacert_path = argv[3];
               }
           }
    
           InitTracer();
    
           foo_library();
    
           CleanupTracer();
       }
  4. プロジェクトをビルドします。

       mkdir build && cd build && cmake .. && make
  5. デモを実行します。「前提条件」セクションの gRPC エンドポイントと認証トークンを渡します。例:プログラムがエラーなく終了した場合、スパンはエクスポートされています。「トレースデータの検証」に進み、コンソールに表示されることを確認してください。

       ./otel-grpc-export-demo <gRPC-endpoint> <token>
       ./otel-grpc-export-demo http://tracing-analysis-dc-hz.aliyuncs.com:8090 xxxxx_xxxxxx

トラブルシューティング

共有ライブラリが見つからない場合

デモの実行中に次のエラーが発生した場合:

./otel-grpc-export-demo: error while loading shared libraries: libopentelemetry_proto_grpc.so: cannot open shared object file: No such file or directory

OpenTelemetry C++ SDK のインストールパスをライブラリ検索パスに追加します。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/

/usr/local/lib はデフォルトのインストールパスです。SDK をカスタムパスにインストールした場合は、それに応じてパスを置き換えてください。

トレースデータの検証

  1. ARMS コンソールにログインします。

  2. 左側のナビゲーションウィンドウで、[アプリケーションモニタリング] > [アプリケーション] を選択します。

  3. リストからアプリケーション名を見つけてクリックし、トポロジー、個別のトレース、パフォーマンスメトリクスなどのトレースデータを表示します。

[言語] 列のアイコンはデータソースを示します。language icon アイコンは、アプリケーションがアプリケーションモニタリングに接続されていることを意味します。ハイフン (-) は、OpenTelemetry 向けマネージドサービスに接続されていることを意味します。

本番環境での推奨事項

このガイドのデモコードでは SimpleSpanProcessor を使用しています。これは各スパンを同期的にエクスポートし、呼び出し元のスレッドをブロックします。本番環境のワークロードでは、以下を推奨します。

  • BatchSpanProcessor に切り替えて、スパンをバッチでバッファリングしてエクスポートし、ネットワークのオーバーヘッドとアプリケーションへのレイテンシーの影響を軽減します。

  • ARMS コンソールでトレースをフィルターおよびグループ化できるように、リソース属性 (service.namehost.nameservice.version) に意味のある値を設定します。

  • gRPC エクスポーターの場合、パブリックインターネット経由でトレースデータを送信する際は、SSL (opts.use_ssl_credentials = true) を有効にすることを検討してください。

参考資料