このトピックでは、OpenTelemetry SDK for C ++ を使用して、C ++ アプリケーションからSimple Log Serviceにトレースデータをインポートする方法について説明します。
前提条件
トレースインスタンスが作成されます。 詳細については、「トレースインスタンスの作成」をご参照ください。
OpenTelemetry SDK for C ++ をコンパイルして実行できる開発環境を用意します。
CMakeを使用する場合は、CMakeのバージョンが3.1以降であることを確認してください。
GCCまたはG ++ を使用する場合は、GCCまたはG ++ のバージョンが4.8以降であることを確認してください。
MSVCを使用する場合は、MSVCのバージョンがVS2015以降であることを確認してください。 VS2019の使用を推奨します。
次のC ++ バージョンがサポートされています。
ISO/IEC 14882:2011 (C ++ 11、C ++ 0x)
ISO/IEC 14882:2014 (C ++ 14、C ++ 1y)
ISO/IEC 14882:2017 (C ++ 17、C ++ 1z)
ISO/IEC 14882:2020 (C ++ 20)
依存関係とバージョンの詳細については、「opentelemetry-cpp」をご参照ください。
ステップ1: SDKの統合
ソースコードまたはパッケージマネージャーを使用してSDKを統合できます。 詳細については、「opentelemetry-cppのインストール」をご参照ください。
ソースコードを使用してSDKを統合し、SDKを独立したCMakeプロジェクトとしてコンパイルする
前提条件
コンパイルは、Windows、macOS、およびLinuxでサポートされています。
C ++ 11以降をサポートするC ++ コンパイラがインストールされています。
Gitがインストールされています。
CMakeがインストールされています。
GoogleTestがインストールされています。
Google Benchmarkがインストールされています。
手順
opentelemetry-cppソースコードを取得します。
$ cd <your-path> $ git clone --recurse-submodules https://github.com/open-telemetry/opentelemetry-cppCMakeビルド構成を作成します。
$ cd opentelemetry-cpp $ mkdir build && cd build && cmake ..CMakeターゲットを構築します。
$ cmake --build . --target allAPIヘッダーファイルをインストールします。
$ cmake --install . --prefix /<install-root>/
ソースコードを使用してSDKをCMakeプロジェクトに統合する
前提条件
コンパイルは、Windows、macOS、およびLinuxでサポートされています。
C ++ 11以降をサポートするC ++ コンパイラがインストールされています。
Gitがインストールされています。
CMakeがインストールされています。
GoogleTestがインストールされています。
Google Benchmarkがインストールされています。
サンプルコード
# CMakeLists.txt
find_package(opentelemetry-cpp CONFIG REQUIRED)
...
target_include_directories(foo PRIVATE ${OPENTELEMETRY_CPP_INCLUDE_DIRS})
target_link_libraries(foo PRIVATE ${OPENTELEMETRY_CPP_LIBRARIES})パッケージマネージャーを使用してSDKを統合する
パッケージマネージャーを使用してSDKを統合する方法の詳細については、「パッケージマネージャーの使用」をご参照ください。
ステップ2: SDKの初期化
OpenTelemetry SDK for C ++ は、SDKを初期化した後にのみ使用できます。 次のサンプルコードは、SDKを初期化する方法の例を示しています。
// Import the following header files:
#include "opentelemetry/exporters/otlp/otlp_grpc_exporter_factory.h"
#include "opentelemetry/sdk/trace/simple_processor_factory.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/sdk/version/version.h"
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/sdk/resource/resource.h"
#include "opentelemetry/sdk/resource/semantic_conventions.h"
namespace trace = opentelemetry::trace;
namespace trace_sdk = opentelemetry::sdk::trace;
namespace otlp = opentelemetry::exporter::otlp;
namespace resource = opentelemetry::sdk::resource;
namespace
{
// Initialize the exporter. The exporter is used to export trace data to a Simple Log Service Logstore.
opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts;
void InitTracer()
{
opts.endpoint = "https://${endpoint}";
opts.use_ssl_credentials = true;
opts.ssl_credentials_cacert_path = "<your root pem file path>"; // Specify the directory in which the root .pem file is stored. In most cases, the root .pem file is stored in the directory of the gRPC dependency library.
// Setup credentials info
opts.metadata.insert(std::pair<std::string, std::string>("x-sls-otel-project", "${project}"));
opts.metadata.insert(std::pair<std::string, std::string>("x-sls-otel-instance-id", "${instanceId}"));
opts.metadata.insert(std::pair<std::string, std::string>("x-sls-otel-ak-id", "${access-key-id}"));
opts.metadata.insert(std::pair<std::string, std::string>("x-sls-otel-ak-secret", "${access-key-secret}"));
// Create OTLP exporter instance
auto exporter = otlp::OtlpGrpcExporterFactory::Create(opts);
auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
// Initialize the tracer provider. The tracer provider is used to expose major API operations and preprocess spans.
// Configure the custom rules that are used to generate trace IDs and span IDs and configure custom samplers. You can configure the settings based on your business requirements.
resource::ResourceAttributes attributes = {
{resource::SemanticConventions::kServiceName, "${service}"}, // Generally, set the value to the name of the submodule.
{resource::SemanticConventions::kServiceNamespace, "${service.namespace}"}, // Generally, set the value to the name of the module or app.
{resource::SemanticConventions::kServiceVersion, "${version}"}, // Generally, set the value to the version number of the module or app.
{resource::SemanticConventions::kHostName, "${host}"},
{resource::SemanticConventions::kDeploymentEnvironment, "${environment}"}
};
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));
// Set the global trace provider
trace::Provider::SetTracerProvider(provider);
}
void CleanupTracer()
{
// We call ForceFlush to prevent to cancel running exportings, It's optional.
opentelemetry::nostd::shared_ptr<opentelemetry::trace::TracerProvider> provider =
trace::Provider::GetTracerProvider();
if (provider)
{
static_cast<trace_sdk::TracerProvider*>(provider.get())->ForceFlush();
}
std::shared_ptr<opentelemetry::trace::TracerProvider> none;
trace::Provider::SetTracerProvider(none);
}
} // namespace変数 | 説明 | 例 |
| Simple Log Serviceプロジェクトのエンドポイント。 形式:
| test-project.cn-hangzhou.log.aliyuncs.com:10010 |
| Simple Log Serviceプロジェクトの名前。 | test-project |
| トレースインスタンスのID。 詳細については、「トレースインスタンスの作成」をご参照ください。 | テストトレース |
| Alibaba CloudアカウントのAccessKey ID。 重要 Simple Log Serviceプロジェクトの書き込み権限のみを持つResource Access Management (RAM) ユーザーのAccessKeyペアを使用することを推奨します。 AccessKey ペアは、AccessKey ID と AccessKey Secret で構成されます。 指定したプロジェクトの書き込み権限をRAMユーザーに付与する方法の詳細については、「カスタムポリシーを使用してRAMユーザーに権限を付与する」をご参照ください。 AccessKeyペアを取得する方法の詳細については、「AcessKeyペア」をご参照ください。 | なし |
| Alibaba CloudアカウントのAccessKeyシークレット。 重要 Simple Log Serviceプロジェクトに対する書き込み権限のみを持つRAMユーザーのAccessKeyペアを使用することを推奨します。 | なし |
| サービスが属する名前空間。 | order |
| サービスの名前です。 ビジネス要件に基づいて値を指定します。 | payment |
| サービスのバージョンです。 va.b.c形式でバージョンを指定することを推奨します。 | v0.1.2 |
| ホスト名。 | localhost |
| デプロイ環境。 例: テスト環境または本番環境。 ビジネス要件に基づいて値を指定します。 | 前 |
ステップ3: SDKの使用
トレーサーの作成
ビジネスシナリオに基づいてトレーサーを作成することを推奨します。 トレーサーを作成するときは、ライブラリ名を指定する必要があります。 これにより、ライブラリごとにトレースデータを区別できます。
namespace trace = opentelemetry::trace;
namespace nostd = opentelemetry::nostd;
namespace
{
nostd::shared_ptr<trace::Tracer> get_tracer()
{
auto provider = trace::Provider::GetTracerProvider();
return provider->GetTracer("<your library name>", OPENTELEMETRY_SDK_VERSION);
}
} // namespace基本スパンの作成
スパンは、トランザクションにおけるオペレーションを指定する。 各スパンは、操作名、開始タイムスタンプおよび終了タイムスタンプ、属性、イベント、およびコンテキストをカプセル化します。
auto span = get_tracer()->StartSpan("basic_f1");
// do your stuff
// ...
span->End();ネストされたスパンの作成
ネストされた操作で作業をトレースするためのネストされたスパンを作成する場合は、OpenTelemetryを使用して、オンプレミスプロセスおよびリモートプロセス間の操作スレッドをトレースできます。 以下の例では、メソッドAはメソッドBを呼び出す。次の例に基づいて、ネストされたスパンを作成できます。
void method_a()
{
auto span = get_tracer()->StartSpan("operation A");
auto scope = get_tracer()->WithActiveSpan(span);
method_b();
span->End();
}
void method_b()
{
auto span_child = get_tracer()->StartSpan("operation B");
// do your stuff
// ...
span_child->End();
}OpenTelemetry APIは、親スパンを伝播する自動化メソッドを提供します。
void method_a()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("operation A"));
method_b();
}
void method_b()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("operation B"));
}属性で注釈を付けたスパンの作成
属性を指定することで、スパン内の特定の操作のコンテキストを指定できます。 たとえば、実行結果と関連するビジネス情報を提供できます。
auto span = get_tracer()->StartSpan("<my operation>");
span->SetAttribute("age", 12);
span->SetAttribute("sex", "man");
// do your stuff
// ...
span->SetAttribute("height", 154.5);
span->End();イベントで注釈を付けたスパンの作成
複数のイベントを使用してスパンに注釈を付けることができます。
auto span = get_tracer()->StartSpan("<my operation>");
// do your stuff
// ...
span->AddEvent("message: success");
span->End();スパンの状態の指定
スパンには、trace::StatusCode::kUnset、trace::StatusCode::kOk、trace::StatusCode::kErrorのいずれかの状態を指定できます。 trace::StatusCode::kUnsetはデフォルトの状態を示します。 trace::StatusCode::kOkは、操作が成功したことを示します。 trace::StatusCode::kErrorは、操作でエラーが発生したことを示します。
auto span = get_tracer()->StartSpan("<my operation>");
// do your stuff
// ...
span->SetStatus(trace::StatusCode::kError);
span->End();コンテキストの伝播
OpenTelemetryは、コンテキストを伝播するテキストベースのメソッドを提供します。
#include "opentelemetry/trace/context.h"
#include "opentelemetry/context/propagation/global_propagator.h"
#include "opentelemetry/context/propagation/text_map_propagator.h"
#include "opentelemetry/trace/propagation/http_trace_context.h"
#include "opentelemetry/nostd/shared_ptr.h"
// Use HttpTraceContext to demonstrate the basic usage of context propagation.
// Configure global propagator during SDK initialization.
opentelemetry::context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
opentelemetry::nostd::shared_ptr<opentelemetry::context::propagation::TextMapPropagator>(
new opentelemetry::trace::propagation::HttpTraceContext()));
// Inject the header information when a network request is initiated on the client side.
opentelemetry::context::propagation::TextMapCarrier carrier; // Replace the value with your TextMapCarrier.
auto propagator = opentelemetry::context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
// Inject the header information.
auto current_ctx = opentelemetry::context::RuntimeContext::GetCurrent();
propagator->Inject(carrier, current_ctx);
// Extract the header information on the server side.
auto current_ctx = opentelemetry::context::RuntimeContext::GetCurrent();
auto new_context = propagator->Extract(carrier, current_ctx);
auto remote_span = opentelemetry::trace::GetSpan(new_context);OpenTelemetry SDKは、W3Cトレースコンテキスト仕様に準拠したコンテキスト伝播をサポートします。 詳細については、「W3CTraceContextPropagatorクラス」をご参照ください。
OpenTelemetry SDKの詳細については、「公式ドキュメント」をご参照ください。