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

Managed Service for OpenTelemetry:OpenTelemetry を使用して C++ アプリケーションのトレースデータをレポートする

最終更新日:Dec 30, 2024

OpenTelemetry を使用してアプリケーションをインストルメントし、トレースデータを Managed Service for OpenTelemetry にレポートすると、Managed Service for OpenTelemetry はアプリケーションの監視を開始します。アプリケーショントポロジー、トレース、異常トランザクション、低速トランザクション、SQL分析などのアプリケーションの監視データを表示できます。このトピックでは、OpenTelemetry SDK for C++ を使用して C++ アプリケーションをインストルメントし、C++ アプリケーションのトレースデータをレポートする方法について説明します。

前提条件

Managed Service for OpenTelemetry のエンドポイントを取得するには、次の手順を実行します。

  1. Managed Service for OpenTelemetry コンソール にログインします。

  2. 左側のナビゲーションペインで、Cluster Configurations をクリックします。表示されるページで、Access point information タブをクリックします。

  3. 上部のナビゲーションバーで、リージョンを選択します。Cluster Information セクションで、Show Token をオンにします。

  4. Client パラメーターを OpenTelemetry に設定します。

    下部の表の Related Information 列に、Managed Service for OpenTelemetry のエンドポイントが表示されます。OT接入点信息

    説明

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

サンプルコード

cpp-demo ページでサンプルコードをダウンロードします。

環境要件

  • C++ 11 以降がインストールされていること。

  • サポートされている C++ のバージョンと開発プラットフォームは、opentelemetry-cpp ページで確認できます。

手順 1: 環境を準備する

  1. オプション。 C++ 環境で 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

手順 2: OpenTelemetry C++ ライブラリのインストール

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

# OpenTelemetry C++ ライブラリを /usr/local パスにインストールします。OpenTelemetry C++ ライブラリはこのパスにインストールすることをお勧めします。
cmake --install . 

# OpenTelemetry C++ ライブラリを指定したパスにインストールします。
# cmake --install . --prefix /opentelemetry-cpp-lib

ステップ 3: プロジェクトで OpenTelemetry C++ ライブラリを使用する

HTTP 経由でデータをレポートする

  1. プロジェクトを作成します。

    mkdir otel-http-export-demo
    cd otel otel-http-export-demo
  2. プロジェクトに CMakeLists.txt ファイルを作成します。

    cmake_minimum_required(VERSION 3.25.1) # CMake のバージョン。
    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(
        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 ファイルが 1 つだけ含まれています。

    ${ServiceName} をアプリケーション名に、${HostName} をホスト名に置き換えます。

    // 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()
        {
            // OpenTelemetry Protocol (OTLP) エクスポーターを作成します。
            auto exporter  = otlp::OtlpHttpExporterFactory::Create(opts);
            auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
    
            resource::ResourceAttributes attributes = {
                    {resource::SemanticConventions::kServiceName, "${ServiceName}"}, // アプリケーション名。
                    {resource::SemanticConventions::kHostName, "${HostName}"} // ホスト名
            };
            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. プロジェクトを実行します。

    ./otel-http-export-demo ${http-endpoint}

    ${http-endpoint} を「前提条件」セクションで取得した HTTP エンドポイントに置き換えます。

    例:

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

gRPC 経由でデータをレポートする

  1. プロジェクトを作成します。

    mkdir otel-grpc-export-demo
    cd otel otel-grpc-export-demo
  2. プロジェクトに CMakeLists.txt ファイルを作成します。

    cmake_minimum_required(VERSION 3.25.1) # CMake のバージョン
    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 ファイルが 1 つだけ含まれています。

    ${ServiceName} をアプリケーション名に、${HostName} をホスト名に置き換えます。

    // 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 エクスポーターを作成します。
            auto exporter  = otlp::OtlpGrpcExporterFactory::Create(opts);
            auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
    
            resource::ResourceAttributes attributes = {
                    {resource::SemanticConventions::kServiceName, "${ServiceName} "}, // アプリケーション名
                    {resource::SemanticConventions::kHostName, "${HostName}"} // ホスト名
            };
            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. プロジェクトを実行します。

    ./otel-grpc-export-demo ${gRPC-endpoint} ${token}

    ${gRPC-endpoint}${token} を、「前提条件」セクションで取得した gRPC エンドポイントと認証トークンに置き換えます。

    例:

    ./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

次のコマンドを実行して、環境変数を変更します。

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

/usr/local/lib は、opentelemetry-cpp デモがインストールされているパスを示します。

監視データを表示する

Applications ページで、Managed Service for OpenTelemetry コンソールアプリケーションの名前をクリックします。表示されるページで、トレースデータを表示します。