分散トレーシングは、マイクロサービス全体でレイテンシーのボトルネックや障害を特定するのに役立ちます。OpenTelemetry C++ SDK を使用して C++ アプリケーションをインストルメント化することで、HTTP または gRPC 経由で OpenTelemetry 向けマネージドサービスにトレースデータをエクスポートできます。接続が完了すると、ARMS コンソールに、ご利用のアプリケーションのアプリケーショントポロジー、トレース、異常および低速なトランザクション、SQL 分析が表示されます。
仕組み
OpenTelemetry C++ SDK は、3 つのコアコンポーネントを使用してトレースデータを収集し、エクスポートします。
| コンポーネント | 役割 |
|---|---|
| TracerProvider | トレーサーを作成および管理します。各トレーサーは、作業単位を表すスパンを生成します。 |
| SpanProcessor | 完了したスパンを受信し、エクスポーターに転送します。SimpleSpanProcessor は各スパンを即座にエクスポートするため、デモに適しています。本番環境では、スループットを向上させるために BatchSpanProcessor を使用してください。 |
| OTLP エクスポーター | HTTP または gRPC 経由でバックエンドにスパンを送信します。このガイドでは、バックエンドとして OpenTelemetry 向けマネージドサービスを使用します。 |
前提条件
エンドポイントと認証トークンの取得
OpenTelemetry 向けマネージドサービスコンソールにログインします。
左側のナビゲーションウィンドウで、[クラスター設定] をクリックし、[アクセスポイント情報] タブをクリックします。
上部のナビゲーションバーで、リージョンを選択します。[クラスター情報] セクションで、[トークンの表示] をオンにします。
[クライアント] パラメーターを [OpenTelemetry] に設定します。
[関連情報] 列で、ご利用のネットワーク環境に一致するエンドポイントとトークンをコピーします。gRPC の場合は、同じ行に表示される認証トークンもコピーします。
デプロイメント 使用するエンドポイント Alibaba Cloud 上 (ECS、ACK、またはその他の Alibaba Cloud サービス) VPC エンドポイント Alibaba Cloud 外部またはローカル開発 パブリックエンドポイント 
環境要件
C++ 11 以降
サポートされている C++ コンパイラのバージョンとプラットフォームについては、「opentelemetry-cpp supported versions」をご参照ください。
サンプルコード
完全なサンプルコードは alibabacloud-observability/cpp-demo で入手できます。
環境の準備
(任意) GCC ツールチェーンを使用して Docker コンテナを起動します。
docker pull gcc # Debian ベースのイメージ docker run -it --name otel-cpp-demo gcc bashシステム依存関係 (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 経由でのデータレポート
プロジェクトディレクトリを作成します。
mkdir otel-http-export-demo cd otel-http-export-demoCMakeLists.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 )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(); }プロジェクトをビルドします。
mkdir build && cd build && cmake .. && makeデモを実行します。「前提条件」セクションの 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 経由でのデータレポート
プロジェクトディレクトリを作成します。
mkdir otel-grpc-export-demo cd otel-grpc-export-demoCMakeLists.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 )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(); }プロジェクトをビルドします。
mkdir build && cd build && cmake .. && makeデモを実行します。「前提条件」セクションの 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 directoryOpenTelemetry C++ SDK のインストールパスをライブラリ検索パスに追加します。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib//usr/local/lib はデフォルトのインストールパスです。SDK をカスタムパスにインストールした場合は、それに応じてパスを置き換えてください。
トレースデータの検証
ARMS コンソールにログインします。
左側のナビゲーションウィンドウで、[アプリケーションモニタリング] > [アプリケーション] を選択します。
リストからアプリケーション名を見つけてクリックし、トポロジー、個別のトレース、パフォーマンスメトリクスなどのトレースデータを表示します。
[言語] 列のアイコンはデータソースを示します。アイコンは、アプリケーションがアプリケーションモニタリングに接続されていることを意味します。ハイフン (-) は、OpenTelemetry 向けマネージドサービスに接続されていることを意味します。
本番環境での推奨事項
このガイドのデモコードでは SimpleSpanProcessor を使用しています。これは各スパンを同期的にエクスポートし、呼び出し元のスレッドをブロックします。本番環境のワークロードでは、以下を推奨します。
BatchSpanProcessorに切り替えて、スパンをバッチでバッファリングしてエクスポートし、ネットワークのオーバーヘッドとアプリケーションへのレイテンシーの影響を軽減します。ARMS コンソールでトレースをフィルターおよびグループ化できるように、リソース属性 (
service.name、host.name、service.version) に意味のある値を設定します。gRPC エクスポーターの場合、パブリックインターネット経由でトレースデータを送信する際は、SSL (
opts.use_ssl_credentials = true) を有効にすることを検討してください。
アイコンは、アプリケーションがアプリケーションモニタリングに接続されていることを意味します。ハイフン (-) は、OpenTelemetry 向けマネージドサービスに接続されていることを意味します。