Home Database monitoring with Gatus
Post
Cancel

Database monitoring with Gatus

Uptime-kuma is a great solution to monitor the health of your services but I prefer Gatus. With Gatus you can define what you want to monitor declaratively, with Uptime-kuma you have to setup everything by clicking through the UI. But Uptime-kuma supports more kinds of monitors, including postgres databases. So how do I bridge the gap?

I somehow need a service with an http endpoint for gatus to check. So I found PostgreSQL Server Exporter. It is designed to export metrics from a postgres server for Prometheus which is often used to then visualize the metrics with Grafana. But we do not need all of this, we only want the exporter to give use a list of metrics via http. There are a ton of metrics but we are only interested in one pg_up. It can have the values 0 for database is unreachable and 1 for database is reachable.

I run both the database and the exporter as containers via a compose.yaml file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
services:
  postgresql:
    image: docker.io/bitnami/postgresql:17
    restart: unless-stopped
    ports:
      - 5433:5432
    volumes:
      - postgresql_data:/bitnami/postgresql
      - ./backups:/backups
    environment:
      POSTGRESQL_PASSWORD:

  postgres-exporter:
    image: quay.io/prometheuscommunity/postgres-exporter:latest
    restart: unless-stopped
    ports:
      - 9187:9187
    environment:
      DATA_SOURCE_URI: "postgresql:5432/postgres?sslmode=disable"
      DATA_SOURCE_USER: postgres
      DATA_SOURCE_PASS: ${POSTGRESQL_PASSWORD}

volumes:
  postgresql_data:

In Gatus we simply configure an endpoint to check if the response from the exporter includes pg_up 1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
config:
  endpoints:
  - name: database
    url: http://<IP-OF-EXPORTER>:9187/metrics
    interval: 60s
    conditions:
    - "[BODY] == pat(*pg_up 1*)"
    client:
      insecure: true
    alerts:
    - type: telegram
      send-on-resolved: true
    - type: matrix
      send-on-resolved: true
This post is licensed under CC BY 4.0 by the author.