1
Fork 0
mirror of https://github.com/Steffo99/service-monitor.git synced 2024-11-24 09:14:18 +00:00

First commit

This commit is contained in:
Steffo 2017-10-19 10:40:00 +02:00
commit 58ea5d344c
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: C27544372FBB445D
3 changed files with 201 additions and 0 deletions

32
aliveHosts.log Normal file
View file

@ -0,0 +1,32 @@
2017-10-19 10:20:31 ✅ Logging started.
2017-10-19 10:20:31 HTTPS on Caronte (caronte.fermi.mo.it:443) is 🔵 up.
2017-10-19 10:20:31 HTTP on Caronte (caronte.fermi.mo.it:80) is 🔵 up.
2017-10-19 10:20:31 Postgres on Steffo (royal.steffo.eu:5432) is 🔵 up.
2017-10-19 10:20:31 HTTP on Steffo (royal.steffo.eu:80) is 🔵 up.
2017-10-19 10:20:31 HTTPS on Steffo (royal.steffo.eu:443) is 🔵 up.
2017-10-19 10:20:31 Minecraft on Steffo (royal.steffo.eu:25565) is 🔵 up.
2017-10-19 10:20:31 SSH on Steffo (royal.steffo.eu:22) is 🔵 up.
2017-10-19 10:20:32 Source DS on Steffo (royal.steffo.eu:27015) is 🔴 down.
2017-10-19 10:22:27 🛑 Logging stopped.
2017-10-19 10:22:48 ✅ Logging started.
2017-10-19 10:22:48 HTTPS on Caronte (caronte.fermi.mo.it:443) is 🔵 up.
2017-10-19 10:22:48 SSH on Steffo (royal.steffo.eu:22) is 🔵 up.
2017-10-19 10:22:48 Postgres on Steffo (royal.steffo.eu:5432) is 🔵 up.
2017-10-19 10:22:48 Minecraft on Steffo (royal.steffo.eu:25565) is 🔵 up.
2017-10-19 10:22:48 HTTP on Steffo (royal.steffo.eu:80) is 🔵 up.
2017-10-19 10:22:48 HTTPS on Steffo (royal.steffo.eu:443) is 🔵 up.
2017-10-19 10:22:48 HTTP on Caronte (caronte.fermi.mo.it:80) is 🔵 up.
2017-10-19 10:22:49 Source DS on Steffo (royal.steffo.eu:27015) is 🔴 down.
2017-10-19 10:23:24 ✅ Logging started.
2017-10-19 10:23:24 HTTPS on Caronte (caronte.fermi.mo.it:443) is 🔵 up.
2017-10-19 10:23:24 HTTP on Caronte (caronte.fermi.mo.it:80) is 🔵 up.
2017-10-19 10:23:24 HTTPS on Steffo (royal.steffo.eu:443) is 🔵 up.
2017-10-19 10:23:24 Postgres on Steffo (royal.steffo.eu:5432) is 🔵 up.
2017-10-19 10:23:24 SSH on Steffo (royal.steffo.eu:22) is 🔵 up.
2017-10-19 10:23:24 Minecraft on Steffo (royal.steffo.eu:25565) is 🔵 up.
2017-10-19 10:23:24 HTTP on Steffo (royal.steffo.eu:80) is 🔵 up.
2017-10-19 10:23:25 Source DS on Steffo (royal.steffo.eu:27015) is 🔴 down.
2017-10-19 10:23:38 HTTP on Steffo (royal.steffo.eu:80) went 🔴 down.
2017-10-19 10:23:38 HTTPS on Steffo (royal.steffo.eu:443) went 🔴 down.
2017-10-19 10:23:41 HTTPS on Steffo (royal.steffo.eu:443) went 🔵 up.
2017-10-19 10:23:41 HTTP on Steffo (royal.steffo.eu:80) went 🔵 up.

32
config.json Normal file
View file

@ -0,0 +1,32 @@
{
"stdout": true,
"log": {
"filename": "aliveHosts.log"
},
"telegram": {
"token": "375232708:AAGthX2LkCzR26Q01t-Jtc8pP79KYP2QqqI",
"channel_id": -1001128933395
},
"hosts": {
"Caronte": {
"address": "caronte.fermi.mo.it",
"interval": 5,
"services": {
"HTTP": 80,
"HTTPS": 443
}
},
"Steffo": {
"address": "royal.steffo.eu",
"interval": 5,
"services": {
"SSH": 22,
"HTTP": 80,
"HTTPS": 443,
"Postgres": 5432,
"Minecraft": 25565,
"Source DS": 27015
}
}
}
}

137
main.py Normal file
View file

@ -0,0 +1,137 @@
import requests
import datetime
import time
import json
import socket
import threading
# Read the config
with open("config.json") as file:
config = json.load(file)
loglock = threading.Lock()
class Service:
def __init__(self, host, name, port, interval):
self.host = host
self.name = name
self.port = port
self.interval = interval
self.status = None
self.thread = None
def __repr__(self):
return f"<Service {self.name} on port {self.port} with status {self.status}>"
def __str__(self):
return f"{self.name} ({self.port}): {'alive' if self.status else 'dead'}"
def poll(self):
"""Try to connect to a port"""
s = socket.socket()
s.setblocking(False)
s.settimeout(5)
try:
s.connect((self.host.address, self.port))
s.close()
except socket.timeout:
return 1
except ConnectionError:
return 1
else:
return 0
def update(self, callback=None):
"""Update the status once"""
oldstate = self.status
self.status = self.poll()
if callback is not None:
callback(host=self.host, service=self, old=oldstate, new=self.status)
def monitor(self, callback):
"""Run this as a thread to continuously update the status"""
th = threading.current_thread()
while getattr(th, "running", True):
# Tra un tentativo e l'altro devono passare interval secondi
t = time.clock()
self.update(callback)
ct = time.clock()
time.sleep(0 if 1-(ct+t) < 0 else 1-(ct+t))
class Host:
def __init__(self, name, **kwargs):
self.name = name
self.address = kwargs["address"]
self.interval = kwargs["interval"]
self.services = []
for service in kwargs["services"]:
self.services.append(Service(host=self, name=service, port=kwargs["services"][service], interval=self.interval))
def __repr__(self):
return f"<Host {self.name} ({self.address}), with {self.interval}s interval>"
def __str__(self, formatting="text"):
text = ""
if formatting == "text":
for service in self.services:
text += str(service) + "\n"
return text
def broadcast(message):
"""Send a message to the log, stdout and the telegram channel."""
if config["stdout"]:
print(message)
if config["log"]["filename"] != "":
loglock.acquire()
with open(config["log"]["filename"], "ab") as file:
file.write(message.encode("utf-8"))
loglock.release()
if config["telegram"]["channel_id"] != 0:
requests.get(f"https://api.telegram.org/bot{config['telegram']['token']}/sendMessage", params={
"chat_id": config["telegram"]["channel_id"],
"text": message
})
def handle_update(host, service, old, new):
# 0 = Up
# >0 = Down
t = datetime.datetime.now()
if old is None:
if new == 0:
# Service is up
broadcast(t.strftime(r"%Y-%m-%d %H:%M:%S") + f" {service.name} on {host.name} ({host.address}:{service.port}) is 🔵 up.\n")
else:
# Service is down
broadcast(t.strftime(r"%Y-%m-%d %H:%M:%S") + f" {service.name} on {host.name} ({host.address}:{service.port}) is 🔴 down.\n")
elif old == 0 and new > 0:
# Service died
broadcast(t.strftime(r"%Y-%m-%d %H:%M:%S") + f" {service.name} on {host.name} ({host.address}:{service.port}) went 🔴 down.\n")
elif old > 0 and new == 0:
# Service was revived
broadcast(t.strftime(r"%Y-%m-%d %H:%M:%S") + f" {service.name} on {host.name} ({host.address}:{service.port}) went 🔵 up.\n")
hosts = []
if __name__ == "__main__":
for host in config["hosts"]:
hosts.append(Host(host, **config["hosts"][host]))
for host in hosts:
for service in host.services:
service.thread = threading.Thread(target=service.monitor, args=(handle_update,), name=repr(service))
service.thread.running = True
service.thread.start()
broadcast(datetime.datetime.now().strftime(r"%Y-%m-%d %H:%M:%S") + f" ✅ Logging started.\n")
try:
while True:
time.sleep(300)
except KeyboardInterrupt:
for host in hosts:
for service in host.services:
service.thread.running = False
service.thread.join()
broadcast(datetime.datetime.now().strftime(r"%Y-%m-%d %H:%M:%S") + f" 🛑 Logging stopped.\n")