Prerequisites
- A ClickHouse Observability service
- For your own traces, an Nginx installation with the OpenTelemetry module and permission to update its configuration; the Docker example below uses
nginx:1.27-otel - For the demo dataset,
curland Docker
Connection details
- Fully managed
- Self-managed
Open ClickHouse Observability and go to Team Settings → Data → Managed Telemetry. Copy your endpoint and API key using Copy connection details, or select Reveal key to view the masked key.The Nginx module exports over OTLP/gRPC, normally on port 4317. The JSON demo uses OTLP/HTTP, normally on port 4318. Use the endpoint for the matching protocol, including Replace the placeholders with your service’s connection details. Use the base HTTP endpoint without
https:// when TLS is required:/v1/traces; the collector exporter adds that path.host.docker.internal to reach a collector on the host. For containers on a shared Docker network, use the collector’s container name. Use http:// for a local endpoint without TLS.
Integration with existing Nginx
1
Install the OpenTelemetry Nginx module
The
nginx:1.27-otel image includes ngx_otel_module.so. For an installation outside Docker, follow the installation instructions linked from the Nginx OpenTelemetry module documentation.2
Configure Nginx tracing
The following Docker example uses a template so the container’s startup script substitutes the connection environment variables. Save it as Save this as The substitution filter preserves Nginx variables such as
nginx.conf.template. The return 200 location provides a simple smoke test; for your application, retain your existing server and routing configuration and add the tracing directives shown here.compose.yaml in the same directory:$request_method and $uri. Nginx does not automatically substitute shell environment variables in a directly mounted nginx.conf. Outside Docker, replace the connection placeholders with their actual values before validating the configuration, and restrict access to the file containing the key.3
Validate and start Nginx
Set the connection variables in the same terminal, then run:Each request creates a span with the method, path, status code, and duration. For an existing deployment, generate requests to your application’s URL. After changing the template or environment variables, run
docker compose up -d --force-recreate nginx to apply them.4
Verify traces in the UI
Open Search, select Traces, and filter for
ServiceName:nginx-proxy. Select a time range covering your requests and allow a few seconds for export. Open a trace to inspect its spans and HTTP attributes.Demo dataset
The sample contains 1,000 Nginx spans across nine endpoints, with successful requests, HTTP errors, and varied latencies. Set the connection variables before sending it.1
Download the sample dataset
2
Configure the demo collector
Save the following as
nginx-traces-demo.yaml in the download directory:The demo-only
transform/demo_timestamps processor shifts this sample into roughly the past 24 hours, ending two minutes before ingestion, while preserving span durations and the traffic pattern. Omit this processor for your own Nginx traces so their original timestamps are preserved. Sending the sample again can produce duplicate spans.3
Run the demo collector
For a destination collector running on this computer, set
OTEL_EXPORTER_OTLP_ENDPOINT to http://host.docker.internal:4318. The command below includes the Docker host mapping.0.161.0 from the directory containing the configuration, in the terminal where you set the connection variables. Keep this terminal open:14318 to avoid conflicting with an existing collector on port 4318. The collector forwards the traces to your configured endpoint using the authentication settings above.4
Send the traces
In another terminal, from the download directory, send the original sample to the local collector:An empty success response such as
{} or {"partialSuccess":{}} indicates the local collector accepted the request. Check the collector’s output for export errors and allow a few seconds for the batch to reach your service. Stop the demo collector with Ctrl+C when finished.5
Verify the demo traces
Open Search, select Traces, filter for
ServiceName:nginx-proxy, and select Last 2 days to include the full shifted dataset. Open a trace to inspect the HTTP attributes.Dashboards and visualization
1
Download the dashboard configuration
.
2
Import the dashboard
- Open Dashboards and click Import in the upper-right corner.
- Upload
nginx-traces-dashboard.json. - Map the charts to your Traces source and click Finish Import.
3
View the dashboard
Filter for
ServiceName:nginx-proxy and select a time range covering your traces. For the demo, select Last 2 days.Troubleshooting
Nginx fails to start
Rundocker compose run --rm nginx nginx -t to validate the generated configuration. An unknown otel_* directive or missing module file means the module is not installed or loaded. Check that you are using the -otel image and that the template is mounted at the documented path.
No traces appearing
- Verify the gRPC endpoint and any authentication required by your destination collector. Managed services use the
Bearerprefix. Do not use the HTTP endpoint for the Nginx module. - Confirm the endpoint is reachable from the Nginx container and that its scheme matches the destination’s TLS configuration.
- Generate requests; an idle Nginx instance produces no request spans.
- Check Traces, the service-name filter, and the selected time range. For the demo, confirm
transform/demo_timestampsis included in the collector pipeline and select Last 2 days. - For the demo, check the collector terminal for authentication or export errors. Verify its HTTP endpoint and authorization value against your connection details.
- Inspect Nginx errors with
docker compose logs nginx. Outside Docker, inspect your Nginx error log.
Next steps
- Set up alerts for errors or latency thresholds.
- Create additional dashboards.
- For a collector between Nginx and your destination, see Sending OpenTelemetry data.