Sign In

PostgreSQL Monitoring

Monitor your PostgreSQL databases with OpenTelemetry


Overview

Monitor PostgreSQL performance and health using the OpenTelemetry Collector with the PostgreSQL receiver. Get visibility into connections, queries, replication, and resource usage.

What You'll Monitor

  • • Connection counts and pool usage
  • • Query performance and slow queries
  • • Database size and table statistics
  • • Replication lag
  • • Lock contention
  • • Buffer cache hit ratio

OpenTelemetry Collector Setup

Use the OpenTelemetry Collector with the PostgreSQL receiver to collect database metrics.

1. Create a Monitoring User

-- Create a dedicated monitoring user
CREATE USER qorrelate_monitor WITH PASSWORD 'secure_password';

-- Grant necessary permissions
GRANT pg_monitor TO qorrelate_monitor;

-- Or for older PostgreSQL versions (< 10):
GRANT SELECT ON pg_stat_database TO qorrelate_monitor;
GRANT SELECT ON pg_stat_bgwriter TO qorrelate_monitor;
GRANT SELECT ON pg_stat_activity TO qorrelate_monitor;

2. Configure the Collector

# otel-collector-config.yaml
receivers:
  postgresql:
    endpoint: localhost:5432
    username: qorrelate_monitor
    password: ${POSTGRES_PASSWORD}
    databases:
      - myapp_production
      - myapp_analytics
    collection_interval: 30s
    tls:
      insecure: false
      ca_file: /etc/ssl/certs/ca-certificates.crt

exporters:
  otlphttp:
    endpoint: https://qorrelate.io
    headers:
      Authorization: "Bearer ${QORRELATE_API_KEY}"
      X-Organization-Id: "${QORRELATE_ORG_ID}"

service:
  pipelines:
    metrics:
      receivers: [postgresql]
      exporters: [otlphttp]

3. Run the Collector

# Docker
docker run -v ./otel-collector-config.yaml:/etc/otel/config.yaml \
  -e POSTGRES_PASSWORD=secure_password \
  -e QORRELATE_API_KEY=your_api_key \
  -e QORRELATE_ORG_ID=your_org_id \
  otel/opentelemetry-collector-contrib:latest \
  --config=/etc/otel/config.yaml

# Or Kubernetes (add as sidecar or DaemonSet)

Available Metrics

Metric Description Type
postgresql.backends Active connections by database Gauge
postgresql.commits Committed transactions Counter
postgresql.rollbacks Rolled back transactions Counter
postgresql.db_size Database size in bytes Gauge
postgresql.rows_fetched Rows fetched by queries Counter
postgresql.rows_inserted Rows inserted Counter
postgresql.rows_updated Rows updated Counter
postgresql.rows_deleted Rows deleted Counter
postgresql.blocks_read Disk blocks read Counter
postgresql.blocks_hit Buffer cache hits Counter
postgresql.replication.lag Replication lag in bytes Gauge

Application-Level Query Tracing

To trace individual SQL queries from your application, use OpenTelemetry SDK instrumentation.

Python (psycopg2/asyncpg)

pip install opentelemetry-instrumentation-psycopg2
# or
pip install opentelemetry-instrumentation-asyncpg
from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor

# Auto-instrument all psycopg2 connections
Psycopg2Instrumentor().instrument()

# Your queries are now traced automatically
cursor.execute("SELECT * FROM users WHERE id = %s", [user_id])

Node.js (pg)

npm install @opentelemetry/instrumentation-pg
const { PgInstrumentation } = require('@opentelemetry/instrumentation-pg');

// Add to your instrumentation setup
instrumentations: [
  new PgInstrumentation({
    enhancedDatabaseReporting: true
  })
]

Java (JDBC)

<!-- The Java agent auto-instruments JDBC -->
<!-- Just run with: -javaagent:opentelemetry-javaagent.jar -->

Slow Query Logging

Configure PostgreSQL to log slow queries, then forward them to Qorrelate:

1. Enable Slow Query Logging in PostgreSQL

-- In postgresql.conf or via ALTER SYSTEM
ALTER SYSTEM SET log_min_duration_statement = '500';  -- Log queries > 500ms
ALTER SYSTEM SET log_statement = 'none';  -- Don't log all statements
SELECT pg_reload_conf();

2. Forward Logs to Qorrelate

# Add filelog receiver to collector
receivers:
  filelog:
    include: [/var/log/postgresql/*.log]
    operators:
      - type: regex_parser
        regex: '^(?P<timestamp>[\d-]+ [\d:.]+) .* LOG:  duration: (?P<duration>[\d.]+) ms  statement: (?P<query>.*)$'
      - type: add
        field: attributes.service.name
        value: postgresql

Pre-built Dashboard Queries

Use these PromQL queries to build your PostgreSQL dashboard:

Active Connections

sum by (database) (postgresql_backends)

Buffer Cache Hit Ratio

100 * sum(rate(postgresql_blocks_hit[5m])) / 
  (sum(rate(postgresql_blocks_hit[5m])) + sum(rate(postgresql_blocks_read[5m])))

Transaction Rate

sum(rate(postgresql_commits[5m])) + sum(rate(postgresql_rollbacks[5m]))

Rollback Ratio

100 * sum(rate(postgresql_rollbacks[5m])) / 
  (sum(rate(postgresql_commits[5m])) + sum(rate(postgresql_rollbacks[5m])))

Recommended Alerts

Connection Pool Exhaustion

postgresql_backends / postgresql_max_connections > 0.8

Alert when >80% of connections are in use

Replication Lag

postgresql_replication_lag_bytes > 104857600

Alert when replication lag exceeds 100MB

Low Cache Hit Ratio

100 * sum(rate(postgresql_blocks_hit[5m])) / 
  (sum(rate(postgresql_blocks_hit[5m])) + sum(rate(postgresql_blocks_read[5m]))) < 90

Alert when buffer cache hit ratio drops below 90%