2024-06-25 19:11:07 +00:00
|
|
|
#!/usr/bin/python3
|
|
|
|
|
|
|
|
# MIT License
|
|
|
|
|
2024-06-27 17:44:12 +00:00
|
|
|
# Copyright (c) 2024 Thomas Williams - https://git.server.wales/thomas
|
2024-06-25 19:11:07 +00:00
|
|
|
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
|
|
# in the Software without restriction, including without limitation the rights
|
|
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
|
|
# furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
|
|
# copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
# SOFTWARE.
|
|
|
|
|
|
|
|
import config
|
|
|
|
import psutil
|
|
|
|
import os
|
|
|
|
import time
|
|
|
|
import log
|
|
|
|
import requests
|
2024-06-27 17:25:59 +00:00
|
|
|
import threading
|
2024-06-29 11:55:24 +00:00
|
|
|
import signal
|
2024-07-02 19:46:36 +00:00
|
|
|
import socket
|
2024-06-26 18:40:26 +00:00
|
|
|
from functools import partial
|
|
|
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
2024-06-25 19:11:07 +00:00
|
|
|
from bs4 import BeautifulSoup
|
2024-07-02 19:46:36 +00:00
|
|
|
from log import hostLogsManager
|
|
|
|
from datetime import datetime
|
2024-06-25 19:11:07 +00:00
|
|
|
|
2024-06-29 11:55:24 +00:00
|
|
|
stop_event = threading.Event()
|
|
|
|
|
|
|
|
def signal_handler(sig, frame):
|
|
|
|
print('SIGINT/SIGTERM aknowledged. Stopping script gracefully, please wait...')
|
|
|
|
stop_event.set()
|
|
|
|
|
2024-06-26 18:40:26 +00:00
|
|
|
def loadUrl(url):
|
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
headers = { 'User-Agent': 'Monutil monitor' }
|
|
|
|
|
2024-06-26 18:40:26 +00:00
|
|
|
response = requests.get(url, timeout=config.urlTimeout, headers=headers)
|
|
|
|
return response
|
|
|
|
|
|
|
|
def prepareUrl(src, baseUrl):
|
|
|
|
|
|
|
|
if not src.startswith("http://") and not src.startswith("https://"):
|
|
|
|
return baseUrl.rstrip("/") + "/" + src.lstrip("/")
|
|
|
|
return src
|
|
|
|
|
2024-06-29 11:55:24 +00:00
|
|
|
def monitorHost(stop_event):
|
2024-06-25 19:11:07 +00:00
|
|
|
|
2024-06-29 11:55:24 +00:00
|
|
|
while not stop_event.is_set():
|
2024-06-25 19:11:07 +00:00
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
load1, load5, load15 = psutil.getloadavg() # this takes time to warm up if not running script on *nix
|
|
|
|
loadavg = round((load1/os.cpu_count()) * 100, 2)
|
2024-06-29 16:59:54 +00:00
|
|
|
|
|
|
|
memory = psutil.virtual_memory().percent
|
2024-07-02 19:46:36 +00:00
|
|
|
logHostLog(socket.gethostname(), datetime.now(), loadavg, memory)
|
2024-06-25 19:11:07 +00:00
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
print("CPU %: " + str(loadavg))
|
|
|
|
print("Memory %: " + str(memory))
|
2024-06-25 19:11:07 +00:00
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
time.sleep(config.hostMonitoringPeriod)
|
2024-06-25 19:11:07 +00:00
|
|
|
|
2024-06-29 11:55:24 +00:00
|
|
|
def monitorUrls(stop_event):
|
2024-06-27 17:25:59 +00:00
|
|
|
|
2024-06-29 11:55:24 +00:00
|
|
|
while not stop_event.is_set():
|
2024-06-26 18:40:26 +00:00
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
for url in config.urls:
|
|
|
|
|
|
|
|
baseUrl = url
|
|
|
|
urlFail = False
|
|
|
|
|
|
|
|
startTime = time.time()
|
|
|
|
request = loadUrl(url)
|
|
|
|
|
|
|
|
if request.status_code == 200:
|
|
|
|
|
|
|
|
html = BeautifulSoup(request.content, 'html.parser')
|
|
|
|
imageUrls = [img['src'] for img in html.find_all('img')]
|
|
|
|
|
|
|
|
with ThreadPoolExecutor(max_workers=config.maxWorkers) as executor:
|
|
|
|
|
|
|
|
responses = [executor.submit(loadUrl, prepareUrl(url, baseUrl)) for url in imageUrls]
|
|
|
|
responses = [future.result() for future in as_completed(responses)]
|
|
|
|
|
|
|
|
for response in responses:
|
2024-06-26 18:40:26 +00:00
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
if not response.status_code == 200:
|
|
|
|
urlFail = True
|
|
|
|
|
|
|
|
endTime = time.time()
|
|
|
|
timeDiff = endTime - startTime
|
|
|
|
|
|
|
|
print(timeDiff)
|
|
|
|
|
|
|
|
else:
|
|
|
|
urlFail = True
|
|
|
|
|
|
|
|
time.sleep(config.urlMonitoringPeriod)
|
|
|
|
|
2024-07-02 19:46:36 +00:00
|
|
|
def logHostLog(hostname, logTime, cpu, memory):
|
|
|
|
|
|
|
|
manager = hostLogsManager(config.sqlServer, config.sqlDatabase, config.sqlUsername, config.sqlPassword)
|
|
|
|
manager.insert_host_log(hostname, logTime, cpu, memory)
|
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
def main():
|
2024-06-29 11:55:24 +00:00
|
|
|
|
|
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
2024-06-27 17:25:59 +00:00
|
|
|
|
2024-06-29 11:55:24 +00:00
|
|
|
hostMonitorThread = threading.Thread(target=monitorHost, args=(stop_event,))
|
|
|
|
urlMonitorThread = threading.Thread(target=monitorUrls, args=(stop_event,))
|
2024-06-27 17:25:59 +00:00
|
|
|
|
|
|
|
hostMonitorThread.start()
|
|
|
|
urlMonitorThread.start()
|
|
|
|
|
|
|
|
hostMonitorThread.join()
|
|
|
|
urlMonitorThread.join()
|
2024-06-25 19:11:07 +00:00
|
|
|
|
2024-06-27 17:25:59 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|