Proven working Postgresql monitor

This commit is contained in:
Lyncoln
2026-09-17 09:23:17 -04:00
commit 0123da0e12
7 changed files with 769 additions and 0 deletions
+255
View File
@@ -0,0 +1,255 @@
#!/usr/bin/env python3
import json
import os
import signal
import socket
import traceback
import psycopg2
import psycopg2.extras
SOCKET_PATH = os.environ.get(
"MANAGED_CONTAINERD_SOCKET",
"/run/managed-containerd/managed-containerd.sock",
)
PGHOST = os.environ.get("PGHOST", "postgres")
PGPORT = int(os.environ.get("PGPORT", "5432"))
PGUSER = os.environ.get("PGUSER", "david")
PGDATABASE = os.environ.get("PGDATABASE", "david")
PGPASSWORD_FILE = os.environ.get("PGPASSWORD_FILE")
server_socket = None
def read_secret(path):
if not path:
return None
with open(path, "r", encoding="utf-8") as f:
return f.read().strip()
def postgres_status():
password = read_secret(PGPASSWORD_FILE)
conn = psycopg2.connect(
host=PGHOST,
port=PGPORT,
user=PGUSER,
dbname=PGDATABASE,
password=password,
connect_timeout=5,
application_name="managed-containerd",
)
try:
conn.autocommit = True
with conn.cursor(
cursor_factory=psycopg2.extras.RealDictCursor
) as cur:
#
# Establish role first.
#
cur.execute("""
SELECT pg_is_in_recovery() AS in_recovery
""")
in_recovery = bool(cur.fetchone()["in_recovery"])
#
# Primary-only state.
#
if not in_recovery:
cur.execute("""
SELECT
pg_current_wal_lsn()::text AS current_wal_lsn
""")
primary = cur.fetchone()
else:
primary = None
#
# Recovery state.
#
if in_recovery:
cur.execute("""
SELECT
pg_last_wal_receive_lsn()::text AS receive_lsn,
pg_last_wal_replay_lsn()::text AS replay_lsn,
pg_is_wal_replay_paused() AS replay_paused
""")
recovery = cur.fetchone()
cur.execute("""
SELECT
status,
sender_host,
sender_port,
slot_name,
latest_end_lsn::text AS latest_end_lsn
FROM pg_stat_wal_receiver
LIMIT 1
""")
receiver = cur.fetchone()
else:
recovery = {
"receive_lsn": None,
"replay_lsn": None,
"replay_paused": False,
}
receiver = None
#
# General server state.
#
cur.execute("""
SELECT
current_setting('server_version') AS server_version,
current_setting('cluster_name', true) AS cluster_name,
current_user AS current_user,
current_database() AS current_database,
inet_server_addr()::text AS server_address,
inet_server_port() AS server_port
""")
server = cur.fetchone()
if in_recovery:
role = "standby"
streaming = bool(
receiver and receiver.get("status") == "streaming"
)
else:
role = "primary"
streaming = False
return {
"ok": True,
"application": "postgresql",
"role": role,
"in_recovery": in_recovery,
"streaming": streaming,
"wal_receiver": dict(receiver) if receiver else None,
"recovery": dict(recovery),
"primary": dict(primary) if primary else None,
"server": dict(server),
}
finally:
conn.close()
def handle_request(req):
action = req.get("action")
if action == "ping":
return {
"ok": True,
"daemon": "managed-containerd",
"version": 1,
}
if action == "postgresql.status":
return postgres_status()
return {
"ok": False,
"error": f"unknown action: {action}",
}
def cleanup_socket():
try:
os.unlink(SOCKET_PATH)
except FileNotFoundError:
pass
def shutdown(signum, frame):
global server_socket
print(
f"managed-containerd received signal {signum}; shutting down",
flush=True,
)
if server_socket is not None:
try:
server_socket.close()
except OSError:
pass
cleanup_socket()
raise SystemExit(0)
def serve():
global server_socket
os.makedirs(os.path.dirname(SOCKET_PATH), exist_ok=True)
cleanup_socket()
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
server_socket = socket.socket(
socket.AF_UNIX,
socket.SOCK_STREAM,
)
server_socket.bind(SOCKET_PATH)
os.chmod(SOCKET_PATH, 0o660)
server_socket.listen(16)
print(
f"managed-containerd listening on {SOCKET_PATH}",
flush=True,
)
try:
while True:
conn, _ = server_socket.accept()
with conn:
try:
raw = b""
while b"\n" not in raw:
chunk = conn.recv(65536)
if not chunk:
break
raw += chunk
req = json.loads(
raw.decode("utf-8").strip()
)
response = handle_request(req)
except Exception as exc:
traceback.print_exc()
response = {
"ok": False,
"error": str(exc),
}
conn.sendall(
json.dumps(
response,
default=str,
).encode("utf-8") + b"\n"
)
finally:
cleanup_socket()
if __name__ == "__main__":
serve()