Opentelemetry-Language APIs & SDKs-C++-Getting Started

2024-05-24 19:22:38 浏览数 (2)

大纲

  • *Getting Started*
    • *Prerequisites*
    • *Example Application*
    • *Setup*
    • *Dependencies*
    • *Create and launch an HTTP Server*
    • *Instrumentation*
    • *Next Steps*

Getting Started

入门

Get telemetry for your app in less than 5 minutes! 不到 5 分钟即可获取您的应用程序的遥测数据!

This page will show you how to get started with OpenTelemetry in C . 本页将向您展示如何开始使用 C 中的 OpenTelemetry。

You will learn how to instrument a simple C application, such that traces are emitted to the terminal. 您将学习如何检测简单的 C 应用程序,以便将Trace发送到终端。

Prerequisites

先决条件

Ensure that you have the following installed locally: 确保您已在本地安装以下软件:

  • Git
  • C compiler supporting C version >= 14
  • Make
  • CMake version >= 3.20

Example Application

应用示例

The following example uses a basic Oat application. If you are not using Oat , that’s OK - you can use OpenTelemetry C with any other web framework as well. 以下示例使用基本的Oat 应用程序。如果您不使用 Oat ,那也没关系 - 您也可以将 OpenTelemetry C 与任何其他 Web 框架一起使用。

Setup

  • Create a folder named otel-cpp-starter. 创建一个名为 的文件夹otel-cpp-starter。
  • move into the newly created folder. This will serve as your working directory. 移动到新创建的文件夹中。这将作为您的工作目录。
  • After setting up dependencies, your directory structure should resemble this: 设置依赖项后,您的目录结构应类似于以下内容:

otel-cpp-starter │ ├── oatpp ├── opentelemetry-cpp └── roll-dice

Dependencies

依赖关系

To begin, install Oat locally using the source code and make, following these steps: 首先,按照以下步骤在本地下载和使用 Oat 源代码:

  1. Obtain the Oat source code by cloning from the oatpp/oatpp  GitHub repository. 通过从GitHub的oatpp/oatpp 存储库克隆来获取 Oat 源代码 。
代码语言:javascript复制
git clone https://github.com/oatpp/oatpp.git
  1. Navigate to the oatpp directory. 进入oatpp目录。
代码语言:javascript复制
cd oatpp
  1. Create a build subdirectory and navigate into it. 创建一个build子目录并进入其中。
代码语言:javascript复制
mkdir build
cd build
  1. Build oatpp using the cmake and make commands. This command will trigger the build process specified in the CMakeLists.txt included in the oatpp source code. 使用cmake和make命令构建 oatpp。该命令将触发toatpp源代码中CMakeLists.tx指定的构建过程。
代码语言:javascript复制
cmake ..
make
  1. Install oatpp. 安装oatpp。

This command will install the built oatpp library and headers on your system, making it accessible for development in your project. 此命令将在您的系统上安装构建的oatpp库和头文件,使其可以在您的项目中进行开发。

代码语言:javascript复制
sudo make install

To uninstall the built oatpp library and headers from your system. 从系统中卸载内置的oatpp库和头文件。

代码语言:javascript复制
sudo make uninstall

Next, install and build OpenTelemetry C locally using CMake, following these steps: 接下来,使用CMake在本地安装并构建OpenTelemetry C ,步骤如下:

  1. In your terminal, navigate back to the otel-cpp-starter directory. Then, clone the OpenTelemetry C GitHub repository to your local machine. 在您的终端中,切换到otel-cpp-starter目录。然后,将GitHub中的OpenTelemetry C 存储库克隆到本地计算机。
代码语言:javascript复制
git clone https://github.com/open-telemetry/opentelemetry-cpp.git
  1. Change your working directory to the OpenTelemetry C SDK directory. 将工作目录更改为 OpenTelemetry C SDK 目录。
代码语言:javascript复制
cd opentelemetry-cpp
  1. Create a build directory and navigate into it. 创建build目录并切换到其中。
代码语言:javascript复制
mkdir build
cd build
  1. In the build directory run CMake, to configure and generate the build system. 在build目录中运行CMake,配置并生成构建系统
代码语言:javascript复制
cmake ..

Or, if the cmake --build fails, you can also try: 或者,如果cmake --build失败,您也可以尝试:

代码语言:javascript复制
cmake -DWITH_ABSEIL=ON ..
  1. Execute the build process. 执行构建过程。
代码语言:javascript复制
cmake --build .

With Oat and OpenTelemetry C ready, you can continue with creating the HTTP Server, that we want to instrument eventually. 准备好Oat 和OpenTelemetry C 后,您可以继续创建我们最终想要测量的HTTP服务器。

Create and launch an HTTP Server

创建并启动HTTP服务器

In your otel-cpp-starter folder, create a subfolder roll-dice, where the Oat library will be used by referencing the oatpp headers and linking them when compiling your project. 在您的otel-cpp-starter文件夹中,创建一个子文件夹roll-dice,其中将通过引用oatpp头文件,并在编译项目时链接它们来使用Oat 库。

Create a file called CMakeLists.txt to define the Oat library directories, include paths, and link against Oat during the compilation process. 创建一个名为CMakeLists.txt的文件,用于定义Oat 库目录、包含路径,并在编译过程中链接到Oat 。

代码语言:javascript复制
project(RollDiceServer)
cmake_minimum_required(VERSION 3.1)
# Set C   standard (e.g., C  17)
set(CMAKE_CXX_STANDARD 17)
set(project_name roll-dice-server)

# Define your project's source files
set(SOURCES
    main.cpp  # Add your source files here
)

# Create an executable target
add_executable(dice-server ${SOURCES})

set(OATPP_ROOT ../oatpp)
find_library(OATPP_LIB NAMES liboatpp.a HINTS "${OATPP_ROOT}/build/src/" NO_DEFAULT_PATH)

if (NOT OATPP_LIB)
  message(SEND_ERROR "Did not find oatpp library ${OATPP_ROOT}/build/src")
endif()
#set the path to the directory containing "oatpp" package configuration files
include_directories(${OATPP_ROOT}/src)
target_link_libraries(dice-server PRIVATE ${OATPP_LIB})

Next, the sample HTTP server source code is needed. It will do the following: 接下来,需要编写示例HTTP服务器源代码。它将执行以下操作:

  • Initialize an HTTP router and set up a request handler to generate a random number as the response when a GET request is made to the /rolldice endpoint. 初始化HTTP路由器并设置请求处理程序,以在向端点发出GET请求时生成随机数作为响应/rolldice。
  • Next, create a connection handler, a connection provider, and start the server on localhost:8080. 接下来,创建一个连接处理程序、一个连接提供程序,并在localhost:8080上启动服务器。
  • Lastly, initialize and run the application within the main function. 最后,在主函数中初始化并运行应用程序。

In that roll-dice folder, create a file called main.cpp and add the following code to the file. 在该roll-dice文件夹中,创建一个名为main.cpp的文件,并将以下代码添加到该文件中。

代码语言:javascript复制
#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;
    // Convert a std::string to 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", connectionProvider->getProperty("port").getData());
  server.run();
}

int main() {
  oatpp::base::Environment::init();
  srand((int)time(0));
  run();
  oatpp::base::Environment::destroy();
  return 0;
}

Build and run the application with the following CMake commands. 使用以下CMake命令构建并运行应用程序。

代码语言:javascript复制
mkdir build
cd build
cmake ..
cmake --build .

After successfully building your project, you can run the generated executable. 成功构建项目后,您可以运行生成的可执行文件。

代码语言:javascript复制
./dice-server

Then, open http://localhost:8080/rolldice in your browser to ensure it is working. 然后,在浏览器中打开http://localhost:8080/rolldice以确保其正常工作。

Instrumentation

测量装置

To add OpenTelemetry to your application, update the CMakeLists.txt file with the following additional dependencies. 要将OpenTelemetry添加到您的应用程序,请让CMakeLists.txt使用以下附加依赖项,并更新文件。

代码语言:javascript复制
project(RollDiceServer)
cmake_minimum_required(VERSION 3.1)
# Set C   standard (e.g., C  17)
set(CMAKE_CXX_STANDARD 17)
set(project_name roll-dice-server)

# Define your project's source files
set(SOURCES
    main.cpp  # Add your source files here
)
# Create an executable target
add_executable(dice-server ${SOURCES})

set(OATPP_ROOT ../oatpp)
set(OPENTELEMETRY_ROOT ../opentelemetry-cpp)
find_library(OATPP_LIB NAMES liboatpp.a HINTS "${OATPP_ROOT}/build/src/" NO_DEFAULT_PATH)
if (NOT OATPP_LIB)
  message(SEND_ERROR "Did not find oatpp library ${OATPP_ROOT}/build/src")
endif()
# set the path to the directory containing "oatpp" package configuration files
include_directories(${OATPP_ROOT}/src)

include_directories(${OPENTELEMETRY_ROOT}/api/include)
include_directories(${OPENTELEMETRY_ROOT}/sdk/include)
include_directories(${OPENTELEMETRY_ROOT}/sdk/src)
include_directories(${OPENTELEMETRY_ROOT}/exporters/ostream/include)

find_library(OPENTELEMETRY_COMMON_LIB NAMES libopentelemetry_common.a HINTS "${OPENTELEMETRY_ROOT}/build/sdk/src/common" NO_DEFAULT_PATH)
find_library(OPENTELEMETRY_TRACE_LIB NAMES libopentelemetry_trace.a HINTS "${OPENTELEMETRY_ROOT}/build/sdk/src/trace" NO_DEFAULT_PATH)
find_library(OPENTELEMETRY_EXPORTER_LIB NAMES libopentelemetry_exporter_ostream_span.a HINTS "${OPENTELEMETRY_ROOT}/build/exporters/ostream" NO_DEFAULT_PATH)
find_library(OPENTELEMETRY_RESOURCE_LIB NAMES libopentelemetry_resources.a HINTS "${OPENTELEMETRY_ROOT}/build/sdk/src/resource" NO_DEFAULT_PATH)

if(OPENTELEMETRY_COMMON_LIB AND OPENTELEMETRY_TRACE_LIB AND OPENTELEMETRY_EXPORTER_LIB AND OPENTELEMETRY_RESOURCE_LIB)
  message(STATUS "Found opentelemetry libraries")
else()
  message(SEND_ERROR "Did not find opentelemetry libraries")
endif()

target_link_libraries(dice-server PRIVATE ${OATPP_LIB} ${OPENTELEMETRY_COMMON_LIB} ${OPENTELEMETRY_TRACE_LIB} ${OPENTELEMETRY_EXPORTER_LIB} ${OPENTELEMETRY_RESOURCE_LIB})

Update the main.cpp file with the following code to initialize a tracer and to emit spans when the /rolldice request handler is called. main.cpp使用以下代码更新文件,以初始化Tracer,并在程序处理/rolldice调用请求时发出Span。

代码语言:javascript复制
#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));
    //set the global trace provider
    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;
    // Convert a std::string to 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", 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;
}

Build your project again. 再次构建您的项目。

代码语言:javascript复制
cd build
cmake ..
cmake --build .

After successfully building your project, you can run the generated executable. 成功构建项目后,您可以运行生成的可执行文件。

代码语言:javascript复制
./dice-server

When you send a request to the server at http://localhost:8080/rolldice , you will see a span being emitted to the terminal. 当您向http://localhost:8080/rolldice的服务器发送请求时,您将看到一个Span被发送到终端

代码语言:javascript复制
{
  "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"
}

Next Steps

For more information about instrumenting your code, refer the instrumentation documentation. 有关测量代码的更多信息,请参阅测量装置文档。

You’ll also want to configure an appropriate exporter to export your telemetry data to one or more telemetry backends. 您还需要配置适当的导出器以将遥测数据导出到一个或多个遥测后端。

0 人点赞