RousselTMLEARNING

Article · SigNoz and ClickStack: observability on ClickHouse

Telemetry in ClickHouse

This article is available in French.

1. L'exportateur ClickHouse #

OpenTelemetry vers SQL.

Configuration #

# Collector OpenTelemetry (distribution contrib)
exporters:
  clickhouse:
    endpoint: tcp://clickhouse:9000?dial_timeout=10s
    database: otel
    username: otel
    password: ${env:CLICKHOUSE_PASSWORD}
    ttl: 168h                  # rétention 7 jours
    create_schema: true        # crée les tables au démarrage
    logs_table_name: otel_logs
    traces_table_name: otel_traces
service:
  pipelines:
    logs:   { receivers: [otlp], processors: [batch], exporters: [clickhouse] }
    traces: { receivers: [otlp], processors: [batch], exporters: [clickhouse] }

L'exportateur crée des tables otel_logs, otel_traces et otel_metrics_* (par type de métrique) au format MergeTree, triées pour les requêtes par service et par temps.

2. Interroger en SQL #

Les colonnes principales.

Requêtes #

TableColonnes utiles
otel_tracesTimestamp, TraceId, SpanId, ParentSpanId, SpanName, ServiceName, Duration (ns), StatusCode, SpanAttributes (Map)
otel_logsTimestamp, TraceId, ServiceName, SeverityText, Body, LogAttributes (Map), ResourceAttributes (Map)
-- Latence p95 par opération sur la dernière heure
SELECT ServiceName, SpanName,
       quantile(0.95)(Duration) / 1e6 AS p95_ms, count() AS spans
FROM otel.otel_traces
WHERE Timestamp > now() - INTERVAL 1 HOUR AND SpanKind = 'Server'
GROUP BY ServiceName, SpanName
ORDER BY p95_ms DESC LIMIT 10;

-- Logs d'erreur d'une trace lente, en une jointure
SELECT l.Timestamp, l.ServiceName, l.Body
FROM otel.otel_logs AS l
WHERE l.TraceId IN (
  SELECT TraceId FROM otel.otel_traces
  WHERE Timestamp > now() - INTERVAL 1 HOUR AND Duration > 2e9 LIMIT 100)
  AND l.SeverityText = 'ERROR'
ORDER BY l.Timestamp;

-- Attribut à haute cardinalité : top clients en erreur
SELECT SpanAttributes['client.id'] AS client, countIf(StatusCode = 'Error') AS erreurs
FROM otel.otel_traces WHERE Timestamp > now() - INTERVAL 1 DAY
GROUP BY client ORDER BY erreurs DESC LIMIT 10;

3. Rétention et performance #

TTL et vues matérialisées.

Réglages #

-- Modifier la rétention d'une table existante
ALTER TABLE otel.otel_logs MODIFY TTL toDateTime(Timestamp) + INTERVAL 14 DAY;

-- Pré-agréger les métriques RED par minute
CREATE MATERIALIZED VIEW otel.red_par_minute
ENGINE = SummingMergeTree ORDER BY (ServiceName, SpanName, minute) AS
SELECT ServiceName, SpanName, toStartOfMinute(Timestamp) AS minute,
       count() AS requetes, countIf(StatusCode = 'Error') AS erreurs
FROM otel.otel_traces WHERE SpanKind = 'Server'
GROUP BY ServiceName, SpanName, minute;

-- Place occupée et taux de compression
SELECT table, formatReadableSize(sum(data_compressed_bytes)) AS compresse,
       round(sum(data_uncompressed_bytes) / sum(data_compressed_bytes), 1) AS ratio
FROM system.parts WHERE database = 'otel' AND active GROUP BY table;
Bonne Pratique : Avec le plugin ClickHouse de Grafana, ces requêtes deviennent des panneaux, avec des liens vers les traces : une option intéressante pour une équipe déjà sur Grafana.

📄 Stocker et interroger la télémétrie directement dans ClickHouse →

My progress

  • ⏱ Estimated time : ≈ 7 min

Sign in to track your progress and take notes. Sign in

✉️ Ask a question

Recommended Articles

Understanding the concept of score

The concept of score allows Elasticsearch to rank your documents by relevance during a search.

Understanding the Elastic Common Schema (ECS)

As always in our consulting engagements, we recommend that companies harmonise and standardise: k...

License consumption types

Understand the evolution of billing in Dynatrace: the difference between the old licensing model ...

Grafana Alloy: The importance of Self-Monitoring

Discover why and how to configure Grafana Alloy so that it monitors itself, collecting its own lo...

Grafana Alloy: Understanding and exploiting the User Interface (UI)

Discover how to enable, secure, and use Grafana Alloy's built-in web interface to visualize your ...

Grafana Alloy: Introduction and Architecture

Discover the fundamental concepts of Grafana Alloy, the transition from the static Agent to Alloy...

Grafana Alloy: Syntax and Configuration (Alloy Language: River)

As part of a Grafana training or observability training, master the declarative syntax of Grafana...

Grafana Alloy: Metrics Collection (Prometheus & Ecosystem)

Learn how to configure Grafana Alloy to collect, transform, and forward metrics using the Prometh...

Grafana Alloy: Log Management with Loki

Discover how to configure Grafana Alloy to read log files, journald, or network streams, process ...