Skip to main content
Version: Dev

Export Request Traces to ClickHouse

AISIX gateways export request traces over OTLP/HTTP. You can send those traces directly to a ClickStack ingestion endpoint or run an OpenTelemetry Collector that writes them to an existing ClickHouse database.

Choose an Ingestion Path​

Choose the path that matches the ClickHouse service you operate:

DestinationPath
ClickStackSend traces to the OTLP/HTTP endpoint supplied by ClickStack. Its packaged Collector handles batching, schema management, and ClickHouse writes. Skip to Configure the AISIX Exporter.
Existing ClickHouse databaseDeploy the custom Collector configuration in this guide. The Collector receives traces from AISIX and writes them with the ClickHouse exporter.

For ClickStack, use the complete traces endpoint and authentication header shown by your deployment. A ClickStack OTLP/HTTP endpoint normally ends in /v1/traces. Self-managed ClickStack can use an ingestion key or OIDC bearer token, depending on how its packaged Collector is configured. See the ClickStack Collector guidance for the deployment options.

The remaining Collector deployment steps are for an existing ClickHouse database that does not already expose a suitable OTLP endpoint:

Prerequisites​

Before deploying the custom Collector path, prepare the following:

  • An AISIX Enterprise or AISIX Cloud environment with an attached gateway, or an AISIX OSS deployment that loads a declarative resources.yaml file.
  • An existing ClickHouse database and a write account. Decide whether the Collector may create its database and tables.
  • A working request through the gateway for verification.
  • Network access from the gateway to the Collector and from the Collector to ClickHouse.
  • Docker Compose or access to the Kubernetes namespace where the gateway runs.

This guide pins OpenTelemetry Collector Contrib 0.163.2. The ClickHouse exporter is included in that distribution, and its v0.163.0 component reference classifies traces support as beta. Review its stability and configuration before using it for production telemetry.

Configure the Collector​

The complete configuration below is for a new dedicated Collector. If you already operate a compatible Collector, merge these component definitions and pipeline references into its configuration without replacing unrelated components, then use its normal rollout process.

Create a working directory:

mkdir aisix-clickhouse
cd aisix-clickhouse

Create the following complete Collector configuration and replace the uppercase placeholders:

collector.yaml
extensions:
bearertokenauth:
token: 'COLLECTOR_TOKEN'

receivers:
otlp:
protocols:
http:
endpoint: '0.0.0.0:4318'
auth:
authenticator: bearertokenauth

exporters:
clickhouse:
endpoint: 'tcp://CLICKHOUSE_HOST:9000?dial_timeout=10s'
username: 'CLICKHOUSE_USER'
password: 'CLICKHOUSE_PASSWORD'
database: 'TARGET_DATABASE'
traces_table_name: 'TARGET_TRACES_TABLE'
create_schema: true
sending_queue:
num_consumers: 10
batch:
min_size: 5000
flush_timeout: 5s

service:
extensions: [bearertokenauth]
pipelines:
traces:
receivers: [otlp]
exporters: [clickhouse]

Replace the placeholders as follows:

Placeholder or fieldValue
COLLECTOR_TOKENA long random token. For example, generate one with openssl rand -hex 32. Use the same value in the AISIX exporter header.
CLICKHOUSE_HOST and port 9000The ClickHouse native endpoint reachable from the Collector. Use the port and TLS settings supplied by your database operator.
CLICKHOUSE_USER and CLICKHOUSE_PASSWORDA ClickHouse account that can insert traces and, when schema creation is enabled, create the target database and tables.
TARGET_DATABASEThe database that stores the trace table, such as aisix.
TARGET_TRACES_TABLEThe trace table name, such as otel_traces.
create_schemaKeep true to let the exporter create a compatible database and table. Set it to false only after your database operator creates a schema compatible with this exporter version.

The endpoint in this example uses the ClickHouse native protocol without TLS. Configure the exporter's TLS settings when traffic crosses an untrusted network or your database requires TLS. Keep credentials out of source control.

The internal sending_queue.batch block follows the ClickHouse exporter's current batching recommendation. It flushes a partial batch after five seconds, so low-volume verification does not wait for 5,000 rows. Do not add the standalone batch processor for this pipeline.

The queue is in memory and can lose pending traces if the Collector restarts. For restart durability, configure sending_queue.storage with a storage extension, add that extension to service.extensions, and mount its directory on durable storage.

Deploy the Collector​

Both examples run the Collector beside the gateway and make the OTLP/HTTP receiver available as otel-collector:4318.

Find the gateway container and its Docker networks:

docker ps --format 'table {{.Names}}\t{{.Image}}'
docker inspect GATEWAY_CONTAINER --format '{{json .NetworkSettings.Networks}}'

Replace GATEWAY_CONTAINER with the container name returned by docker ps. Select a user-defined network attached to the gateway. Create the following file beside collector.yaml, then replace GATEWAY_NETWORK with that network name:

compose.yaml
services:
otel-collector:
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.163.2
command: ['--config=/etc/otelcol-contrib/config.yaml']
volumes:
- ./collector.yaml:/etc/otelcol-contrib/config.yaml:ro
networks: [gateway]
restart: unless-stopped

networks:
gateway:
external: true
name: GATEWAY_NETWORK

Validate the configuration, start the Collector, and inspect its logs:

docker compose run --rm otel-collector validate --config=/etc/otelcol-contrib/config.yaml
docker compose up -d
docker compose logs --tail=100 otel-collector

The gateway can now reach the receiver at http://otel-collector:4318/v1/traces. Ensure the selected network also lets the Collector reach ClickHouse.

These deployment examples use one Collector replica and do not set resource limits. Size the Collector, queue, and availability model for your trace volume before using this path in production.

Configure the AISIX Exporter​

Export the gateway URL and request values used for verification:

# AISIX_PROXY has no trailing slash or endpoint path
# The local quickstarts use http://127.0.0.1:3000
export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export MODEL_ALIAS="YOUR_MODEL_ALIAS"

For the custom Collector deployment above, export the receiver URL and authentication header:

export OTLP_ENDPOINT="http://otel-collector:4318/v1/traces"
export OTLP_AUTH_HEADER="Bearer YOUR_COLLECTOR_TOKEN"

For ClickStack, replace these values with its complete OTLP/HTTP traces endpoint and the exact authorization value required by its ingestion setup.

The Dev gateway accepts http:// and https:// exporter endpoints on any host. With http://, the authorization header and exported telemetry cross the network in plaintext. Use it only on a network you trust, especially when full content capture is enabled.

Follow Configure an OTLP Exporter to create the exporter through AISIX Enterprise, AISIX Cloud, or AISIX OSS. Keep sample_rate at 1 until delivery is verified. A saved exporter confirms only that AISIX accepted the configuration.

Verify Delivery​

Send a successful request through an existing model alias and save the response headers:

curl -sS -D aisix-response.headers -o /dev/null \
-X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer $AISIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${MODEL_ALIAS}"'",
"messages": [{"role": "user", "content": "Reply with: ClickHouse trace check"}]
}'

export TEST_REQUEST_ID=$(awk 'tolower($1) == "x-aisix-request-id:" {id=$2; sub(/\r$/, "", id)} END {print id}' aisix-response.headers)
printf 'request ID: %s\n' "$TEST_REQUEST_ID"

If the ID is empty, confirm that the request passed through AISIX and succeeded before checking the export path.

For ClickStack, search its trace view for this request ID. For the custom Collector path, wait at least five seconds for the configured partial batch to flush, then query the target table:

SELECT
Timestamp,
SpanName,
SpanKind,
TraceId,
SpanId,
ParentSpanId,
SpanAttributes['aisix.request_id'] AS request_id,
SpanAttributes['http.response.status_code'] AS status
FROM aisix.otel_traces
WHERE Timestamp >= now() - INTERVAL 15 MINUTE
AND SpanAttributes['aisix.request_id'] = 'YOUR_RETURNED_REQUEST_ID'
ORDER BY Timestamp ASC;

Replace the request ID, database, and table names with your values. A typical model request that reaches an upstream produces a SERVER span, a logical CLIENT span, and an attempt CLIENT span. Other outcomes can produce fewer spans, so finding the request ID is the delivery check; a fixed row count is not.

Troubleshoot Delivery​

For ClickStack, check its ingestion status or packaged Collector logs, then confirm that the AISIX endpoint and authorization header match the values ClickStack provides.

For the custom Collector path, inspect both the gateway and Collector logs before changing the configuration:

Replace GATEWAY_CONTAINER with the gateway container name used during deployment:

docker compose ps
docker compose logs --since=10m otel-collector
docker logs --since=10m GATEWAY_CONTAINER
SymptomCheck
Receiver returns 401 or 403The Collector token, the AISIX Authorization header, and the space after Bearer.
DNS or connection failureService names, namespaces, Docker networks, NetworkPolicies, and the ClickHouse host and port.
Database authentication, schema, or insert errorClickHouse credentials, permissions, TLS settings, and schema compatibility with the pinned exporter.
Exporter is configured but no current rows appearThe target gateway, sample rate, request ID, batching delay, and query time range.
Repeated Collector restartsThe pinned image, unresolved placeholders, configuration syntax, resource limits, and workload logs.

For AISIX Enterprise or AISIX Cloud, the exporter row in the environment's Observability view also shows delivery health reported by online gateways. For AISIX OSS, use the gateway logs and the destination result.

Stop Exporting​

Disable or remove the AISIX exporter through the same configuration path used to create it. For ClickStack, no change to its packaged Collector is required. For the custom Collector path, keep a shared Collector running for its other pipelines. If the ClickHouse pipeline is no longer needed, remove only its receiver and exporter references through your normal Collector rollout process; existing database records are unaffected.

Next Steps​

See Observability Exporters for sampling, content capture, trace structure, and gateway delivery behavior. Use the ClickHouse exporter reference for schema, retention, queue, and database options.