メインコンテンツへスキップ
メインコンテンツへスキップ

OpenTelemetry による ClickHouse のトレーシング

OpenTelemetry は、分散アプリケーションからトレースとメトリクスを収集するためのオープンな標準仕様です。ClickHouse は OpenTelemetry を一部サポートしています。

ClickHouse へのトレースコンテキストの指定

ClickHouse は、W3C 勧告 で説明されているトレースコンテキスト HTTP ヘッダーを受け付けます。また、ClickHouse サーバー間やクライアントとサーバー間の通信に使用されるネイティブプロトコルを介して渡されるトレースコンテキストも受け付けます。手動でテストする場合、Trace Context 勧告に準拠したトレースコンテキストヘッダーは、clickhouse-client に対して --opentelemetry-traceparent および --opentelemetry-tracestate フラグを使用して指定できます。

親トレースコンテキストが指定されていない場合、または指定されたトレースコンテキストが上記の W3C 標準に準拠していない場合、ClickHouse は新しいトレースを開始します。その発生確率は、opentelemetry_start_trace_probability 設定で制御されます。

トレースコンテキストの伝播

トレースコンテキストは、次の場合に下流のサービスへ伝播されます。

  • Distributed テーブルエンジンを使用する場合など、リモートの ClickHouse サーバーに対してクエリを実行する場合。

  • url テーブル関数を使用する場合。この場合、トレースコンテキスト情報は HTTP ヘッダーで送信されます。

ClickHouse 自体のトレース

ClickHouse は、各クエリおよびクエリ計画や分散クエリなど一部のクエリ実行ステージごとに trace spans を作成します。

トレース情報を有用にするには、JaegerPrometheus など、OpenTelemetry をサポートするモニタリングシステムにエクスポートする必要があります。ClickHouse は特定のモニタリングシステムへの依存を避け、代わりにシステムテーブルを通じてのみトレースデータを提供します。標準で要求されている OpenTelemetry のトレーススパン情報は、system.opentelemetry_span_log テーブルに保存されます。

このテーブルを利用するには、サーバー設定で有効化されている必要があります。デフォルトの設定ファイル config.xml 内の opentelemetry_span_log 要素を参照してください。デフォルトでは有効になっています。

タグまたは属性は、キーと値を含む 2 つの並列配列として保存されます。これらを扱うには ARRAY JOIN を使用します。

Log-query-settings

log_query_settings 設定を有効にすると、クエリの実行中に行われたクエリ設定の変更内容をログとして記録できるようになります。有効化されている場合、クエリ設定に対して行われたあらゆる変更は OpenTelemetry のスパンログに記録されます。この機能は、本番環境においてクエリ性能に影響を与えうる設定変更を追跡するのに特に有用です。

監視システムとの統合

現時点では、ClickHouse から監視システムへトレースデータをエクスポートするための既製ツールは用意されていません。

テスト用途として、system.opentelemetry_span_log テーブルに対して URL エンジンを使用したマテリアライズドビューをセットアップすることで、受信したログデータをトレースコレクターの HTTP エンドポイントに送信できます。例えば、http://localhost:9411 で稼働している Zipkin インスタンスに、Zipkin v2 の JSON フォーマットで最小限の span データを送信するには、次のようにします。

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

エラーが発生した場合、そのエラーが発生した対象のログデータの一部は、エラーを通知することなく失われます。データが届かない場合は、サーバーログでエラーメッセージを確認してください。