> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> Руководство по использованию OpenTelemetry для распределённой трассировки и сбора метрик в ClickHouse

# Трассировка ClickHouse с OpenTelemetry

[OpenTelemetry](https://opentelemetry.io/) — это открытый стандарт для сбора трейсов и метрик в распределённых приложениях. ClickHouse в некоторой степени поддерживает OpenTelemetry.

<div id="supplying-trace-context-to-clickhouse">
  ## Передача контекста трассировки в ClickHouse
</div>

ClickHouse принимает HTTP-заголовки контекста трассировки, как описано в [рекомендации W3C](https://www.w3.org/TR/trace-context/). Он также принимает контекст трассировки через собственный протокол, который используется для обмена данными между серверами ClickHouse или между клиентом и сервером. Для ручного тестирования заголовки контекста трассировки, соответствующие рекомендации Trace Context, можно передать в `clickhouse-client` с помощью флагов `--opentelemetry-traceparent` и `--opentelemetry-tracestate`.

Если родительский контекст трассировки не передан или переданный контекст трассировки не соответствует указанному выше стандарту W3C, ClickHouse может начать новую трассировку с вероятностью, задаваемой настройкой [opentelemetry\_start\_trace\_probability](/docs/ru/reference/settings/session-settings#opentelemetry_start_trace_probability).

<div id="propagating-the-trace-context">
  ## Передача контекста трассировки
</div>

Контекст трассировки передаётся в сервисы ниже по цепочке в следующих случаях:

* Запросы к удалённым серверам ClickHouse, например при использовании движка таблицы [Distributed](/docs/ru/reference/engines/table-engines/special/distributed).

* Табличная функция [url](/docs/ru/reference/functions/table-functions/url). Информация о контексте трассировки отправляется в заголовках HTTP.

<div id="tracing-clickhouse-keeper-requests">
  ## Трассировка запросов ClickHouse Keeper
</div>

ClickHouse поддерживает трассировку OpenTelemetry для запросов [ClickHouse Keeper](/docs/ru/guides/oss/deployment-and-scaling/keeper/index) (сервиса координации, совместимого с ZooKeeper). Эта возможность обеспечивает подробную видимость всего жизненного цикла операций Keeper — от отправки клиентского запроса до его обработки на стороне сервера.

<div id="enabling-keeper-tracing">
  ### Включение трассировки запросов Keeper
</div>

Чтобы включить трассировку запросов Keeper, настройте следующие параметры в конфигурации клиента ZooKeeper/Keeper:

```xml theme={null}
<clickhouse>
    <zookeeper>
        <node>
            <host>keeper1</host>
            <port>9181</port>
        </node>
        <!-- Включить передачу контекста трассировки OpenTelemetry -->
        <pass_opentelemetry_tracing_context>true</pass_opentelemetry_tracing_context>
    </zookeeper>
</clickhouse>
```

<div id="keeper-span-types">
  ### Типы спанов Keeper
</div>

Когда трассировка включена, ClickHouse создает спаны как для клиентских, так и для серверных операций Keeper:

**Клиентские спаны:**

* `zookeeper.create` — Создание нового узла
* `zookeeper.get` — Получение данных узла
* `zookeeper.set` — Запись данных узла
* `zookeeper.remove` — Удаление узла
* `zookeeper.list` — Получение списка дочерних узлов
* `zookeeper.exists` — Проверка существования узла
* `zookeeper.multi` — Атомарное выполнение нескольких операций
* `zookeeper.client.requests_queue` — Время ожидания запросов в очереди перед отправкой

**Серверные спаны (Keeper):**

* `keeper.receive_request` — Получение и разбор запроса от клиента
* `keeper.dispatcher.requests_queue` — Ожидание запроса в очереди диспетчера
* `keeper.write.pre_commit` — Предварительная обработка запросов на запись перед фиксацией в Raft
* `keeper.write.commit` — Обработка запросов на запись после фиксации в Raft
* `keeper.read.wait_for_write` — Ожидание запросов на чтение, зависящих от записи
* `keeper.read.process` — Обработка запросов на чтение
* `keeper.dispatcher.responses_queue` — Ожидание ответа в очереди диспетчера
* `keeper.send_response` — Отправка ответа клиенту

<div id="sampling-and-performance">
  ### Сэмплирование и производительность
</div>

Чтобы снизить накладные расходы на трассировку, Keeper использует динамическое сэмплирование. Частота сэмплирования автоматически регулируется в диапазоне от 1/10,000 до 1/10 в зависимости от размера запроса. Для мониторинга производительности значения длительности всех запросов (как сэмплированных, так и несэмплированных) записываются в метрики-гистограммы.

<div id="tracing-the-clickhouse-itself">
  ## Трассировка самого ClickHouse
</div>

ClickHouse создает `trace spans` для каждого запроса и некоторых этапов его выполнения, таких как планирование запроса или распределенные запросы.

Чтобы эта информация была полезной, ее нужно экспортировать в систему мониторинга с поддержкой OpenTelemetry, например [Jaeger](https://jaegertracing.io/) или [Prometheus](https://prometheus.io/). ClickHouse не зависит от какой-либо конкретной системы мониторинга и предоставляет данные трассировки только через системную таблицу. Информация о спанах трассировки OpenTelemetry, [требуемая стандартом](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/overview.md#span), хранится в таблице [system.opentelemetry\_span\_log](/docs/ru/reference/system-tables/opentelemetry_span_log).

Эта таблица должна быть включена в конфигурации сервера, см. элемент `opentelemetry_span_log` в файле конфигурации по умолчанию `config.xml`. По умолчанию она включена.

Теги или атрибуты сохраняются в виде двух параллельных массивов, содержащих ключи и значения. Используйте [ARRAY JOIN](/docs/ru/reference/statements/select/array-join), чтобы работать с ними.

<div id="log-query-settings">
  ## Журналирование настроек запроса
</div>

Настройка [log\_query\_settings](/docs/ru/reference/settings/session-settings) позволяет журналировать изменения настроек запроса во время выполнения запроса. Когда она включена, любые изменения, внесенные в настройки запроса, будут записаны в журнал спана OpenTelemetry. Эта возможность особенно полезна в продакшн-средах для отслеживания изменений конфигурации, которые могут повлиять на производительность запросов.

<div id="integration-with-monitoring-systems">
  ## Интеграция с системами мониторинга
</div>

На данный момент не существует готового инструмента, который мог бы экспортировать данные трассировки из ClickHouse в систему мониторинга.

Для тестирования можно настроить экспорт с помощью materialized view с движком [URL](/docs/ru/reference/engines/table-engines/special/url) поверх таблицы [system.opentelemetry\_span\_log](/docs/ru/reference/system-tables/opentelemetry_span_log), которая будет отправлять поступающие записи журнала на HTTP-конечную точку коллектора трассировки. Например, чтобы отправлять минимальный набор данных спана в экземпляр Zipkin, работающий по адресу `http://localhost:9411`, в формате Zipkin v2 JSON:

```sql theme={null}
CREATE MATERIALIZED VIEW default.zipkin_spans
ENGINE = URL('http://127.0.0.1:9411/api/v2/spans', 'JSONEachRow')
SETTINGS output_format_json_named_tuples_as_objects = 1,
    output_format_json_array_of_rows = 1 AS
SELECT
    lower(hex(trace_id)) AS traceId,
    CASE WHEN parent_span_id = 0 THEN '' ELSE lower(hex(parent_span_id)) END AS parentId,
    lower(hex(span_id)) AS id,
    operation_name AS name,
    start_time_us AS timestamp,
    finish_time_us - start_time_us AS duration,
    cast(tuple('clickhouse'), 'Tuple(serviceName text)') AS localEndpoint,
    cast(tuple(
        attribute.values[indexOf(attribute.names, 'db.statement')]),
        'Tuple("db.statement" text)') AS tags
FROM system.opentelemetry_span_log
```

В случае ошибок соответствующая часть данных журнала будет незаметно потеряна. Если данные не поступают, проверьте журнал сервера на наличие сообщений об ошибках.

<div id="related-content">
  ## Материалы по теме
</div>

* Блог: [Создание решения для обсервабилити на базе ClickHouse — часть 2 — трейсы](https://clickhouse.com/blog/storing-traces-and-spans-open-telemetry-in-clickhouse)
