Метрики с OpenTelemetry
YDB SDK инструментируют операции Query Service метриками OpenTelemetry, позволяя наблюдать состояние клиента — длительность и количество операций, состояние пула сессий — от кода приложения до gRPC-вызовов к YDB. Метрики экспортируются по стандартному протоколу OTLP и совместимы с Prometheus, Grafana, VictoriaMetrics и любым другим бэкендом, поддерживающим OpenTelemetry.
Список метрик
Метрики операций
| Имя | Тип | Единица | Описание |
|---|---|---|---|
ydb.client.operation.duration |
Histogram | s |
Длительность одной попытки клиентской операции (ExecuteQuery, Commit, Rollback, CreateSession). |
ydb.client.operation.failed |
Counter | {operation} |
Количество неуспешных клиентских операций. |
Метрики пула сессий
| Имя | Тип | Единица | Описание |
|---|---|---|---|
ydb.query.session.create_time |
Histogram | s |
Длительность создания новой сессии. |
ydb.query.session.pending_requests |
Counter | {request} |
Монотонный счётчик запросов на получение сессии, попавших в очередь ожидания, с момента создания пула. |
ydb.query.session.timeouts |
Counter | {timeout} |
Монотонный счётчик таймаутов при ожидании свободной сессии, с момента создания пула. |
ydb.query.session.count |
Gauge | {session} |
Текущее количество сессий в пуле, разделённое по состояниям. |
ydb.query.session.min |
Gauge | {session} |
Настроенный минимальный размер пула сессий. |
ydb.query.session.max |
Gauge | {session} |
Настроенный максимальный размер пула сессий. |
Метрики повторных попыток
| Имя | Тип | Единица | Описание |
|---|---|---|---|
ydb.client.retry.duration |
Histogram | s |
Полная видимая клиенту длительность логической операции, выполненной через политику повторов, включая все попытки и задержки backoff. |
ydb.client.retry.attempts |
Histogram | {attempt} |
Распределение числа попыток на одну логическую операцию. Значение 1 означает успех с первой попытки. |
Атрибуты
| Имя | Применяется к | Значение |
|---|---|---|
database |
ydb.client.operation.duration, ydb.client.operation.failed |
Имя базы данных YDB. |
endpoint |
ydb.client.operation.duration, ydb.client.operation.failed |
Discovery-endpoint в формате host:port. |
operation.name |
ydb.client.operation.duration, ydb.client.operation.failed, ydb.client.retry.duration, ydb.client.retry.attempts |
Имя клиентской операции: ExecuteQuery, Commit, Rollback, CreateSession. |
status_code |
ydb.client.operation.failed |
Код статуса YDB (например, BAD_REQUEST, SCHEME_ERROR). |
ydb.query.session.pool.name |
Все метрики ydb.query.session.* |
Имя пула сессий. По умолчанию формируется как <endpoint>/<database>; настраивается через API конкретного SDK. |
ydb.query.session.state |
ydb.query.session.count |
Состояние сессии: idle или used. |
Подключение к SDK
Подключите заголовок метрик OpenTelemetry из YDB C++ SDK и зарегистрируйте MetricRegistry в TDriverConfig:
#include <ydb-cpp-sdk/client/driver/driver.h>
#include <ydb-cpp-sdk/open_telemetry/metrics.h>
#include <opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h>
#include <opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h>
#include <opentelemetry/sdk/metrics/meter_provider.h>
#include <opentelemetry/sdk/metrics/view/view_registry.h>
#include <opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_factory.h>
#include <opentelemetry/sdk/resource/resource.h>
#include <opentelemetry/metrics/provider.h>
namespace sdkmetrics = opentelemetry::sdk::metrics;
namespace otlp = opentelemetry::exporter::otlp;
namespace resource = opentelemetry::sdk::resource;
using namespace NYdb;
// 1. Инициализируем провайдер метрик OTel
otlp::OtlpHttpMetricExporterOptions opts;
opts.url = "http://localhost:4318/v1/metrics";
auto exporter = otlp::OtlpHttpMetricExporterFactory::Create(opts);
sdkmetrics::PeriodicExportingMetricReaderOptions readerOpts;
readerOpts.export_interval_millis = std::chrono::milliseconds(5000);
auto reader = sdkmetrics::PeriodicExportingMetricReaderFactory::Create(
std::move(exporter), readerOpts);
auto res = resource::Resource::Create({{"service.name", "my-service"}});
auto rawProvider = std::make_shared<sdkmetrics::MeterProvider>(
std::unique_ptr<sdkmetrics::ViewRegistry>(new sdkmetrics::ViewRegistry()), res);
rawProvider->AddMetricReader(std::move(reader));
std::shared_ptr<opentelemetry::metrics::MeterProvider> meterProvider = rawProvider;
opentelemetry::metrics::Provider::SetMeterProvider(meterProvider);
// 2. Оборачиваем в регистратор метрик YDB
auto ydbMetricRegistry = NMetrics::CreateOtelMetricRegistry(meterProvider);
// 3. Создаём драйвер YDB с включёнными метриками
auto driverConfig = TDriverConfig()
.SetEndpoint("localhost:2136")
.SetDatabase("/local")
.SetMetricRegistry(ydbMetricRegistry);
TDriver driver(driverConfig);
Метрики и трассировку можно подключить вместе, зарегистрировав в TDriverConfig одновременно MetricRegistry и TraceProvider.
Установите адаптер OpenTelemetry для YDB Go SDK:
go get github.com/ydb-platform/ydb-go-sdk-otel
Настройте MeterProvider, получите из него Meter и передайте его в адаптер ydbOtel.WithMetrics, который подключается к драйверу через опцию ydb.Open. Детализацию собираемых метрик можно настроить через ydbOtel.WithDetailer:
package main
import (
"context"
"os"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
"github.com/ydb-platform/ydb-go-sdk/v3"
"github.com/ydb-platform/ydb-go-sdk/v3/trace"
ydbOtel "github.com/ydb-platform/ydb-go-sdk-otel"
)
func main() {
ctx := context.Background()
exporter, err := otlpmetricgrpc.New(ctx,
otlpmetricgrpc.WithEndpoint("localhost:4317"),
otlpmetricgrpc.WithInsecure(),
)
if err != nil {
panic(err)
}
res, _ := resource.Merge(resource.Default(), resource.NewSchemaless(
attribute.String("service.name", "my-service"),
))
mp := metric.NewMeterProvider(
metric.WithReader(metric.NewPeriodicReader(exporter)),
metric.WithResource(res),
)
defer mp.Shutdown(ctx)
otel.SetMeterProvider(mp)
db, err := ydb.Open(ctx,
os.Getenv("YDB_CONNECTION_STRING"),
ydbOtel.WithMetrics(
mp.Meter("ydb-go-sdk"),
ydbOtel.WithDetailer(trace.DetailsAll),
),
)
if err != nil {
panic(err)
}
defer db.Close(ctx)
}
Примечание
В Java SDK на данный момент поддерживаются только метрики пула сессий.
Передайте свой OpenTelemetry в SDK через адаптер OpenTelemetryMeter и метод QueryClient.Builder#withMeter:
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.core.metrics.OpenTelemetryMeter;
import tech.ydb.query.QueryClient;
SdkMeterProvider meterProvider = SdkMeterProvider.builder()
.registerMetricReader(PeriodicMetricReader
.builder(OtlpGrpcMetricExporter.getDefault())
.build())
.build();
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setMeterProvider(meterProvider)
.build();
try (GrpcTransport transport = GrpcTransport
.forConnectionString(System.getenv("YDB_CONNECTION_STRING"))
.build();
QueryClient queryClient = QueryClient.newClient(transport)
.withMeter(OpenTelemetryMeter.fromOpenTelemetry(openTelemetry))
.sessionPoolName("my-app")
.build()) {
// Используйте queryClient
}
meterProvider.close();
Если уже настроен глобальный GlobalOpenTelemetry, можно использовать OpenTelemetryMeter.createGlobal(). TableClient также поддерживает withMeter(...).
Функциональность на данный момент не поддерживается.
Добавьте NuGet-пакет:
dotnet add package Ydb.Sdk.OpenTelemetry
Зарегистрируйте инструментацию YDB в конвейере OpenTelemetry-метрик:
services.AddOpenTelemetry()
.WithMetrics(builder => builder
.AddYdb()
.AddOtlpExporter());
Или с использованием standalone MeterProvider:
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("my-service"))
.AddYdb()
.AddOtlpExporter()
.Build();
Имя пула сессий задаётся параметром PoolName= в строке подключения YdbDataSource. Полный пример с нагрузкой и Grafana — в репозитории SDK (Ydb.Sdk.AdoNet.OpenTelemetry/Metrics).
Установите пакет телеметрии YDB JavaScript SDK и OpenTelemetry SDK:
npm install @ydbjs/telemetry @opentelemetry/sdk-node @opentelemetry/exporter-metrics-otlp-http
Инициализируйте NodeSDK до создания Driver и зарегистрируйте инструментацию @ydbjs/telemetry:
import { NodeSDK } from '@opentelemetry/sdk-node'
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'
import { Driver } from '@ydbjs/core'
import { query } from '@ydbjs/query'
import { register } from '@ydbjs/telemetry'
const sdk = new NodeSDK({
serviceName: 'my-service',
metricReader: new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: 'http://localhost:4318/v1/metrics',
}),
}),
})
sdk.start()
// Должно быть вызвано ДО создания Driver: пакет подписывается на
// diagnostics_channel события SDK и преобразует их в OTel metrics.
const instrumentation = register()
const driver = new Driver(process.env.YDB_CONNECTION_STRING)
await driver.ready()
const sql = query(driver)
await sql`SELECT 1`
instrumentation.disable()
await driver.close()
await sdk.shutdown()
Пакет @ydbjs/telemetry подписывается на события node:diagnostics_channel из @ydbjs/core, @ydbjs/query, @ydbjs/auth и @ydbjs/retry и публикует метрики из списка выше. Длительность операций экспортируется как db.client.operation.duration (семантические конвенции OpenTelemetry), а не ydb.client.operation.duration. Текущее число ожидающих сессию запросов — gauge ydb.query.session.acquire.pending, а не counter ydb.query.session.pending_requests. Подробнее см. репозиторий JavaScript SDK.
Кроме того, JavaScript SDK публикует собственные метрики повторных попыток с именами и семантикой, отличными от ydb.client.retry.*:
| Имя | Тип | Единица | Описание |
|---|---|---|---|
ydb.retry.attempts |
Counter | {attempt} |
Монотонный счётчик попыток повторного выполнения с тегом исхода ydb.retry.outcome (например, success, retried). В отличие от гистограммы ydb.client.retry.attempts, не показывает распределение числа попыток на один запрос. |
ydb.retry.duration |
Histogram | s |
Суммарная длительность цикла повторных попыток, включая backoff (аналог ydb.client.retry.duration). |
Функциональность на данный момент не поддерживается.
Отслеживать прогресс или проголосовать за поддержку в Rust SDK: ydb-rs-sdk#268
Функциональность на данный момент не поддерживается.