Watchlog DocsWatchlog Docs
Home
Get Started
Gen AI Monitoring
Integrations
Log Watchlist
Home
Get Started
Gen AI Monitoring
Integrations
Log Watchlist
  • All Integrations
  • NGINX

    • Nginx Integration
    • Connect NGINX to Watchlog
    • Docker
    • Windows
    • Kubernetes
    • Source Code
  • IIS

    • IIS Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • REDIS

    • Redis Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • POSTGRESQL

    • PostgreSQL Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • MONGODB

    • MongoDB Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • MYSQL

    • MySQL Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • PM2

    • PM2 Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • DOCKER

    • Docker Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • GITLAB

    • Gitlab Integration
    • Ubuntu
    • Docker
    • Windows
    • Kubernetes
    • Source
  • ELASTICSEARCH

    • Elasticsearch Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code

Kubernetes

In your watchlog-node-agent.yaml, locate the PostgreSQL env vars:

      - name: MONITOR_POSTGRESQL
        value: "false"
      - name: POSTGRESQL_HOST
        value: "127.0.0.1"
      - name: POSTGRESQL_PORT
        value: "5432"
      - name: POSTGRESQL_USERNAME
        value: ""
      - name: POSTGRESQL_PASSWORD
        value: ""
      - name: POSTGRESQL_DATABASES
        value: ""

Update as follows:

-       value: "false"
+       value: "true"
-      - name: POSTGRESQL_DATABASES
-        value: ""
+      - name: POSTGRESQL_DATABASES
+        value: "db1,db2"

Then apply:

kubectl apply -f watchlog-node-agent.yaml

POSTGRESQL_DATABASES decides which databases get per-table and per-index detail. Cluster- wide metrics — connections, transactions, cache ratio, WAL, replication — need no list at all.

Keep the password in a Secret

apiVersion: v1
kind: Secret
metadata:
  name: watchlog-postgresql
  namespace: watchlog
type: Opaque
stringData:
  password: "your_password"
      - name: POSTGRESQL_PASSWORD
        valueFrom:
          secretKeyRef:
            name: watchlog-postgresql
            key: password

Pointing at a PostgreSQL Service

The node agent runs as a DaemonSet, so 127.0.0.1 only reaches a PostgreSQL on that same node. For a cluster-hosted database, use the Service DNS name:

      - name: POSTGRESQL_HOST
        value: "postgres.database.svc.cluster.local"
      - name: POSTGRESQL_PORT
        value: "5432"

pg_hba.conf

The agent connects from a pod IP that changes on every restart. A pg_hba.conf line scoped to a single address will start failing the first time the agent pod is rescheduled. Use the pod CIDR:

host    all    watchlog_monitor    10.244.0.0/16    scram-sha-256

Creating the monitoring role

kubectl exec -i -n database statefulset/postgres -- psql -U postgres <<'SQL'
CREATE USER watchlog_monitor WITH PASSWORD 'your_password';
GRANT pg_monitor TO watchlog_monitor;
GRANT CONNECT ON DATABASE myapp TO watchlog_monitor;
SQL

kubectl exec needs -i for the heredoc to reach the container.

Which agent should monitor it?

A DaemonSet means every node's agent polls PostgreSQL — N agents collecting the same data, each opening one connection per configured database. Watchlog identifies an instance by host:port, so they all write to the same integration and the data stays correct, but the connections are wasted and they count against max_connections.

  • Preferred: run a single-replica Deployment of the agent dedicated to integrations, and keep the DaemonSet for host and container metrics only.
  • Or use a node selector so only one node's agent carries the PostgreSQL env vars.

pg_stat_statements

This is what unlocks the Queries and Slow Queries tabs, and Watchlog will never install it. For a Helm-deployed PostgreSQL, set it in the chart values:

primary:
  extendedConfiguration: |
    shared_preload_libraries = 'pg_stat_statements'
    pg_stat_statements.track = top

shared_preload_libraries needs a pod restart, not a reload. Then create the extension once per database:

kubectl exec -i -n database statefulset/postgres -- \
  psql -U postgres -d myapp -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"

Advanced options in Kubernetes

The env vars cover the connection. For collection caps, throttle intervals and the activity thresholds, mount an integration.json through a ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: watchlog-integrations
  namespace: watchlog
data:
  integration.json: |
    [
      {
        "service": "postgresql",
        "monitor": true,
        "host": "postgres.database.svc.cluster.local",
        "port": "5432",
        "username": "watchlog_monitor",
        "database": ["myapp"],
        "advanced": {
          "queries": true,
          "activity": true,
          "locks": true,
          "storage": true,
          "indexes": true,
          "vacuum": true,
          "wal": true,
          "replication": true,
          "storageIntervalSeconds": 300
        },
        "slowQuery": { "thresholdMs": 100 },
        "activity": {
          "longQuerySeconds": 30,
          "longTransactionSeconds": 60,
          "idleTransactionSeconds": 300
        }
      }
    ]
          volumeMounts:
            - name: integrations
              mountPath: /app/app/config/integration.json
              subPath: integration.json
              readOnly: true
      volumes:
        - name: integrations
          configMap:
            name: watchlog-integrations

Warning

Do not put the password in the ConfigMap — a ConfigMap is readable by anything with get on the namespace. Keep it in the POSTGRESQL_PASSWORD Secret env var.

Operator-managed clusters

For PostgreSQL deployed by an operator (CloudNativePG, Zalando, Crunchy), the credentials live in a generated Secret:

kubectl get secret <cluster>-superuser -n database \
  -o go-template='{{.data.password | base64decode}}'

Create a dedicated watchlog_monitor role with pg_monitor rather than reusing the superuser. Point the agent at the read-write Service for cluster-wide metrics; adding the read-only Service as a second entry gives you each replica's own replay lag, which the primary cannot report.

Last Updated:: 8/13/26, 12:54 AM
Contributors: mohammad
Prev
Windows
Next
Source Code