La tua applicazione è strumentata con OpenTelemetry e vedi tutte le tracce delle query a PostgreSQL. Ma quando le performance calano, ti mancano informazioni cruciali: quante connessioni attive ci sono? Quali query consumano più risorse? PostgreSQL è il collo di bottiglia?
Per rendere il sistema completamente osservabile, dobbiamo raccogliere telemetria anche da PostgreSQL stesso. In questo articolo vedremo come usare OpenTelemetry Collector per ottenere questi dati.
Come recuperare dati di telemetria da PostgreSQL
Al fine di poter rendere sempre più osservabile il nostro sistema andando a raccogliere i dati di telemetria da PostgreSQL andremo a vedere 3 alternative, ognuna con i propri pro e contro.
1) postgresql receiver
È il receiver specifico del Collector in versione contrib ed è nativo per PostgreSQL.
Si connette ad un’istanza di PostgreSQL e dalle viste specifiche (pg_stat_database
, pg_stat_activity
, pg_stat_statements
, …) produce metriche pronte, permettendo di scegliere da quali database raccogliere i dati. Tramite configurazione si può inoltre settare l’intervallo di campionamento, endpoint, protocollo ed altro.
È particolarmente consigliato per iniziare a raccogliere i dati principali con il minimo sforzo. Vedremo più sotto un esempio completo.
✅ Vantaggi
- Integrazione nativa
- Configurazione semplice
- Supporto a query sample e top query
❌ Svantaggi
- Stato beta: possibili cambiamenti negli upgrade
- Richiede OpenTelemetry Collector contrib
2) sqlquery receiver
È il receiver specifico del Collector in versione contrib ed è generico. Permette di collegarsi a diversi database, in particolare a tutti quelli per cui esiste un driver in Go. I più comuni sono PostgreSQL, SqlServer, SAP HANA, Oracle, MySQL, SQLite.
Un’altra differenza sostanziale rispetto al postgresqlreceiver è che in questo caso non ci sono metriche pronte ma si devono specificare le query per ottenere le metriche. Ovviamente questo offre il massimo della flessibilità ma la configurazione diventa più complessa.
È consigliato per lavorare di fino e se si sa già cosa occorre raccogliere mentre diventa sconsigliato come punto di partenza.
Per vedere un esempio completo del sqlquery receiver lo puoi trovare qui: configurazione sqlquery receiver.
✅ Vantaggi
- Massima flessibilità
- Misuri indicatori specifici del tuo dominio
❌ Svantaggi
- Configurazione più complessa
- Stato alpha: possibili cambiamenti negli upgrade
- Richiede OpenTelemetry Collector contrib
3) postgres_exporter + Prometheus
Lo standard de facto nel mondo Prometheus: un exporter dedicato espone metriche che poi vengono raccolte da Prometheus. Il Collector può integrare questi dati tramite prometheusreceiver
. Ha il grande vantaggio di essere il più conosciuto e consolidato per la produzione ma ha, a mio avviso, lo svantaggio di un’architettura più complessa con la necessità di aggiungere un ulteriore strato con Prometheus.
✅ Vantaggi
- Soluzione consolidata e matura
❌ Svantaggi
- Architettura più complessa: exporter + Prometheus + Collector
- Non è nativo OpenTelemetry
Esempio di receiver PostgreSQL
In questo esempio vedremo come usare il postgresql receiver dal Collector contrib come container. Per prima cosa si deve configurare l’endpoint, username e password per la connessione.
La configurazione dei database è opzionale, lasciando vuota raccogliere da tutti i database, mentre se occorre semplicemente escludere qualche database si può usare exclude_databases.
A titolo di esempio ho anche aggiunto alcuni attributi e poi fatta l’esportazione verso un endpoint che riceve via OTLP.
receivers:
postgresql:
endpoint: "host.docker.internal:5432"
transport: tcp
username: devpills_monitor
password: StrongPwd
databases: ["postgres"]
collection_interval: 10s
tls:
insecure: true
exporters:
otlp:
endpoint: "host.docker.internal:4317" # invia metriche al collector sulla macchina host
tls:
insecure: true
processors:
attributes/add_custom_tags:
actions:
- key: environment
value: production
action: insert
resource/pg:
attributes:
- key: service.name
value: devpills_pgreceiver
action: upsert
- key: service.version
value: 1.0.0
action: insert
batch: {}
service:
pipelines:
metrics:
receivers: [postgresql]
processors: [attributes/add_custom_tags, resource/pg, batch]
exporters: [otlp]
Trovi l’esempio completo qui: configurazione PostgreSQL receiver.
Questa è solo una demo, per la sicurezza in produzione ricorda di creare un utente dedicato con solo i permessi minimi e ruolo pg_monitor, configura TLS e gestisci le credenziali tramite variabili d’ambiente o secrets.
-- Abilita l'estensione per statistiche delle query
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Esempio di utente dedicato per monitoring
CREATE USER devpills_monitor WITH PASSWORD 'StrongPwd';
GRANT CONNECT ON DATABASE postgres TO devpills_monitor;
GRANT pg_monitor TO devpills_monitor;
Ricorda inoltre di configurare l’intervallo di campionamento appropriato per il tuo carico.
Con questo esempio raccogli già metriche importanti, come:
- postgresql_connections: numero di connessioni attive, idle e totali per database
- postgresql_max_connections: limite massimo di connessioni configurato
- postgresql_db_size: dimensione in byte di ogni database
- postgresql_commits: numero di transazioni committate
- postgresql_rollbacks: numero di transazioni annullate
- postgresql_table_size: dimensione delle tabelle
- postgresql_table_vacuum_count: contatori delle operazioni di vacuum
- postgresql_rows_: contatori di inserimenti, aggiornamenti, cancellazioni
L’elenco completo lo trovi qui: documentazione delle metriche PostgreSQL.
Conclusioni
Per iniziare ti consiglio di partire dal postgresqlreceiver
: è il modo più semplice per raccogliere le metriche fondamentali di PostgreSQL con il minimo sforzo.
Quando avrai esigenze più specifiche, potrai passare al sqlqueryreceiver
per definire query personalizzate che riflettano i KPI del tuo dominio.
Se invece utilizzi già Prometheus in produzione, il postgres_exporter
rimane la scelta più naturale e consolidata.
In ogni caso, il grande vantaggio dell’OpenTelemetry Collector è che puoi centralizzare tutto in un’unica pipeline di telemetria, disaccoppiando la logica delle tue applicazioni dalla raccolta dei dati.