Add TCP support
This commit is contained in:
@@ -3,6 +3,7 @@ import threading
|
||||
import requests
|
||||
import tomllib
|
||||
import logging
|
||||
import socket
|
||||
import time
|
||||
|
||||
with open("config.toml", "rb") as f:
|
||||
@@ -14,59 +15,140 @@ logging.disable(logging.CRITICAL)
|
||||
uptime = {}
|
||||
|
||||
|
||||
def http_ping(service):
|
||||
def handle_service_status(
|
||||
service_name: str,
|
||||
down: bool = False,
|
||||
error: str | None = None,
|
||||
):
|
||||
if (
|
||||
uptime[service_name][config["frontend"]["pings"] - 1] != "O"
|
||||
and config["ntfy"]["enabled"]
|
||||
and down
|
||||
):
|
||||
requests.post(
|
||||
url=f"https://{config['ntfy']['server']}/{config['ntfy']['topic']}",
|
||||
data=f"Service {service_name} is offline",
|
||||
)
|
||||
elif (
|
||||
uptime[service_name][config["frontend"]["pings"] - 1] != "I"
|
||||
and config["ntfy"]["enabled"]
|
||||
and not down
|
||||
):
|
||||
requests.post(
|
||||
url=f"https://{config['ntfy']['server']}/{config['ntfy']['topic']}",
|
||||
data=f"Service {service_name} is online",
|
||||
)
|
||||
|
||||
uptime[service_name].pop(0)
|
||||
if down:
|
||||
uptime[service_name].append("O")
|
||||
print(f"[E] An error happened while pinging for {service_name}: {error}")
|
||||
else:
|
||||
uptime[service_name].append("I")
|
||||
print(f"[I] Pinging {service_name} succeeded!")
|
||||
|
||||
|
||||
def tcp_ping(service):
|
||||
ip = service["ip_version"]
|
||||
name = service["name"]
|
||||
host = service["hostname"]
|
||||
port = service["port"]
|
||||
timeout = service["timeout"]
|
||||
|
||||
if ip == 4:
|
||||
socket_type = socket.AF_INET
|
||||
elif ip == 6:
|
||||
socket_type = socket.AF_INET6
|
||||
else:
|
||||
print(f"[E] IP version for {name} is not 4 or 6")
|
||||
return
|
||||
|
||||
while True:
|
||||
print(f"[I] Pinging {service}")
|
||||
print(f"[I] Pinging {name}")
|
||||
|
||||
try:
|
||||
resp = requests.get(config["services"][service])
|
||||
resp.raise_for_status()
|
||||
with socket.socket(family=socket_type, type=socket.SOCK_STREAM) as sock:
|
||||
sock.settimeout(timeout)
|
||||
sock.connect((host, port))
|
||||
|
||||
if (
|
||||
uptime[service][config["frontend"]["pings"] - 1] != "I"
|
||||
and config["ntfy"]["enabled"]
|
||||
):
|
||||
requests.post(
|
||||
f"https://{config['ntfy']['server']}/{config['ntfy']['topic']}",
|
||||
data=f"Service {service} is online",
|
||||
)
|
||||
handle_service_status(
|
||||
service_name=name,
|
||||
down=False,
|
||||
)
|
||||
|
||||
uptime[service].pop(0)
|
||||
uptime[service].append("I")
|
||||
print(f"[I] Pinging {service} worked!")
|
||||
except Exception as e:
|
||||
if (
|
||||
"Remote end closed connection without response" in str(e)
|
||||
and config["pinging"]["allow_empty_responses"]
|
||||
):
|
||||
uptime[service].pop(0)
|
||||
uptime[service].append("I")
|
||||
print(f"[I] Pinging {service} worked!")
|
||||
else:
|
||||
if (
|
||||
uptime[service][config["frontend"]["pings"] - 1] != "O"
|
||||
and config["ntfy"]["enabled"]
|
||||
):
|
||||
requests.post(
|
||||
f"https://{config['ntfy']['server']}/{config['ntfy']['topic']}",
|
||||
data=f"Service {service} is offline",
|
||||
)
|
||||
except socket.timeout:
|
||||
handle_service_status(
|
||||
service_name=name,
|
||||
down=True,
|
||||
error=f"[E] Connection to {host}:{port} timed out",
|
||||
)
|
||||
|
||||
uptime[service].pop(0)
|
||||
uptime[service].append("O")
|
||||
print(f"[E] An error happened while pinging for {service}: {e}")
|
||||
except Exception as err:
|
||||
handle_service_status(
|
||||
service_name=name,
|
||||
down=True,
|
||||
error=f"[E] Connection error: {err}",
|
||||
)
|
||||
|
||||
time.sleep(config["pinging"]["seconds_between_ping"])
|
||||
|
||||
|
||||
for service in config["services"]:
|
||||
uptime[service] = []
|
||||
for _ in range(config["frontend"]["pings"]):
|
||||
uptime[service].append("?")
|
||||
def http_ping(service):
|
||||
name = service["name"]
|
||||
address = service["address"]
|
||||
timeout = service["timeout"]
|
||||
|
||||
threading.Thread(
|
||||
target=http_ping,
|
||||
args=(service,),
|
||||
).start()
|
||||
while True:
|
||||
print(f"[I] Pinging {service['name']}")
|
||||
try:
|
||||
resp = requests.get(
|
||||
url=address,
|
||||
timeout=timeout,
|
||||
)
|
||||
resp.raise_for_status()
|
||||
|
||||
handle_service_status(
|
||||
service_name=name,
|
||||
down=False,
|
||||
)
|
||||
except Exception as e:
|
||||
handle_service_status(
|
||||
service_name=name,
|
||||
down=True,
|
||||
error=str(e),
|
||||
)
|
||||
|
||||
time.sleep(config["pinging"]["seconds_between_ping"])
|
||||
|
||||
|
||||
for service_name in config["services"]:
|
||||
service = config["services"][service_name]
|
||||
if "type" in service and "name" in service and "timeout" in service:
|
||||
uptime[service["name"]] = []
|
||||
for _ in range(config["frontend"]["pings"]):
|
||||
uptime[service["name"]].append("?")
|
||||
|
||||
if service["type"] == "http" and "address" in service:
|
||||
threading.Thread(
|
||||
target=http_ping,
|
||||
args=(service,),
|
||||
).start()
|
||||
elif (
|
||||
service["type"] == "tcp"
|
||||
and "port" in service
|
||||
and "hostname" in service
|
||||
and "ip_version" in service
|
||||
):
|
||||
threading.Thread(
|
||||
target=tcp_ping,
|
||||
args=(service,),
|
||||
).start()
|
||||
else:
|
||||
print(
|
||||
f"[W] Service {service['name']} is missing required fields, ignoring."
|
||||
)
|
||||
else:
|
||||
print("[W] Invalid service entry found, ignoring.")
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
|
||||
Reference in New Issue
Block a user