Prerequisites
- A ClickHouse Observability service
- Docker to run the collector commands below, or an existing OpenTelemetry Collector Contrib deployment
- For your own logs, an existing Nginx installation, permission to edit its configuration, and access to its log files from the collector
Connection details
- Fully managed
- Self-managed
Open ClickHouse Observability and go to Team Settings → Data → Managed Telemetry. Copy your OTLP HTTP endpoint and API key. You can use Copy connection details to copy the configuration, or Reveal key to view the masked key.For the OTLP exporter examples below, set these variables in the terminal where you will run the collector:Replace the placeholders with the exact endpoint, including its port, and API key from your service. Use the base HTTP endpoint without a
/v1/logs suffix; the exporter appends the signal path.host.docker.internal instead of localhost. On Linux, use a shared Docker network and the destination container’s name, or another reachable host address.
Integration with existing Nginx
Run a collector on a host that can read your Nginx access logs. The collector parses the logs and forwards them to your service’s OTLP HTTP endpoint.1
Configure Nginx log format
Configure Nginx to write JSON access logs in This format uses the same field names as the demo dataset, including
nginx.conf.The nginx.conf file is typically located at:- Linux (apt/yum):
/etc/nginx/nginx.conf - macOS (Homebrew):
/usr/local/etc/nginx/nginx.confor/opt/homebrew/etc/nginx/nginx.conf - Docker: Configuration is usually mounted as a volume
http block. Keep the rest of your configuration, and replace any existing access_log directive for the same file:request, which contains the method, URI, and HTTP version. upstream_response_time is kept as a string because Nginx can report multiple upstream timings. The demo dataset contains a single numeric value for this field.Validate the configuration with nginx -t, then reload Nginx using your deployment’s normal procedure. If a server or location block overrides access_log, update that directive to use json_combined too.2
Configure the collector
Get your connection details and set the endpoint and API-key environment variables in the terminal where you will run the collector. Save the following complete configuration as This configuration reads new JSON access-log entries, preserves their original timestamps, and sets
nginx-monitoring.yaml:service.name to nginx. It forwards logs to your OTLP HTTP endpoint using the authentication settings above. Nginx error logs require a separate parser and are not included.3
Run the collector
The following command assumes the log directory is The collector runs in the foreground and must have permission to read the mounted log files. Leave it running and generate a few requests to Nginx from another terminal or browser so it writes new access-log entries.
/var/log/nginx on the Docker host. Adjust the host side of the log mount if your files are elsewhere. For containerized Nginx, mount its shared log volume into the collector instead.From the directory containing nginx-monitoring.yaml, run:4
Verify logs in ClickHouse Observability
- Open Search in your UI and select Logs.
- Filter for
ServiceName:nginxand select a time range covering your requests. - Expand an entry and select Column Values to check fields such as
request,request_time, andupstream_response_timeunderLogAttributes.
ServiceName:nginx-demo:Demo dataset
The sample dataset contains 14,743 JSON access-log entries with successful requests, errors, and upstream response timings. You need Docker and a ClickHouse Observability service. Set the connection environment variables before starting, and keep the downloaded file and configuration in the same directory.1
Download the sample dataset
2
Create test collector configuration
Save the following complete configuration as The standalone collector examples use OpenTelemetry Collector Contrib
nginx-demo.yaml. The collector reads the downloaded access logs and forwards them to your OTLP endpoint.The demo-only
transform/demo_timestamps processor shifts the sample’s timestamps to roughly the past 24 hours, ending two minutes before ingestion, while retaining its traffic pattern. The original time_local attribute and log body stay unchanged. Omit this processor for your own Nginx logs so their original timestamps are preserved.0.161.0, the version used to validate these configurations.3
Run the demo collector
From the directory containing Leave this terminal open while you verify ingestion. Both mounted files must be readable by the container. After the logs appear, press Ctrl+C to stop the demo collector. Running it again re-ingests the dataset with newly shifted timestamps because this demo does not persist file offsets.
access.log and nginx-demo.yaml, run the OpenTelemetry Collector Contrib image:4
Verify logs in ClickHouse Observability
Once the collector is running:
- Open your UI.
- Navigate to Search, select Logs, and filter for
ServiceName:nginx-demo. - Set the time range to Last 2 days to include the full shifted dataset.
LogAttributes.Dashboards and visualization
Import a dashboard for request counts, errors, status codes, and average upstream response time.1
Download the dashboard configuration
.
2
Import the pre-built dashboard
- Open ClickHouse Observability and navigate to Dashboards.
- Click Import in the upper-right corner.
- Upload
nginx-logs-dashboard.json. Confirm that all five charts map to the Logs data source, then click Finish Import.
3
View the dashboard
Filter the dashboard to
ServiceName:nginx-demo for the demo dataset, or ServiceName:nginx for your own logs. Set the time range to cover the ingested records. For the demo, select Last 2 days.The following dashboard shows the demo dataset:Troubleshooting
Collector fails to start
Check the collector’s terminal output for configuration errors. Confirm that the YAML file exists at the mounted path. If you use the OTLP exporter configuration, check that the endpoint variable and any required authentication variable are set in the terminal where you run Docker.No logs appearing
- Check the collector output for authentication or export errors. If you use the OTLP exporter, verify the endpoint and authorization header against your connection details.
- Confirm Nginx is writing JSON access logs and that the collector can read them. With
start_at: end, generate new requests after the collector starts. - Check the selected Logs source and service-name filter:
ServiceName:nginx-demofor the demo dataset, orServiceName:nginxfor your own logs. - Set the time range to cover the logs. For the demo, confirm
transform/demo_timestampsis included in the pipeline and select Last 2 days.
CONTAINER_NAME with your collector container’s name, and adjust the host path if needed:
Next steps
- Set up alerts for error rates or latency thresholds.
- Create additional dashboards.
- See Sending OpenTelemetry data for more collector configuration guidance.