PgBouncer puede “hablar” muchísimo… o lo justo y necesario. En producción, lo que quieres es:
saber quién se conecta y desde dónde,
detectar cola / saturación del pool,
ver errores reales (auth, TLS, backend caído),
y poder hacer troubleshooting sin subir a debug por horas.
Este post te deja un set de logs “mínimo útil”, qué significa cada cosa y qué patrones vigilar.
1) El objetivo: logs accionables (no ruido)
Logs que SÍ quieres
Conexiones / desconexiones
Errores que se le devuelven al cliente (pooler errors)
Eventos de backend (Postgres no reachable, auth al backend, reset)
Auth/TLS (fallos de SASL, certificados, etc.)
Reload/arranque (para confirmar que cambios se aplicaron)
Logs que NO quieres 24/7
Verbosidad alta permanente (te mata el disco y te oculta la señal)
Dumps excesivos en horas pico (empeoran el rendimiento y el diagnóstico)
2) Configuración recomendada de logging (baseline de producción)
En pgbouncer.ini:
[pgbouncer] ; Dónde loguear logfile = /var/log/pgbouncer/pgbouncer.log ; o alternativa: ; syslog = 1 ; syslog_ident = pgbouncer ; Señal útil log_connections = 1 log_disconnections = 1 log_pooler_errors = 1 ; Verbosidad (0–3). Producción: 0 o 1 verbose = 0
Qué te da esto:
trazabilidad básica de quién entra/sale,
errores que importan (los que impactan a la app),
sin inundarte.
Tip: si estás en systemd, muchas veces conviene log a journald y usar journalctl -u pgbouncer (y/o forward a tu stack de logs). Si ya tienes ELK/Loki/Datadog, syslog/journald suele ser más cómodo que un archivo.
3) Los 3 flags que más valor dan
log_connections
Registra conexiones exitosas.
Útil para auditoría ligera (“¿están conectando desde donde deben?”)
Útil para detectar picos raros (cambios en el patrón de conexiones)
log_disconnections
Registra desconexiones + motivo.
Aquí aparecen timeouts, resets, “client disconnected”, etc.
Es clave para ver “se corta cada X segundos” (típico de healthchecks mal configurados o timeouts agresivos)
log_pooler_errors
Este es oro: loguea los errores que PgBouncer le entrega al cliente.
Si Odoo dice “auth failed” o “no such user”, aquí suele quedar el rastro real.
Si hay “too many connections” o “pool is full”, también.
4) Cuándo subir verbose (y cómo hacerlo bien)
No lo dejes alto permanente. Úsalo como “modo lupa”.
Procedimiento sano
Sube verbose a 1 o 2 por ventana corta
Reproduce el problema
Baja de vuelta
verbose = 2
Buenas prácticas
Si subes verbosidad en hora pico, hazlo 2–5 minutos, no 2 horas.
Acompáñalo con un “marcador” en logs (anota hora exacta del cambio).
5) Los patrones de log que realmente te importan
A) Auth fallando (cliente → PgBouncer)
Qué vas a ver (conceptualmente):
usuario inexistente (“no such user”)
password/SCRAM inválido (“SASL authentication failed”, “password authentication failed”)
HBA de PgBouncer (si usas auth_type=hba)
Qué hacer
Confirmar que el usuario existe en userlist.txt o que auth_user/auth_query está bien
Confirmar que hiciste RELOAD (muchos “no funciona” son “no recargué”)
B) PgBouncer acepta al cliente, pero falla hacia Postgres (backend)
Esto es el caso típico de “Odoo conecta pero luego explota al ejecutar cosas”.
Verás mensajes como:
“server login failed”
“cannot connect to server”
“FATAL” de Postgres propagado
timeouts de conexión al backend
Qué significa
PgBouncer está bien, el problema es la conexión server (network, TLS, credenciales, Postgres saturado, pg_hba.conf, etc.)
C) Saturación del pool (cola)
En logs lo verás como:
“no more connections allowed”
errores de pool/limits
clientes que se desconectan por timeout
Lo correcto
No adivines: confirma con métricas (SHOW POOLS;) y correlación con crons/transacciones largas.
Si el pool está “secuestrado”, subir pool_size no siempre arregla (a veces solo empeora Postgres).
D) Problemas de TLS
Si activas TLS, los logs de valor son:
handshake failures
CA/hostname mismatch (en verify)
certificados expirados
protocolos/ciphers incompatibles
Clave operativa
estos errores suelen ser “binarios”: o conectas o no conectas, así que el log te permite arreglar rápido (cert, CA, SNI/hostname, clock skew).
6) Logs vs comandos SHOW: cómo combinarlos
Los logs te dicen “qué pasó”.
Los SHOW te dicen “cómo está ahora”.
Cuando hay incidentes, usa ambos:
Logs: qué error exacto y desde qué IP/usuario
SHOW POOLS;: hay cola real o no
SHOW SERVERS;: qué conexiones están ocupadas
Postgres: pg_stat_activity para transacciones largas/locks
Esto evita el error típico de “subí pool_size y listo” cuando el problema era un lock eterno.
7) Rotación de logs (lo que casi todos olvidan)
Si logueas a archivo (logfile = ...), define rotación con logrotate.
Después de rotar, a veces necesitas que PgBouncer reabra el archivo (dependiendo del método). Lo común es enviar HUP o usar RELOAD (según cómo lo operes).
Checklist mínimo
rotate diario/semanal
compresión
retención razonable
alertas si el disco sube de cierto %
8) “Nivel pro”: qué alertar desde logs (sin métricas aún)
Si todavía no tienes Prometheus/Grafana, puedes sacar alertas desde logs:
auth failures > X/min
backend connect failures > X/min
errores de pool/limits (cualquier aparición = alerta)
TLS handshake errors (cualquier aparición = alerta)
reinicios/reloads inesperados (cambio de config fuera de ventana)
9) Configs que suelen crear ruido inútil
verbose alto permanente
log_connections + muchísimos healthchecks que abren/cierra conexiones (ruido). Mejor: healthchecks menos agresivos o conexión persistente.
cambios de config sin “marcador” (luego no sabes qué correlacionar)
Cierre
Si tienes PgBouncer en producción, el set “que sí importa” es:
log_connections=1
log_disconnections=1
log_pooler_errors=1
verbose=0 (y subirlo solo para incidentes)
rotación bien hecha