サンプルによる入門
このページでは、C++ で OpenTelemetry を始める方法を紹介します。
シンプルな C++ アプリケーションを計装する方法を学び、トレースがターミナルに出力されるようにします。
前提条件
以下がローカルにインストールされていることを確認してください。
- Git
- C++ バージョン14以上をサポートする C++ コンパイラー
- Make
- CMake バージョン3.25以上
アプリケーション例
次の例では、基本的な Oat++ アプリケーションを使用します。 Oat++ を使用していなくても問題ありません。OpenTelemetry C++ は他のどのウェブフレームワークでも使用できます。
セットアップ
otel-cpp-starterという名前のフォルダーを作成します。新しく作成したフォルダーに移動します。 ここが作業ディレクトリになります。
依存関係のセットアップ後、ディレクトリ構造は次のようになります。
otel-cpp-starter │ ├── oatpp ├── opentelemetry-cpp └── roll-dice
依存関係
まず、ソースコードと make を使用して、次の手順で Oat++ をローカルにインストールします。
oatpp/oatpp GitHub リポジトリからクローンして、Oat++ のソースコードを取得します。
git clone https://github.com/oatpp/oatpp.gitoatppディレクトリに移動し、当面は1.3.0バージョンに切り替えます。cd oatpp git checkout 1.3.0-latestbuildサブディレクトリを作成し、その中に移動します。mkdir build cd buildcmakeとmakeコマンドを使用して oatpp をビルドします。 このコマンドは、oatpp のソースコードに含まれるCMakeLists.txtで指定されたビルドプロセスを実行します。cmake .. makeoatpp をローカル接頭辞にインストールします。 このコマンドは、ビルドした oatpp ライブラリ、ヘッダー、CMake パッケージ設定を
installディレクトリにインストールし、開発で利用できるようにします。cmake --install . --prefix ../../install
次に、CMake を使用して OpenTelemetry C++ をローカルにインストールしてビルドします。 手順は以下のとおりです。
ターミナルで
otel-cpp-starterディレクトリに戻ります。 次に、OpenTelemetry C++ の GitHub リポジトリをローカルマシンにクローンします。git clone https://github.com/open-telemetry/opentelemetry-cpp.git作業ディレクトリを OpenTelemetry C++ SDK のディレクトリに変更します。
cd opentelemetry-cppビルドディレクトリを作成し、その中に移動します。
mkdir build cd buildbuildディレクトリで CMake を実行し、テストを無効にしてビルドシステムを構成・生成します。cmake -DBUILD_TESTING=OFF ..または、
cmake --buildが失敗した場合は、次のコマンドも試せます。cmake -DBUILD_TESTING=OFF -DWITH_ABSEIL=ON ..ビルドプロセスを実行します。
cmake --build .OpenTelemetry C++ を oatpp と同じローカル接頭辞にインストールします。
cmake --install . --prefix ../../install
Oat++ と OpenTelemetry C++ の準備ができたら、最終的に計装する HTTP サーバーの作成に進みます。
HTTP サーバーの作成と起動
otel-cpp-starter フォルダー内に roll-dice サブフォルダーを作成します。
ここで Oat++ ライブラリを使用するために、oatpp のヘッダーを参照し、プロジェクトのコンパイル時にリンクします。
roll-dice 内に CMakeLists.txt というファイルを作成して、Oat++ ライブラリのディレクトリ、インクルードパス、コンパイル時のリンクを定義します。
cmake_minimum_required(VERSION 3.25)
project(RollDiceServer)
# C++ 標準を設定する(例: C++17)
set(CMAKE_CXX_STANDARD 17)
set(project_name roll-dice-server)
# プロジェクトのソースファイルを定義する
set(SOURCES
main.cpp # ここにソースファイルを追加する
)
# 実行可能ターゲットを作成する
add_executable(dice-server ${SOURCES})
find_package(oatpp REQUIRED)
target_link_libraries(dice-server PRIVATE oatpp::oatpp)
次に、サンプル HTTP サーバーのソースコードが必要です。 このコードは以下を行います。
- HTTP ルーターを初期化し、
/rolldiceエンドポイントへの GET リクエストに対してランダムな数値をレスポンスとして生成するリクエストハンドラーを設定します。 - 次に、コネクションハンドラー、コネクションプロバイダーを作成し、http://localhost:8080 でサーバーを起動します。
- 最後に、main 関数内でアプリケーションを初期化して実行します。
roll-dice フォルダー内に main.cpp というファイルを作成し、次のコードを追加します。
#include "oatpp/web/server/HttpConnectionHandler.hpp"
#include "oatpp/network/Server.hpp"
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
class Handler : public oatpp::web::server::HttpRequestHandler {
public:
shared_ptr<OutgoingResponse> handle(const shared_ptr<IncomingRequest>& request) override {
int low = 1;
int high = 7;
int random = rand() % (high - low) + low;
// std::string を oatpp::String に変換する
const string response = to_string(random);
return ResponseFactory::createResponse(Status::CODE_200, response.c_str());
}
};
void run() {
auto router = oatpp::web::server::HttpRouter::createShared();
router->route("GET", "/rolldice", std::make_shared<Handler>());
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
auto connectionProvider = oatpp::network::tcp::server::ConnectionProvider::createShared({"localhost", 8080, oatpp::network::Address::IP_4});
oatpp::network::Server server(connectionProvider, connectionHandler);
OATPP_LOGI("Dice Server", "Server running on port %s", static_cast<const char*>(connectionProvider->getProperty("port").getData()));
server.run();
}
int main() {
oatpp::base::Environment::init();
srand((int)time(0));
run();
oatpp::base::Environment::destroy();
return 0;
}
以下の CMake コマンドでアプリケーションをビルドして実行します。
mkdir build
cd build
cmake .. -DCMAKE_PREFIX_PATH=$(pwd)/../../install
cmake --build .
プロジェクトのビルドが成功したら、生成された実行ファイルを実行できます。
./dice-server
次に、ブラウザーで http://localhost:8080/rolldice を開いて、正常に動作していることを確認します。
計装
アプリケーションに OpenTelemetry を追加するために、CMakeLists.txt ファイルを以下の追加の依存関係で更新します。
cmake_minimum_required(VERSION 3.25)
project(RollDiceServer)
# C++ 標準を設定する(例: C++17)
set(CMAKE_CXX_STANDARD 17)
set(project_name roll-dice-server)
# プロジェクトのソースファイルを定義する
set(SOURCES
main.cpp # ここにソースファイルを追加する
)
# 実行可能ターゲットを作成する
add_executable(dice-server ${SOURCES})
find_package(oatpp REQUIRED)
find_package(opentelemetry-cpp CONFIG REQUIRED)
target_link_libraries(dice-server PRIVATE
oatpp::oatpp
${OPENTELEMETRY_CPP_LIBRARIES})
main.cpp ファイルを次のコードで更新して、トレーサーを初期化し、/rolldice リクエストハンドラーが呼ばれたときにスパンを出力するようにします。
#include "oatpp/web/server/HttpConnectionHandler.hpp"
#include "oatpp/network/Server.hpp"
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
#include "opentelemetry/exporters/ostream/span_exporter_factory.h"
#include "opentelemetry/sdk/trace/exporter.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/simple_processor_factory.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"
#include "opentelemetry/trace/provider.h"
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
namespace trace_api = opentelemetry::trace;
namespace trace_sdk = opentelemetry::sdk::trace;
namespace trace_exporter = opentelemetry::exporter::trace;
namespace {
void InitTracer() {
auto exporter = trace_exporter::OStreamSpanExporterFactory::Create();
auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
std::shared_ptr<opentelemetry::trace::TracerProvider> provider =
trace_sdk::TracerProviderFactory::Create(std::move(processor));
// グローバルトレースプロバイダーを設定する
trace_api::Provider::SetTracerProvider(provider);
}
void CleanupTracer() {
std::shared_ptr<opentelemetry::trace::TracerProvider> none;
trace_api::Provider::SetTracerProvider(none);
}
}
class Handler : public oatpp::web::server::HttpRequestHandler {
public:
shared_ptr<OutgoingResponse> handle(const shared_ptr<IncomingRequest>& request) override {
auto tracer = opentelemetry::trace::Provider::GetTracerProvider()->GetTracer("my-app-tracer");
auto span = tracer->StartSpan("RollDiceServer");
int low = 1;
int high = 7;
int random = rand() % (high - low) + low;
// std::string を oatpp::String に変換する
const string response = to_string(random);
span->End();
return ResponseFactory::createResponse(Status::CODE_200, response.c_str());
}
};
void run() {
auto router = oatpp::web::server::HttpRouter::createShared();
router->route("GET", "/rolldice", std::make_shared<Handler>());
auto connectionHandler = oatpp::web::server::HttpConnectionHandler::createShared(router);
auto connectionProvider = oatpp::network::tcp::server::ConnectionProvider::createShared({"localhost", 8080, oatpp::network::Address::IP_4});
oatpp::network::Server server(connectionProvider, connectionHandler);
OATPP_LOGI("Dice Server", "Server running on port %s", static_cast<const char*>(connectionProvider->getProperty("port").getData()));
server.run();
}
int main() {
oatpp::base::Environment::init();
InitTracer();
srand((int)time(0));
run();
oatpp::base::Environment::destroy();
CleanupTracer();
return 0;
}
プロジェクトを再びビルドします。
cd build
cmake .. -DCMAKE_PREFIX_PATH=$(pwd)/../../install
cmake --build .
プロジェクトのビルドが成功したら、生成された実行ファイルを実行できます。
./dice-server
http://localhost:8080/rolldice にリクエストを送ると、ターミナルにスパンが出力されます。
{
"name" : "RollDiceServer",
"trace_id": "f47bea385dc55e4d17470d51f9d3130b",
"span_id": "deed994b51f970fa",
"tracestate" : ,
"parent_span_id": "0000000000000000",
"start": 1698991818716461000,
"duration": 64697,
"span kind": "Internal",
"status": "Unset",
"service.name": "unknown_service",
"telemetry.sdk.language": "cpp",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.11.0",
"instr-lib": "my-app-tracer"
}
次のステップ
コードの計装についての詳細は、計装のドキュメントを参照してください。
また、テレメトリーデータを1つまたは複数のテレメトリーバックエンドにエクスポートするために、適切なエクスポーターを設定することも必要です。
フィードバック
このページは役に立ちましたか?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!