Skip to content

Support tracing in SDK and add loading to OpenTelemetry client #517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .devcontainer/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ volumes:
ydb-certs:

services:
jaeger:
image: jaegertracing/all-in-one:1.51.0
ports:
- "16686:16686" # Jaeger UI frontend
- "4317:4317" # gRPC port for accepts traces in OpenTelemetry OTLP format
- "4318:4318" # HTTP port for accepts traces in OpenTelemetry OTLP format
environment:
- COLLECTOR_OTLP_ENABLED=true

sdk:
platform: linux/amd64

Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ option(YDB_SDK_EXAMPLES "Build YDB C++ SDK examples" On)
set(YDB_SDK_GOOGLE_COMMON_PROTOS_TARGET "" CACHE STRING "Name of cmake target preparing google common proto library")
option(YDB_SDK_USE_RAPID_JSON "Search for rapid json library in system" ON)

option(YDB_SDK_TRACING "Enable tracing support" ON)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Флаг не совсем корректно назван, мы включаем не трейсинг целиком, мы включаем именно конкретный opentelemetry плагин


set(BUILD_SHARED_LIBS Off)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED On)
Expand Down
7 changes: 6 additions & 1 deletion cmake/external_libs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ find_package(jwt-cpp REQUIRED)
find_package(GTest REQUIRED)
find_package(double-conversion REQUIRED)

# OpenTelemetry
if(YDB_SDK_TRACING)
find_package(opentelemetry-cpp REQUIRED)
endif()

# RapidJSON
if (YDB_SDK_USE_RAPID_JSON)
find_package(RapidJSON REQUIRED)
Expand Down Expand Up @@ -85,4 +90,4 @@ target_include_directories(nayuki_md5 PUBLIC
$<INSTALL_INTERFACE:third_party/nayuki_md5>
)

_ydb_sdk_install_targets(TARGETS nayuki_md5)
_ydb_sdk_install_targets(TARGETS nayuki_md5)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лишние изменения

1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ add_subdirectory(pagination)
add_subdirectory(secondary_index)
add_subdirectory(secondary_index_builtin)
add_subdirectory(topic_reader)
add_subdirectory(tracing)
add_subdirectory(ttl)
add_subdirectory(vector_index)
11 changes: 11 additions & 0 deletions examples/tracing/CMakeLists.txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отступы в CMakeLists везде по 2 пробела

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
add_executable(tracing_example tracing_example.cpp)

if(YDB_SDK_TRACING)
target_link_libraries(tracing_example PRIVATE
ydb-cpp-sdk
${OPENTELEMETRY_LIBRARIES}
)
else()
target_link_libraries(tracing_example PRIVATE ydb-cpp-sdk)
target_compile_definitions(tracing_example PRIVATE -DYDB_SDK_TRACING_DISABLED)
endif()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Таргета ydb-cpp-sdk нет
  2. Более чистым будет линковаться c opentelemetry-cpp так:
target_link_libraries(tracing_example PRIVATE opentelemetry-cpp::api)
  1. Если opentelemetry вырублен, example в принципе собирать не надо

25 changes: 25 additions & 0 deletions examples/tracing/tracing_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <ydb-cpp-sdk/client/tracing/otel_tracer.h>
#include <opentelemetry/sdk/trace/tracer_provider.h>
#include <opentelemetry/exporters/jaeger/jaeger_exporter.h>
#include <ydb-cpp-sdk/client/driver.h>

int main() {
auto exporter = opentelemetry::exporter::jaeger::JaegerExporterFactory::Create();
auto provider = opentelemetry::sdk::trace::TracerProviderFactory::Create(std::move(exporter));
auto otelTracer = provider->GetTracer("ydb-cpp-sdk");

auto ydbTracer = std::make_shared<NYdb::NTracing::TOpenTelemetryTracer>(otelTracer);

auto driver = NYdb::TDriver(
NYdb::TDriverConfig()
.SetEndpoint("localhost:2136")
.SetDatabase("/local")
.SetTracer(ydbTracer)
);

auto client = NYdb::NTable::TTableClient(driver);
auto session = client.CreateSession().GetValueSync();
session.ExecuteDataQuery("SELECT 1", NYdb::NTable::TTxControl::BeginTx().CommitTx()).GetValueSync();

return 0;
}
3 changes: 3 additions & 0 deletions include/ydb-cpp-sdk/client/driver/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <ydb-cpp-sdk/client/types/fatal_error_handlers/handlers.h>
#include <ydb-cpp-sdk/client/types/request_settings.h>
#include <ydb-cpp-sdk/client/types/status/status.h>
#include <ydb-cpp-sdk/client/tracing/tracer.h>

#include <library/cpp/logger/backend.h>

Expand Down Expand Up @@ -118,6 +119,8 @@ class TDriverConfig {

//! Log backend.
TDriverConfig& SetLog(std::unique_ptr<TLogBackend>&& log);

TDriverConfig& SetTracer(std::shared_ptr<NTracing::ITracer> tracer);
private:
class TImpl;
std::shared_ptr<TImpl> Impl_;
Expand Down
68 changes: 68 additions & 0 deletions include/ydb-cpp-sdk/client/tracing/tracer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

#include <string>
#include <memory>
#include <unordered_map>

namespace NYdb {
namespace NTracing {

using TAttributeMap = std::unordered_map<std::string, std::string>;

class TTraceContext {
public:
TTraceContext(std::string traceId, std::string spanId, std::string parentSpanId = "")
: TraceId_(std::move(traceId))
, SpanId_(std::move(spanId))
, ParentSpanId_(std::move(parentSpanId))
{}

const std::string& GetTraceId() const { return TraceId_; }
const std::string& GetSpanId() const { return SpanId_; }
const std::string& GetParentSpanId() const { return ParentSpanId_; }

static std::shared_ptr<TTraceContext> GenerateNew();
std::shared_ptr<TTraceContext> CreateChild() const;
std::string ToTraceParent() const;

private:
std::string TraceId_;
std::string SpanId_;
std::string ParentSpanId_;
};


class ISpan {
public:
virtual ~ISpan() = default;

virtual void AddAttribute(const std::string& key, const std::string& value) = 0;
virtual void AddEvent(const std::string& name, const TAttributeMap& attributes = {}) = 0;
virtual void SetStatus(bool isError, const std::string& description = "") = 0;
virtual void End() = 0;

virtual const TTraceContext& GetContext() const = 0;
};


class ITracer {
public:
virtual ~ITracer() = default;

virtual std::unique_ptr<ISpan> StartSpan(
const std::string& name,
const TAttributeMap& attributes = {},
std::shared_ptr<TTraceContext> parentContext = nullptr) = 0;

virtual std::shared_ptr<TTraceContext> GetCurrentContext() const = 0;

virtual std::string GetCurrentTraceParent() const {
if (auto ctx = GetCurrentContext()) {
return ctx->ToTraceParent();
}
return "";
}
};

} // namespace NTracing
} // namespace NYdb
3 changes: 3 additions & 0 deletions include/ydb-cpp-sdk/client/types/request_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <vector>
#include <utility>
#include <string>

namespace NYdb::inline V3 {

Expand All @@ -20,6 +21,7 @@ struct TRequestSettings {
FLUENT_SETTING(std::string, RequestType);
FLUENT_SETTING(THeader, Header);
FLUENT_SETTING(TDuration, ClientTimeout);
FLUENT_SETTING(std::string, TraceParent);

TRequestSettings() = default;

Expand All @@ -29,6 +31,7 @@ struct TRequestSettings {
, RequestType_(other.RequestType_)
, Header_(other.Header_)
, ClientTimeout_(other.ClientTimeout_)
, TraceParent_(other.TraceParent_)
{}
};

Expand Down
6 changes: 6 additions & 0 deletions src/client/driver/driver.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <ydb-cpp-sdk/client/driver/driver.h>
#include <ydb-cpp-sdk/client/tracing/tracer.h>

#define INCLUDE_YDB_INTERNAL_H
#include <src/client/impl/ydb_internal/driver/constants.h>
Expand Down Expand Up @@ -203,6 +204,11 @@ TDriverConfig& TDriverConfig::SetLog(std::unique_ptr<TLogBackend>&& log) {
return *this;
}

TDriverConfig& TDriverConfig::SetTracer(std::shared_ptr<NTracing::ITracer> tracer) {
Impl_->Tracer_ = tracer ? tracer : std::make_shared<NTracing::TNoopTracer>();
return *this;
}

////////////////////////////////////////////////////////////////////////////////

std::shared_ptr<TGRpcConnectionsImpl> CreateInternalInterface(const TDriver connection) {
Expand Down
15 changes: 15 additions & 0 deletions src/client/impl/ydb_internal/grpc_connections/grpc_connections.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ class TGRpcConnectionsImpl

TCallMeta meta;
meta.Timeout = requestSettings.ClientTimeout;

if (!requestSettings.TraceParent.empty()) {
meta.Aux.emplace_back({"traceparent", requestSettings.TraceParent});
}

#ifndef YDB_GRPC_UNSECURE_AUTH
meta.CallCredentials = dbState->CallCredentials;
#else
Expand Down Expand Up @@ -415,6 +420,11 @@ class TGRpcConnectionsImpl

TCallMeta meta;
meta.Timeout = requestSettings.ClientTimeout;

if (!requestSettings.TraceParent.empty()) {
meta.Aux.emplace_back({"traceparent", requestSettings.TraceParent});
}

#ifndef YDB_GRPC_UNSECURE_AUTH
meta.CallCredentials = dbState->CallCredentials;
#else
Expand Down Expand Up @@ -509,6 +519,11 @@ class TGRpcConnectionsImpl
}

TCallMeta meta;

if (!requestSettings.TraceParent.empty()) {
meta.Aux.emplace_back({"traceparent", requestSettings.TraceParent});
}

#ifndef YDB_GRPC_UNSECURE_AUTH
meta.CallCredentials = dbState->CallCredentials;
#else
Expand Down
37 changes: 37 additions & 0 deletions src/client/tracing/noop_tracer.h
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Почему это header файлы?
  2. otel_tracer не нужно компилировать, если проставлен флаг
  3. А как эти трейсеры создать теперь? Надо создать папку plugins в include и src по правильному. Там будет папка для otel_tracer и в нем будет фабричный метод. А то сейчас все в кучу слеплено

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <ydb-cpp-sdk/client/tracing/tracer.h>

namespace NYdb::inline V3 {
namespace NTracing {

class TNoopSpan : public ISpan {
public:
void AddAttribute(const std::string&, const std::string&) override {}
void AddEvent(const std::string&, const TAttributeMap& = {}) override {}
void SetStatus(bool, const std::string& = "") override {}
void End() override {}

const TTraceContext& GetContext() const override {
static TTraceContext emptyContext("", "");
return emptyContext;
}
};

class TNoopTracer : public ITracer {
public:
std::unique_ptr<ISpan> StartSpan(
const std::string&,
const TAttributeMap& = {},
std::shared_ptr<TTraceContext> = nullptr) override
{
return std::make_unique<TNoopSpan>();
}

std::shared_ptr<TTraceContext> GetCurrentContext() const override {
return nullptr;
}
};

} // namespace NTracing
} // namespace NYdb
Loading
Loading