Skip to main content
Collect PostgreSQL CSV logs with an OpenTelemetry collector and send them to ClickHouse Observability. Use the demo dataset to try the integration without installing PostgreSQL.

Prerequisites

  • A ClickHouse Observability service
  • Docker to run the collector examples
  • For your own logs, PostgreSQL 14 or newer and access to its configuration and log files
  • For the demo, curl to download the sample

Connection details

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.
The endpoint must be reachable from the collector container. For a destination collector running on this computer, use http://host.docker.internal:4318. The Docker commands below include the host mapping.

Integration with existing PostgreSQL

1

Configure PostgreSQL logging

Find your configuration file by running this SQL as a database administrator:
Add or update these settings in postgresql.conf:
Create the log directory with ownership and permissions that let PostgreSQL write and the collector read it. For containerized PostgreSQL, mount that directory so the collector can access the same files. CSV output uses a .csv extension even though log_filename ends in .log.Restart PostgreSQL using your deployment process, for example:
Check the active CSV file:
The parser below expects the 26-column PostgreSQL CSV format. Earlier PostgreSQL versions and other log formats require a different parser.
2

Configure the collector

Save this as postgres-logs-monitoring.yaml:
The receiver parses multiline CSV entries, preserves their timestamps and bodies, and adds service.name as postgresql-service. Fields such as database_name, error_severity, message, and query remain available as log attributes.
3

Run the collector

From the directory containing the configuration, run the following command. Adjust the host log directory if needed. With group-readable log files, add --group-add LOG_GROUP_ID, using the numeric group ID shown by ls -ln /var/log/postgresql.
Leave the terminal open. The receiver uses start_at: end, so create a new database connection or execute a query that produces an error after starting the collector:
4

Verify logs

Open Search, select Logs, filter for ServiceName:postgresql-service, and select Last 15 minutes. Expand a record to inspect its PostgreSQL attributes and severity.

Demo dataset

The sample contains 21,325 PostgreSQL CSV records covering connection activity, queries, and server errors.
1

Download the sample dataset

2

Configure the demo collector

Save this as postgres-logs-demo.yaml:
The demo-only timestamp processor shifts the sample into the past 24 hours, ending two minutes before ingestion. Original timestamp attributes and log bodies stay unchanged. Omit this processor for your own PostgreSQL logs.
3

Run the demo collector

From the directory containing the configuration and downloaded log file, run:
Leave the terminal open while verifying ingestion. Stop the collector with Ctrl+C when finished. Running the demo again re-ingests the sample with refreshed timestamps.
4

Verify the demo logs

Open Search, select Logs, filter for ServiceName:postgresql-demo, and select Last 2 days. Expand a record to inspect fields such as database_name, error_severity, message, and query.

Dashboards and visualization

1

2

Import the dashboard

  1. Open Dashboards and click Import in the upper-right corner.
  2. Upload postgresql-logs-dashboard.json.
  3. Map the charts to your Logs source and click Finish Import.
3

View the dashboard

Select Last 2 days for the sample and optionally filter for ServiceName:postgresql-demo. For your own logs, filter for ServiceName:postgresql-service and choose a time range covering your records.

Troubleshooting

Collector fails to start

Check the collector output for configuration errors. Verify the configuration mount and connection variables in the terminal where Docker runs.

No logs appear

Check for authentication or export errors. Confirm the CSV path with pg_current_logfile, ensure the files match the receiver’s include pattern, and check that the collector can read them. With start_at: end, only new entries are collected. For the demo, include the timestamp processor and select Last 2 days.

Permission denied

PostgreSQL normally creates owner-only log files. The configuration above uses log_file_mode = 0640 to allow group reads; add the file’s group to the collector container with --group-add. Existing files keep their previous permissions. Ensure the directory also permits group access.

CSV parsing errors

The parser expects 26 columns from PostgreSQL 14 or newer. Confirm log_destination = 'csvlog' and log_timezone = 'UTC'. Adjust the header for older versions or custom formats; stderr and JSON logs cannot use this CSV parser.

Next steps