From a102d532274d05fe876d96dd7f5566f4e4a1fd12 Mon Sep 17 00:00:00 2001 From: maladetska Date: Sat, 7 Feb 2026 15:57:16 +0300 Subject: [PATCH 1/3] init commit --- cmake/external_libs.cmake | 1 + include/ydb-cpp-sdk/client/metrics/metrics.h | 81 ++++++++++ .../ydb-cpp-sdk/open_telemetry/extension.h | 34 ++++ include/ydb-cpp-sdk/open_telemetry/otel.h | 33 ++++ src/CMakeLists.txt | 3 +- src/client/CMakeLists.txt | 1 + .../grpc_connections/grpc_connections.h | 12 ++ src/client/metrics/CMakeLists.txt | 14 ++ src/client/metrics/metrics.cpp | 32 ++++ src/client/query/CMakeLists.txt | 1 + src/client/query/client.cpp | 55 ++++++- src/client/query/impl/CMakeLists.txt | 1 + src/client/query/impl/query_spans.cpp | 56 +++++++ src/client/query/impl/query_spans.h | 23 +++ src/open_telemetry/CMakeLists.txt | 17 ++ src/open_telemetry/otel.cpp | 153 ++++++++++++++++++ 16 files changed, 509 insertions(+), 8 deletions(-) create mode 100644 include/ydb-cpp-sdk/client/metrics/metrics.h create mode 100644 include/ydb-cpp-sdk/open_telemetry/extension.h create mode 100644 include/ydb-cpp-sdk/open_telemetry/otel.h create mode 100644 src/client/metrics/CMakeLists.txt create mode 100644 src/client/metrics/metrics.cpp create mode 100644 src/client/query/impl/query_spans.cpp create mode 100644 src/client/query/impl/query_spans.h create mode 100644 src/open_telemetry/CMakeLists.txt create mode 100644 src/open_telemetry/otel.cpp diff --git a/cmake/external_libs.cmake b/cmake/external_libs.cmake index dc46fdb1d5e..be645f332ae 100644 --- a/cmake/external_libs.cmake +++ b/cmake/external_libs.cmake @@ -13,6 +13,7 @@ find_package(base64 REQUIRED) find_package(Brotli 1.1.0 REQUIRED) find_package(jwt-cpp REQUIRED) find_package(double-conversion REQUIRED) +find_package(opentelemetry-cpp REQUIRED) # RapidJSON if (YDB_SDK_USE_RAPID_JSON) diff --git a/include/ydb-cpp-sdk/client/metrics/metrics.h b/include/ydb-cpp-sdk/client/metrics/metrics.h new file mode 100644 index 00000000000..d3dc5eb2c19 --- /dev/null +++ b/include/ydb-cpp-sdk/client/metrics/metrics.h @@ -0,0 +1,81 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace NYdb::inline V3::NMetrics { + +using TLabels = std::map; + +class ICounter { +public: + virtual ~ICounter() = default; + virtual void Inc() = 0; +}; + +class IGauge { +public: + virtual ~IGauge() = default; + virtual void Add(double delta) = 0; + virtual void Set(double value) = 0; +}; + +class IHistogram { +public: + virtual ~IHistogram() = default; + virtual void Record(double value) = 0; +}; + +class IMetricRegistry { +public: + virtual ~IMetricRegistry() = default; + + virtual std::shared_ptr Counter(const std::string& name, const TLabels& labels = {}) = 0; + virtual std::shared_ptr Gauge(const std::string& name, const TLabels& labels = {}) = 0; + virtual std::shared_ptr Histogram(const std::string& name, const std::vector& buckets, const TLabels& labels = {}) = 0; +}; + +enum class ESpanKind { + INTERNAL, + SERVER, + CLIENT, + PRODUCER, + CONSUMER +}; + +class ISpan { +public: + virtual ~ISpan() = default; + virtual void End() = 0; + virtual void SetAttribute(const std::string& key, const std::string& value) = 0; + virtual void SetAttribute(const std::string& key, int64_t value) = 0; +}; + +class ITracer { +public: + virtual ~ITracer() = default; + virtual std::shared_ptr StartSpan(const std::string& name, ESpanKind kind = ESpanKind::INTERNAL) = 0; +}; + +class ITraceProvider { +public: + virtual ~ITraceProvider() = default; + virtual std::shared_ptr GetTracer(const std::string& name) = 0; +}; + +class IMetricsApi : public IExtensionApi { +public: + static IMetricsApi* Create(TDriver driver); +public: + virtual ~IMetricsApi() = default; + virtual void SetMetricRegistry(std::shared_ptr registry) = 0; + virtual void SetTraceProvider(std::shared_ptr provider) = 0; + virtual std::shared_ptr GetMetricRegistry() const = 0; + virtual std::shared_ptr GetTraceProvider() const = 0; +}; + +} // namespace NYdb::NMetrics diff --git a/include/ydb-cpp-sdk/open_telemetry/extension.h b/include/ydb-cpp-sdk/open_telemetry/extension.h new file mode 100644 index 00000000000..b5683d6d41b --- /dev/null +++ b/include/ydb-cpp-sdk/open_telemetry/extension.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace NYdb::inline V3::NMetrics { + +class TOtelExtension : public IExtension { +public: + using IApi = IMetricsApi; + + struct TParams { + opentelemetry::nostd::shared_ptr MeterProvider; + opentelemetry::nostd::shared_ptr TracerProvider; + }; + + TOtelExtension(const TParams& params, IApi* api) { + if (params.MeterProvider) { + api->SetMetricRegistry(std::make_shared(params.MeterProvider)); + } + if (params.TracerProvider) { + api->SetTraceProvider(std::make_shared(params.TracerProvider)); + } + } +}; + +inline void AddOpenTelemetry(TDriver& driver + , opentelemetry::nostd::shared_ptr meterProvider + , opentelemetry::nostd::shared_ptr tracerProvider +) { + driver.AddExtension({meterProvider, tracerProvider}); +} + +} // namespace NYdb::NMetrics diff --git a/include/ydb-cpp-sdk/open_telemetry/otel.h b/include/ydb-cpp-sdk/open_telemetry/otel.h new file mode 100644 index 00000000000..b1d23c92fa6 --- /dev/null +++ b/include/ydb-cpp-sdk/open_telemetry/otel.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include +#include + +namespace NYdb::inline V3::NMetrics { + +class TOtelMetricRegistry : public IMetricRegistry { +public: + TOtelMetricRegistry(opentelemetry::nostd::shared_ptr meterProvider); + + std::shared_ptr Counter(const std::string& name, const TLabels& labels = {}) override; + std::shared_ptr Gauge(const std::string& name, const TLabels& labels = {}) override; + std::shared_ptr Histogram(const std::string& name, const std::vector& buckets, const TLabels& labels = {}) override; + +private: + opentelemetry::nostd::shared_ptr MeterProvider_; + opentelemetry::nostd::shared_ptr Meter_; +}; + +class TOtelTraceProvider : public ITraceProvider { +public: + TOtelTraceProvider(opentelemetry::nostd::shared_ptr tracerProvider); + + std::shared_ptr GetTracer(const std::string& name) override; + +private: + opentelemetry::nostd::shared_ptr TracerProvider_; +}; + +} // namespace NYdb::NMetrics diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3dff7094058..c3fa4e733cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(api) add_subdirectory(client) -add_subdirectory(library) \ No newline at end of file +add_subdirectory(library) +add_subdirectory(open_telemetry) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index e7f448e8675..65167cddbd0 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(iam) add_subdirectory(iam_private) add_subdirectory(impl) add_subdirectory(import) +add_subdirectory(metrics) add_subdirectory(monitoring) add_subdirectory(operation) add_subdirectory(params) diff --git a/src/client/impl/internal/grpc_connections/grpc_connections.h b/src/client/impl/internal/grpc_connections/grpc_connections.h index 756d2f0d957..15cddb4e6ec 100644 --- a/src/client/impl/internal/grpc_connections/grpc_connections.h +++ b/src/client/impl/internal/grpc_connections/grpc_connections.h @@ -581,6 +581,18 @@ class TGRpcConnectionsImpl ::NMonitoring::TMetricRegistry* GetMetricRegistry() override; void RegisterExtension(IExtension* extension); void RegisterExtensionApi(IExtensionApi* api); + + template + T* GetExtensionApi() { + std::lock_guard lock(ExtensionsLock_); + for (const auto& api : ExtensionApis_) { + if (auto ptr = dynamic_cast(api.get())) { + return ptr; + } + } + return nullptr; + } + void SetDiscoveryMutator(IDiscoveryMutatorApi::TMutatorCb&& cb); const TLog& GetLog() const override; diff --git a/src/client/metrics/CMakeLists.txt b/src/client/metrics/CMakeLists.txt new file mode 100644 index 00000000000..94902b0f415 --- /dev/null +++ b/src/client/metrics/CMakeLists.txt @@ -0,0 +1,14 @@ +_ydb_sdk_add_library(client-metrics) + +target_sources(client-metrics PRIVATE + metrics.cpp +) + +target_include_directories(client-metrics PUBLIC + $ + $ +) + +target_link_libraries(client-metrics PUBLIC + client-extension_common +) diff --git a/src/client/metrics/metrics.cpp b/src/client/metrics/metrics.cpp new file mode 100644 index 00000000000..836d01f2071 --- /dev/null +++ b/src/client/metrics/metrics.cpp @@ -0,0 +1,32 @@ +#include + +namespace NYdb::inline V3::NMetrics { + +class TMetricsApiImpl : public IMetricsApi { +public: + void SetMetricRegistry(std::shared_ptr registry) override { + Registry_ = std::move(registry); + } + + void SetTraceProvider(std::shared_ptr provider) override { + TraceProvider_ = std::move(provider); + } + + std::shared_ptr GetMetricRegistry() const override { + return Registry_; + } + + std::shared_ptr GetTraceProvider() const override { + return TraceProvider_; + } + +private: + std::shared_ptr Registry_; + std::shared_ptr TraceProvider_; +}; + +IMetricsApi* IMetricsApi::Create(TDriver driver) { + return new TMetricsApiImpl(); +} + +} // namespace NYdb::NMetrics diff --git a/src/client/query/CMakeLists.txt b/src/client/query/CMakeLists.txt index 6677d402d4d..f1395ff107b 100644 --- a/src/client/query/CMakeLists.txt +++ b/src/client/query/CMakeLists.txt @@ -7,6 +7,7 @@ target_link_libraries(client-ydb_query PUBLIC impl-internal-make_request impl-session impl-internal-retry + client-metrics client-ydb_common_client client-ydb_driver client-ydb_query-impl diff --git a/src/client/query/client.cpp b/src/client/query/client.cpp index ccf90f1175c..ca1453e0faf 100644 --- a/src/client/query/client.cpp +++ b/src/client/query/client.cpp @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include @@ -67,6 +69,12 @@ class TQueryClient::TImpl: public TClientImplCommon, public { SetStatCollector(DbDriverState_->StatCollector.GetClientStatCollector("Query")); SessionPool_.SetStatCollector(DbDriverState_->StatCollector.GetSessionPoolStatCollector("Query")); + + if (auto metricsApi = Connections_->GetExtensionApi()) { + if (auto traceProvider = metricsApi->GetTraceProvider()) { + Tracer_ = traceProvider->GetTracer("ydb-cpp-sdk-query"); + } + } } ~TImpl() { @@ -94,8 +102,21 @@ class TQueryClient::TImpl: public TClientImplCommon, public { CollectQuerySize(query); CollectParamsSize(params ? ¶ms->GetProtoMap() : nullptr); + + auto span = std::make_shared(Tracer_, "ExecuteQuery", DbDriverState_->DiscoveryEndpoint); + return TExecQueryImpl::ExecuteQuery( - Connections_, DbDriverState_, query, txControl, params, settings, session); + Connections_, DbDriverState_, query, txControl, params, settings, session) + .Apply([span](TAsyncExecuteQueryResult future) { + try { + auto result = future.GetValue(); + span->End(result.GetStatus()); + return result; + } catch (...) { + span->End(EStatus::CLIENT_INTERNAL_ERROR); + throw; + } + }); } NThreading::TFuture ExecuteScript(const std::string& script, const std::optional& params, const TExecuteScriptSettings& settings) { @@ -162,7 +183,9 @@ class TQueryClient::TImpl: public TClientImplCommon, public auto promise = NThreading::NewPromise(); - auto responseCb = [promise, session] + auto span = std::make_shared(Tracer_, "Rollback", DbDriverState_->DiscoveryEndpoint); + + auto responseCb = [promise, session, span] (Ydb::Query::RollbackTransactionResponse* response, TPlainStatus status) mutable { try { if (response) { @@ -171,11 +194,15 @@ class TQueryClient::TImpl: public TClientImplCommon, public TStatus rollbackTxStatus(TPlainStatus{static_cast(response->status()), std::move(opIssues), status.Endpoint, std::move(status.Metadata)}); + span->End(rollbackTxStatus.GetStatus()); + promise.SetValue(std::move(rollbackTxStatus)); } else { + span->End(status.Status); promise.SetValue(TStatus(std::move(status))); } } catch (...) { + span->End(EStatus::CLIENT_INTERNAL_ERROR); promise.SetException(std::current_exception()); } }; @@ -203,7 +230,9 @@ class TQueryClient::TImpl: public TClientImplCommon, public auto promise = NThreading::NewPromise(); - auto responseCb = [promise, session] + auto span = std::make_shared(Tracer_, "Commit", DbDriverState_->DiscoveryEndpoint); + + auto responseCb = [promise, session, span] (Ydb::Query::CommitTransactionResponse* response, TPlainStatus status) mutable { try { if (response) { @@ -212,12 +241,16 @@ class TQueryClient::TImpl: public TClientImplCommon, public TStatus commitTxStatus(TPlainStatus{static_cast(response->status()), std::move(opIssues), status.Endpoint, std::move(status.Metadata)}); + span->End(commitTxStatus.GetStatus()); + TCommitTransactionResult commitTxResult(std::move(commitTxStatus)); promise.SetValue(std::move(commitTxResult)); } else { + span->End(status.Status); promise.SetValue(TCommitTransactionResult(TStatus(std::move(status)))); } } catch (...) { + span->End(EStatus::CLIENT_INTERNAL_ERROR); promise.SetException(std::current_exception()); } }; @@ -425,10 +458,11 @@ class TQueryClient::TImpl: public TClientImplCommon, public TAsyncCreateSessionResult GetSession(const TCreateSessionSettings& settings) { class TQueryClientGetSessionCtx : public NSessionPool::IGetSessionCtx { public: - TQueryClientGetSessionCtx(std::shared_ptr client, const TCreateSessionSettings& settings) + TQueryClientGetSessionCtx(std::shared_ptr client, const TCreateSessionSettings& settings, std::shared_ptr span) : Promise(NThreading::NewPromise()) , Client(client) , RpcSettings(TRpcRequestSettings::Make(settings)) + , Span(span) {} TAsyncCreateSessionResult GetFuture() { @@ -437,6 +471,7 @@ class TQueryClient::TImpl: public TClientImplCommon, public void ReplyError(TStatus status) override { TSession session; + if (Span) Span->End(status.GetStatus()); ScheduleReply(TCreateSessionResult(std::move(status), std::move(session))); } @@ -449,14 +484,17 @@ class TQueryClient::TImpl: public TClientImplCommon, public ) ); + if (Span) Span->End(EStatus::SUCCESS); ScheduleReply(std::move(val)); } void ReplyNewSession() override { Client->CreateAttachedSession(RpcSettings).Subscribe( - [promise{std::move(Promise)}](TAsyncCreateSessionResult future) mutable + [promise{std::move(Promise)}, span = Span](TAsyncCreateSessionResult future) mutable { - promise.SetValue(future.ExtractValue()); + auto val = future.ExtractValue(); + if (span) span->End(val.GetStatus()); + promise.SetValue(std::move(val)); }); } @@ -481,9 +519,11 @@ class TQueryClient::TImpl: public TClientImplCommon, public NThreading::TPromise Promise; std::shared_ptr Client; const TRpcRequestSettings RpcSettings; + std::shared_ptr Span; }; - auto ctx = std::make_unique(shared_from_this(), settings); + auto span = std::make_shared(Tracer_, "CreateSession", DbDriverState_->DiscoveryEndpoint); + auto ctx = std::make_unique(shared_from_this(), settings, span); auto future = ctx->GetFuture(); SessionPool_.GetSession(std::move(ctx)); @@ -552,6 +592,7 @@ class TQueryClient::TImpl: public TClientImplCommon, public } private: + std::shared_ptr Tracer_; NSdkStats::TStatCollector::TClientRetryOperationStatCollector RetryOperationStatCollector_; NSdkStats::TAtomicHistogram<::NMonitoring::THistogram> QuerySizeHistogram_; NSdkStats::TAtomicHistogram<::NMonitoring::THistogram> ParamsSizeHistogram_; diff --git a/src/client/query/impl/CMakeLists.txt b/src/client/query/impl/CMakeLists.txt index 76b112b2254..70f93b6d68d 100644 --- a/src/client/query/impl/CMakeLists.txt +++ b/src/client/query/impl/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(client-ydb_query-impl PUBLIC target_sources(client-ydb_query-impl PRIVATE exec_query.cpp client_session.cpp + query_spans.cpp ) _ydb_sdk_install_targets(TARGETS client-ydb_query-impl) diff --git a/src/client/query/impl/query_spans.cpp b/src/client/query/impl/query_spans.cpp new file mode 100644 index 00000000000..c612f442663 --- /dev/null +++ b/src/client/query/impl/query_spans.cpp @@ -0,0 +1,56 @@ +#include "query_spans.h" + +#include + +namespace NYdb::inline V3::NQuery { + +namespace { + +void ParseEndpoint(const std::string& endpoint, std::string& host, int& port) { + auto pos = endpoint.find(':'); + if (pos != std::string::npos) { + host = endpoint.substr(0, pos); + try { + port = std::stoi(endpoint.substr(pos + 1)); + } catch (...) { + port = 2135; + } + } else { + host = endpoint; + port = 2135; + } +} + +} // namespace + +TQuerySpan::TQuerySpan(std::shared_ptr tracer, const std::string& operationName, const std::string& endpoint) { + if (!tracer) return; + + std::string host; + int port; + ParseEndpoint(endpoint, host, port); + + Span_ = tracer->StartSpan("ydb." + operationName, NMetrics::ESpanKind::CLIENT); + Span_->SetAttribute("db.system.name", "ydb"); + Span_->SetAttribute("server.address", host); + Span_->SetAttribute("server.port", static_cast(port)); +} + +TQuerySpan::~TQuerySpan() { + if (Span_) { + Span_->End(); + } +} + +void TQuerySpan::End(EStatus status) { + if (Span_) { + Span_->SetAttribute("db.response.status_code", static_cast(status)); + if (status != EStatus::SUCCESS) { + Span_->SetAttribute("error.type", ToString(status)); + } + Span_->End(); + Span_.reset(); + } +} + +} // namespace NYdb::NQuery diff --git a/src/client/query/impl/query_spans.h b/src/client/query/impl/query_spans.h new file mode 100644 index 00000000000..d34e263d4db --- /dev/null +++ b/src/client/query/impl/query_spans.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace NYdb::inline V3::NQuery { + +class TQuerySpan { +public: + TQuerySpan(std::shared_ptr tracer, const std::string& operationName, const std::string& endpoint); + ~TQuerySpan(); + + void End(EStatus status); + +private: + std::shared_ptr Span_; +}; + +} // namespace NYdb::NQuery diff --git a/src/open_telemetry/CMakeLists.txt b/src/open_telemetry/CMakeLists.txt new file mode 100644 index 00000000000..4b0d7df8102 --- /dev/null +++ b/src/open_telemetry/CMakeLists.txt @@ -0,0 +1,17 @@ +_ydb_sdk_add_library(open_telemetry) + +target_sources(open_telemetry PRIVATE + otel.cpp +) + +target_include_directories(open_telemetry PUBLIC + $ + $ +) + +target_link_libraries(open_telemetry PUBLIC + client-metrics + opentelemetry-cpp::api + opentelemetry-cpp::metrics + opentelemetry-cpp::trace +) diff --git a/src/open_telemetry/otel.cpp b/src/open_telemetry/otel.cpp new file mode 100644 index 00000000000..b12a08c1b7b --- /dev/null +++ b/src/open_telemetry/otel.cpp @@ -0,0 +1,153 @@ +#include + +#include +#include +#include +#include +#include + +namespace NYdb::inline V3::NMetrics { + +namespace { + +using namespace opentelemetry; + +common::KeyValueIterableView MakeAttributes(const TLabels& labels) { + return common::KeyValueIterableView(labels); +} + +class TOtelCounter : public ICounter { +public: + TOtelCounter(nostd::shared_ptr> counter, const TLabels& labels) + : Counter_(std::move(counter)) + , Labels_(labels) + {} + + void Inc() override { + Counter_->Add(1, MakeAttributes(Labels_), context::RuntimeContext::GetCurrent()); + } + +private: + nostd::shared_ptr> Counter_; + TLabels Labels_; +}; + +class TOtelUpDownCounterGauge : public IGauge { +public: + TOtelUpDownCounterGauge(nostd::shared_ptr> counter, const TLabels& labels) + : Counter_(std::move(counter)) + , Labels_(labels) + {} + + void Add(double delta) override { + Counter_->Add(delta, MakeAttributes(Labels_), context::RuntimeContext::GetCurrent()); + Value_ += delta; + } + + void Set(double value) override { + Counter_->Add(value - Value_, MakeAttributes(Labels_), context::RuntimeContext::GetCurrent()); + Value_ = value; + } + +private: + nostd::shared_ptr> Counter_; + TLabels Labels_; + double Value_ = 0; +}; + +class TOtelHistogram : public IHistogram { +public: + TOtelHistogram(nostd::shared_ptr> histogram, const TLabels& labels) + : Histogram_(std::move(histogram)) + , Labels_(labels) + {} + + void Record(double value) override { + Histogram_->Record(value, MakeAttributes(Labels_), context::RuntimeContext::GetCurrent()); + } + +private: + nostd::shared_ptr> Histogram_; + TLabels Labels_; +}; + +trace::SpanKind MapSpanKind(ESpanKind kind) { + switch (kind) { + case ESpanKind::INTERNAL: return trace::SpanKind::kInternal; + case ESpanKind::SERVER: return trace::SpanKind::kServer; + case ESpanKind::CLIENT: return trace::SpanKind::kClient; + case ESpanKind::PRODUCER: return trace::SpanKind::kProducer; + case ESpanKind::CONSUMER: return trace::SpanKind::kConsumer; + } + return trace::SpanKind::kInternal; +} + +class TOtelSpan : public ISpan { +public: + TOtelSpan(nostd::shared_ptr span) + : Span_(std::move(span)) + {} + + void End() override { + Span_->End(); + } + + void SetAttribute(const std::string& key, const std::string& value) override { + Span_->SetAttribute(key, value); + } + + void SetAttribute(const std::string& key, int64_t value) override { + Span_->SetAttribute(key, value); + } + +private: + nostd::shared_ptr Span_; +}; + +class TOtelTracer : public ITracer { +public: + TOtelTracer(nostd::shared_ptr tracer) + : Tracer_(std::move(tracer)) + {} + + std::shared_ptr StartSpan(const std::string& name, ESpanKind kind) override { + trace::StartSpanOptions options; + options.kind = MapSpanKind(kind); + return std::make_shared(Tracer_->StartSpan(name, options)); + } + +private: + nostd::shared_ptr Tracer_; +}; + +} // namespace + +TOtelMetricRegistry::TOtelMetricRegistry(nostd::shared_ptr meterProvider) + : MeterProvider_(std::move(meterProvider)) + , Meter_(MeterProvider_->GetMeter("ydb-cpp-sdk", "1.0.0")) +{} + +std::shared_ptr TOtelMetricRegistry::Counter(const std::string& name, const TLabels& labels) { + auto counter = Meter_->CreateUInt64Counter(name); + return std::make_shared(std::move(counter), labels); +} + +std::shared_ptr TOtelMetricRegistry::Gauge(const std::string& name, const TLabels& labels) { + auto counter = Meter_->CreateDoubleUpDownCounter(name); + return std::make_shared(std::move(counter), labels); +} + +std::shared_ptr TOtelMetricRegistry::Histogram(const std::string& name, const std::vector& buckets, const TLabels& labels) { + auto histogram = Meter_->CreateDoubleHistogram(name); + return std::make_shared(std::move(histogram), labels); +} + +TOtelTraceProvider::TOtelTraceProvider(nostd::shared_ptr tracerProvider) + : TracerProvider_(std::move(tracerProvider)) +{} + +std::shared_ptr TOtelTraceProvider::GetTracer(const std::string& name) { + return std::make_shared(TracerProvider_->GetTracer(name)); +} + +} // namespace NYdb::NMetrics From 90118388d09338f83871caf64fff96d5430507ca Mon Sep 17 00:00:00 2001 From: maladetska Date: Sat, 21 Feb 2026 15:57:37 +0300 Subject: [PATCH 2/3] . --- CMakeLists.txt | 4 ++++ cmake/external_libs.cmake | 5 ++++- {src/open_telemetry => open_telemetry}/CMakeLists.txt | 7 +++++-- .../include}/ydb-cpp-sdk/open_telemetry/extension.h | 0 .../include}/ydb-cpp-sdk/open_telemetry/otel.h | 0 {src/open_telemetry => open_telemetry/src}/otel.cpp | 0 src/CMakeLists.txt | 1 - 7 files changed, 13 insertions(+), 4 deletions(-) rename {src/open_telemetry => open_telemetry}/CMakeLists.txt (59%) rename {include => open_telemetry/include}/ydb-cpp-sdk/open_telemetry/extension.h (100%) rename {include => open_telemetry/include}/ydb-cpp-sdk/open_telemetry/otel.h (100%) rename {src/open_telemetry => open_telemetry/src}/otel.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86eaef64720..991c12d8a93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,10 @@ add_subdirectory(include/ydb-cpp-sdk/client) add_subdirectory(src) add_subdirectory(util) +if (YDB_SDK_HAS_OPEN_TELEMETRY) + add_subdirectory(open_telemetry EXCLUDE_FROM_ALL) +endif() + #_ydb_sdk_validate_public_headers() if (YDB_SDK_EXAMPLES) diff --git a/cmake/external_libs.cmake b/cmake/external_libs.cmake index be645f332ae..76666562f06 100644 --- a/cmake/external_libs.cmake +++ b/cmake/external_libs.cmake @@ -13,7 +13,10 @@ find_package(base64 REQUIRED) find_package(Brotli 1.1.0 REQUIRED) find_package(jwt-cpp REQUIRED) find_package(double-conversion REQUIRED) -find_package(opentelemetry-cpp REQUIRED) +find_package(opentelemetry-cpp QUIET) +if (opentelemetry-cpp_FOUND) + set(YDB_SDK_HAS_OPEN_TELEMETRY ON) +endif() # RapidJSON if (YDB_SDK_USE_RAPID_JSON) diff --git a/src/open_telemetry/CMakeLists.txt b/open_telemetry/CMakeLists.txt similarity index 59% rename from src/open_telemetry/CMakeLists.txt rename to open_telemetry/CMakeLists.txt index 4b0d7df8102..aa0cee855e1 100644 --- a/src/open_telemetry/CMakeLists.txt +++ b/open_telemetry/CMakeLists.txt @@ -1,11 +1,11 @@ _ydb_sdk_add_library(open_telemetry) target_sources(open_telemetry PRIVATE - otel.cpp + src/otel.cpp ) target_include_directories(open_telemetry PUBLIC - $ + $ $ ) @@ -15,3 +15,6 @@ target_link_libraries(open_telemetry PUBLIC opentelemetry-cpp::metrics opentelemetry-cpp::trace ) + +_ydb_sdk_make_client_component(OpenTelemetry open_telemetry) +_ydb_sdk_install_headers(${CMAKE_INSTALL_INCLUDEDIR} DIRECTORY include/) diff --git a/include/ydb-cpp-sdk/open_telemetry/extension.h b/open_telemetry/include/ydb-cpp-sdk/open_telemetry/extension.h similarity index 100% rename from include/ydb-cpp-sdk/open_telemetry/extension.h rename to open_telemetry/include/ydb-cpp-sdk/open_telemetry/extension.h diff --git a/include/ydb-cpp-sdk/open_telemetry/otel.h b/open_telemetry/include/ydb-cpp-sdk/open_telemetry/otel.h similarity index 100% rename from include/ydb-cpp-sdk/open_telemetry/otel.h rename to open_telemetry/include/ydb-cpp-sdk/open_telemetry/otel.h diff --git a/src/open_telemetry/otel.cpp b/open_telemetry/src/otel.cpp similarity index 100% rename from src/open_telemetry/otel.cpp rename to open_telemetry/src/otel.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c3fa4e733cd..b251a041380 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,3 @@ add_subdirectory(api) add_subdirectory(client) add_subdirectory(library) -add_subdirectory(open_telemetry) From bbc803b1aa7e9261e0b32177bec9309886761cb6 Mon Sep 17 00:00:00 2001 From: maladetska Date: Tue, 24 Feb 2026 14:43:45 +0300 Subject: [PATCH 3/3] make metrics as client_component --- src/client/metrics/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/client/metrics/CMakeLists.txt b/src/client/metrics/CMakeLists.txt index 94902b0f415..ce8526b5e7e 100644 --- a/src/client/metrics/CMakeLists.txt +++ b/src/client/metrics/CMakeLists.txt @@ -12,3 +12,5 @@ target_include_directories(client-metrics PUBLIC target_link_libraries(client-metrics PUBLIC client-extension_common ) + +_ydb_sdk_make_client_component(Metrics client-metrics)