Skip to content

added abstract IMetric class and implementations for Solomon, Prometheus, OpenTelemetry, DataDog, New Relic, Victoria Metrics, AppDynamics #390

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 4 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
79 changes: 79 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ 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_MONITORING_PROMETHEUS "Enable Prometheus monitoring" OFF)
option(YDB_SDK_MONITORING_OPENTELEMETRY "Enable OpenTelemetry monitoring" OFF)
option(YDB_SDK_MONITORING_DATADOG "Enable Datadog monitoring" OFF)
option(YDB_SDK_MONITORING_NEWRELIC "Enable New Relic monitoring" OFF)
option(YDB_SDK_MONITORING_APPDYNAMICS "Enable AppDynamics monitoring" OFF)
option(YDB_SDK_MONITORING_VICTORIAMETRICS "Enable Victoria Metrics monitoring" OFF)
option(YDB_SDK_MONITORING_SOLOMON "Enable Yandex Solomon monitoring" ON)

set(BUILD_SHARED_LIBS Off)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED On)
Expand Down Expand Up @@ -97,3 +106,73 @@ if (YDB_SDK_INSTALL)
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ydb-cpp-sdk/Modules
)
endif()

# Поиск зависимостей для систем мониторинга
if(YDB_SDK_MONITORING_PROMETHEUS)
find_package(Prometheus REQUIRED)
endif()

if(YDB_SDK_MONITORING_OPENTELEMETRY)
find_package(OpenTelemetry REQUIRED)
endif()

if(YDB_SDK_MONITORING_DATADOG)
find_package(Datadog REQUIRED)
endif()

if(YDB_SDK_MONITORING_NEWRELIC)
find_package(NewRelic REQUIRED)
endif()

if(YDB_SDK_MONITORING_APPDYNAMICS)
find_package(AppDynamics REQUIRED)
endif()

if(YDB_SDK_MONITORING_VICTORIAMETRICS)
find_package(VictoriaMetrics REQUIRED)
endif()

# Поиск дополнительных зависимостей
find_package(Brotli REQUIRED)
find_package(LZ4 REQUIRED)
find_package(xxHash REQUIRED)
find_package(ZSTD REQUIRED)

# Определяем основную библиотеку
add_library(ydb-cpp-sdk STATIC
src/client/common_client/settings.cpp
src/client/driver/driver.cpp
)

# Добавляем зависимости в target_link_libraries
target_link_libraries(ydb-cpp-sdk
PRIVATE
client-ydb_common_client
client-ydb_types-credentials
impl-ydb_internal-common
yutil
protobuf::libprotobuf
grpc++
grpc++_reflection
OpenSSL::SSL
OpenSSL::Crypto
ZLIB::ZLIB
brotli
lz4
xxhash
zstd
BZip2::BZip2
IDN::IDN
$<$<BOOL:${YDB_SDK_MONITORING_PROMETHEUS}>:prometheus-cpp::prometheus-cpp>
$<$<BOOL:${YDB_SDK_MONITORING_OPENTELEMETRY}>:OpenTelemetry::OpenTelemetry>
$<$<BOOL:${YDB_SDK_MONITORING_DATADOG}>:Datadog::Datadog>
$<$<BOOL:${YDB_SDK_MONITORING_NEWRELIC}>:NewRelic::NewRelic>
$<$<BOOL:${YDB_SDK_MONITORING_APPDYNAMICS}>:AppDynamics::AppDynamics>
$<$<BOOL:${YDB_SDK_MONITORING_VICTORIAMETRICS}>:VictoriaMetrics::VictoriaMetrics>
)

target_include_directories(ydb-cpp-sdk
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
)
5 changes: 5 additions & 0 deletions 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)

# Prometheus
if (YDB_SDK_MONITORING_PROMETHEUS)
find_package(prometheus-cpp REQUIRED)
endif()

# RapidJSON
if (YDB_SDK_USE_RAPID_JSON)
find_package(RapidJSON REQUIRED)
Expand Down
273 changes: 273 additions & 0 deletions docs/monitoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
# Мониторинг в YDB C++ SDK

YDB C++ SDK поддерживает различные системы мониторинга для сбора метрик. Вы можете выбрать одну или несколько систем мониторинга при сборке проекта.

## Поддерживаемые системы мониторинга

- Prometheus
- OpenTelemetry
- Datadog
- New Relic
- AppDynamics
- Victoria Metrics
- Yandex Solomon (по умолчанию)

## Настройка сборки

При сборке проекта вы можете включить поддержку нужных систем мониторинга с помощью CMake опций:

```cmake
cmake -DYDB_SDK_MONITORING_PROMETHEUS=ON \
-DYDB_SDK_MONITORING_OPENTELEMETRY=ON \
-DYDB_SDK_MONITORING_DATADOG=ON \
-DYDB_SDK_MONITORING_NEWRELIC=ON \
-DYDB_SDK_MONITORING_APPDYNAMICS=ON \
-DYDB_SDK_MONITORING_VICTORIAMETRICS=ON \
-DYDB_SDK_MONITORING_SOLOMON=ON \
..
```

## Использование

### Prometheus

```cpp
#include <ydb-cpp-sdk/client/monitoring/metrics.h>
#include <ydb-cpp-sdk/client/monitoring/impl/prometheus.h>
#include <ydb-cpp-sdk/client/driver/driver.h>
#include <ydb-cpp-sdk/client/table/table.h>

// Создаем систему мониторинга
auto monitoringSystem = TMonitoringSystemFactory::CreatePrometheus("localhost:9090");
TMetricsContext::Instance().SetMonitoringSystem(std::move(monitoringSystem));

// Создаем драйвер YDB
TDriverConfig config;
config.SetEndpoint("localhost:2135");
config.SetDatabase("/local");
TDriver driver(config);

// Создаем клиент таблиц
TTableClient client(driver);

try {
// Выполняем запрос
auto result = client.ExecuteDataQuery(R"(
SELECT 1 + 1 AS result;
)", TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx());

// Создаем метрики на основе результата запроса
std::unordered_map<std::string, std::string> labels = {
{"operation", "query"},
{"status", "success"},
{"database", "/local"}
};

// Метрика количества запросов
TPrometheusMetric queryCount("ydb_query_count", "1", labels);
TMetricsContext::Instance().RecordMetric(queryCount);

// Метрика задержки запроса
auto latency = result.GetExecutionTime().MilliSeconds();
TPrometheusMetric queryLatency("ydb_query_latency", std::to_string(latency), labels);
TMetricsContext::Instance().RecordMetric(queryLatency);

// Метрика количества строк в результате
auto rowCount = result.GetResultSet(0).RowsCount();
TPrometheusMetric resultRows("ydb_result_rows", std::to_string(rowCount), labels);
TMetricsContext::Instance().RecordMetric(resultRows);

// Принудительно отправляем метрики
TMetricsContext::Instance().Flush();

} catch (const TYdbErrorException& e) {
// В случае ошибки отправляем метрику ошибки
std::unordered_map<std::string, std::string> errorLabels = {
{"operation", "query"},
{"status", "error"},
{"database", "/local"},
{"error_type", e.GetStatus().ToString()}
};
TPrometheusMetric errorCount("ydb_error_count", "1", errorLabels);
TMetricsContext::Instance().RecordMetric(errorCount);
TMetricsContext::Instance().Flush();
}
```

### OpenTelemetry

```cpp
#include <ydb-cpp-sdk/client/monitoring/metrics.h>
#include <ydb-cpp-sdk/client/monitoring/impl/opentelemetry.h>
#include <ydb-cpp-sdk/client/driver/driver.h>
#include <ydb-cpp-sdk/client/table/table.h>

// Создаем систему мониторинга
auto monitoringSystem = TMonitoringSystemFactory::CreateOpenTelemetry("localhost:4317");
TMetricsContext::Instance().SetMonitoringSystem(std::move(monitoringSystem));

// Создаем драйвер YDB
TDriverConfig config;
config.SetEndpoint("localhost:2135");
config.SetDatabase("/local");
TDriver driver(config);

// Создаем клиент таблиц
TTableClient client(driver);

try {
// Выполняем запрос
auto result = client.ExecuteDataQuery(R"(
SELECT 1 + 1 AS result;
)", TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx());

// Создаем метрики на основе результата запроса
std::unordered_map<std::string, std::string> labels = {
{"operation", "query"},
{"status", "success"},
{"database", "/local"}
};

// Метрика количества запросов
TOpenTelemetryMetric queryCount("ydb_query_count", "1", labels);
TMetricsContext::Instance().RecordMetric(queryCount);

// Метрика задержки запроса
auto latency = result.GetExecutionTime().MilliSeconds();
TOpenTelemetryMetric queryLatency("ydb_query_latency", std::to_string(latency), labels);
TMetricsContext::Instance().RecordMetric(queryLatency);

// Метрика количества строк в результате
auto rowCount = result.GetResultSet(0).RowsCount();
TOpenTelemetryMetric resultRows("ydb_result_rows", std::to_string(rowCount), labels);
TMetricsContext::Instance().RecordMetric(resultRows);

// Принудительно отправляем метрики
TMetricsContext::Instance().Flush();

} catch (const TYdbErrorException& e) {
// В случае ошибки отправляем метрику ошибки
std::unordered_map<std::string, std::string> errorLabels = {
{"operation", "query"},
{"status", "error"},
{"database", "/local"},
{"error_type", e.GetStatus().ToString()}
};
TOpenTelemetryMetric errorCount("ydb_error_count", "1", errorLabels);
TMetricsContext::Instance().RecordMetric(errorCount);
TMetricsContext::Instance().Flush();
}
```

### Datadog

```cpp
#include <ydb-cpp-sdk/client/monitoring/metrics.h>
#include <ydb-cpp-sdk/client/monitoring/impl/datadog.h>

// Создаем систему мониторинга
auto monitoringSystem = TMonitoringSystemFactory::CreateDatadog("your-api-key");
TMetricsContext::Instance().SetMonitoringSystem(std::move(monitoringSystem));

// Создаем метрику
std::unordered_map<std::string, std::string> labels = {
{"operation", "query"},
{"status", "success"}
};
TDatadogMetric metric("ydb.query.count", "1", labels);

// Записываем метрику
TMetricsContext::Instance().RecordMetric(metric);
```

### New Relic

```cpp
#include <ydb-cpp-sdk/client/monitoring/metrics.h>
#include <ydb-cpp-sdk/client/monitoring/impl/newrelic.h>

// Создаем систему мониторинга
auto monitoringSystem = TMonitoringSystemFactory::CreateNewRelic("your-license-key");
TMetricsContext::Instance().SetMonitoringSystem(std::move(monitoringSystem));

// Создаем метрику
std::unordered_map<std::string, std::string> labels = {
{"operation", "query"},
{"status", "success"}
};
TNewRelicMetric metric("Custom/ydb/query_count", "1", labels);

// Записываем метрику
TMetricsContext::Instance().RecordMetric(metric);
```

### AppDynamics

```cpp
#include <ydb-cpp-sdk/client/monitoring/metrics.h>
#include <ydb-cpp-sdk/client/monitoring/impl/appdynamics.h>

// Создаем систему мониторинга
auto monitoringSystem = TMonitoringSystemFactory::CreateAppDynamics("http://your-controller:8090");
TMetricsContext::Instance().SetMonitoringSystem(std::move(monitoringSystem));

// Создаем метрику
std::unordered_map<std::string, std::string> labels = {
{"operation", "query"},
{"status", "success"}
};
TAppDynamicsMetric metric("Custom Metrics|YDB|Query Count", "1", labels);

// Записываем метрику
TMetricsContext::Instance().RecordMetric(metric);
```

### Victoria Metrics

```cpp
#include <ydb-cpp-sdk/client/monitoring/metrics.h>
#include <ydb-cpp-sdk/client/monitoring/impl/victoriametrics.h>

// Создаем систему мониторинга
auto monitoringSystem = TMonitoringSystemFactory::CreateVictoriaMetrics("http://localhost:8428");
TMetricsContext::Instance().SetMonitoringSystem(std::move(monitoringSystem));

// Создаем метрику
std::unordered_map<std::string, std::string> labels = {
{"operation", "query"},
{"status", "success"}
};
TVictoriaMetricsMetric metric("ydb_query_count", "1", labels);

// Записываем метрику
TMetricsContext::Instance().RecordMetric(metric);
```

## Доступные метрики

YDB C++ SDK собирает следующие метрики:

- `ydb_query_count` - количество запросов
- `ydb_query_latency` - задержка запросов (в миллисекундах)
- `ydb_error_count` - количество ошибок
- `ydb_result_rows` - количество строк в результате запроса
- `ydb_connection_count` - количество активных соединений
- `ydb_session_count` - количество активных сессий

Каждая метрика может иметь следующие метки (labels):
- `operation` - тип операции (query, transaction и т.д.)
- `status` - статус операции (success, error)
- `database` - имя базы данных
- `error_type` - тип ошибки (только для метрик ошибок)

## Примеры

Полные примеры использования различных систем мониторинга можно найти в директории `examples/monitoring/`:

- `prometheus_example.cpp` - пример использования Prometheus с реальными запросами к YDB
- `opentelemetry_example.cpp` - пример использования OpenTelemetry с реальными запросами к YDB
- `datadog_example.cpp` - пример использования Datadog с реальными запросами к YDB
- `newrelic_example.cpp` - пример использования New Relic с реальными запросами к YDB
- `appdynamics_example.cpp` - пример использования AppDynamics с реальными запросами к YDB
- `victoriametrics_example.cpp` - пример использования Victoria Metrics с реальными запросами к YDB
- `solomon_example.cpp` - пример использования Yandex Solomon с реальными запросами к YDB
Loading
Loading