I made a a small Monitoring Programm with 2 Subclasses of Threading.
Both running good but when i start my main.py just one thread is executed and the second one is not.
main.py
def main():
#Get SSH connection
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(docker_host, username=username, password=password)
# Threading Event
stop_event = threading.Event()
# Creating Threading Objects
monitoring = Monitor(ssh_client, stop_event, container1, container2)
query = Query_Servers(stop_event, url1, url2)
# Start both threads
print("Start monitoring")
monitoring.start()
print("start query")
query.start()
time.sleep(40)
monitoring.join()
query.join()
#Init Funktion
if __name__ == "__main__":
main()
querie_servers.py
## HTTP DOS Abfrage Klasse
import requests # Bibiliothek für HTTP Abfragen
import sys # Import Sys um das Programm zu beenden, falls DOS scheitert.
import threading # Importiert Threading
class Query_Servers(threading.Thread):
def __init__(self,stop_event,url1,url2):
super().__init__()
self.stop_event = stop_event
self.url1 = url1
self.url2 = url2
self.queriesTotal = 0
def run(self):
self.query_servers()
def query_servers(self):
global queriesTotal
while not self.stop_event.is_set():
try:
# Den ersten Server anfragen
response1 = requests.get(self.url1)
if response1.status_code == 200:
self.queriesTotal += 1 # Falls erfolgreich setzte QueriesTotal +1
print(f'Successfully queried {self.url1}')
else:
print(f'Failed to query {url1} with status code {response1.status_code}')
sys.exit('Exiting the Programm') # Falls nicht erfolgreich beende das Programm
# Den zweiten Server anfragen
response2 = requests.get(self.url2) # Den zweiten Server abfragen
if response2.status_code == 200:
self.queriesTotal += 1 # Fals erfolgreich setzte QueriesTotal +1
print(f'Successfully queried {self.url2}')
else:
print(f'Failed to query {url2} with status code {response2.status_code}')
sys.exit('Exiting the Program') # Falls nicht erfolgreich beende das Programm
except requests.RequestException as e:
print(f'An error occurred: {e}')
sys.exit('Exiting the Program')
monitor.py
## Die Klasse Monitor
import paramiko #Bibliothek für die SSH Verbindung
import time # Bibliothek für Zeit
from calculator import Calculator # Die Klass Calculator importieren
import threading # Threading importieren
## Monitoren der Klassen
class Monitor(threading.Thread):
container1_start_CPU=0 # Start Wert Container 1 CPU %
container1_start_MEM=0 # Start Wert Container 1 MEM %
container1_start_MEM_T=0 # Start Wert Container 1 MEM Total
container2_start_CPU=0 # Start Wert Container 2 CPU %
container2_start_MEM=0 # Start Wert Container 2 MEM %
container2_start_MEM_T=0 # Start Wert Container 2 MEM Total
container1_CPU_Array=[] # container1 CPU Array
container1_MEM_Array=[] # container 1 Mem Array
container1_MEM_Array_T=[] # container 1 Mem Array Total
container2_CPU_Array=[] # Container 2 CPU % Array
container2_MEM_Array=[] # Container 2 MEM % Array
container2_MEM_Array_T=[] # container 2 Mem Array Total
def __init__(self, ssh_client, stop_event, container1, container2):
super().__init__()
self.ssh_client = ssh_client
self.container1 = container1
self.container2 = container2
self.stop_event = stop_event
## Monitor Docker Container
def monitor_docker_container(self, container_name):
cpu_command = f"docker stats --no-stream --format '{{{{.CPUPerc}}}}' {container_name}" # CPU Nutzung des Containers
mem_command = f"docker stats --no-stream --format '{{{{.MemPerc}}}}' {container_name}" # Arbeitsspeicher Nutzug des Containers in %
docker_command = f"docker stats --no-stream --format '{{{{.MemUsage}}}}' {container_name} | awk '{{print $1}}'" #Arbeitsspeichernutzung des Containers total
cpu_output = self.execute_ssh_command( cpu_command) # Statistiken per SSH zur Nutzung des CPU
mem_output = self.execute_ssh_command( mem_command)# Statisken per SSH zur Nutzung des Arbeitsspeichers
mem_output_t = self.execute_ssh_command( docker_command) # Statiken der SSH Nutzung Total
# Umwandeln der Statisken in Fließkommazahlen
cpu_usage = float(cpu_output.strip('%'))
mem_usage = float(mem_output.strip('%'))
mem_usage_t = Calculator.convert_into_Megabyte(float(mem_output_t.strip('MiB'))) #Umwandeln Memory Usage Total in Megabyte
return cpu_usage, mem_usage, mem_usage_t
# SSH Kommandos ausführen
def execute_ssh_command(self, command):
stdin, stdout, stderr = self.ssh_client.exec_command(command)
output = stdout.read().decode("utf-8").strip()
return output
# Ausgabe der Werte
def monitor_stats(self):
while not self.stop_event.is_set():
try:
container1_cpu, container1_mem, container1_mem_t = self.monitor_docker_container(self.container1) # "Tuple Unpacking"
container2_cpu, container2_mem, container2_mem_t = self.monitor_docker_container(self.container2) # ""
# An Arrays dranhängen
self.container1_CPU_Array.append(container1_cpu)
self.container1_MEM_Array.append(container1_mem)
self.container1_MEM_Array_T.append(container1_mem_t)
self.container2_CPU_Array.append(container2_cpu)
self.container2_MEM_Array.append(container2_mem)
self.container2_MEM_Array_T.append(container2_mem_t)
# Ausgabe der Werte
print("------------------------------------------")
print(f"{self.container1} CPU Usage: {container1_cpu}%")
print(f"{self.container1} Memory Usage: {container1_mem}%")
print(f"{self.container1} Memory Usage: {container1_mem_t} MB")
print(f"{self.container2} CPU Usage: {container2_cpu}%")
print(f"{self.container2} Memory Usage: {container2_mem}%")
print(f"{self.container2} Memory Usage: {container2_mem_t} MB")
print("------------------------------------------")
except Exception as e:
print(f'An error occurred: {e}')
def run(self):
self.start()
def start(self):
global container1_start_CPU, container1_start_MEM, container1_start_MEM_T
global container2_start_CPU, container2_start_MEM, container2_start_MEM_T
container1_start_CPU, container1_start_MEM, container1_start_MEM_T = self.monitor_docker_container(self.container1)
container2_start_CPU, container2_start_MEM, container2_start_MEM_T = self.monitor_docker_container(self.container2)
print("-----------------------------------")
print("-----Werte vor dem Test------------")
print("-----------------------------------")
print("-----------------------------------")
print(f"---{self.container1}: CPU {container1_start_CPU}%")
print(f"---{self.container1}: MEM {container1_start_MEM}%")
print(f"---{self.container1}: MEM {container1_start_MEM_T}MB")
print(f"---{self.container2}: CPU {container2_start_CPU}%")
print(f"---{self.container2}: MEM {container2_start_MEM}%")
print(f"---{self.container2}: MEM {container2_start_MEM_T}MB")
print("-----------------------------------")
time.sleep(5)
print("----Starte Test--------------------")
self.monitor_stats()
# End Funktion zum Abrufen des Ergebnisses
def end(self):
c1_cpu_average=Calculator.calculate_Average(container1_CPU_Array)
c1_mem_average=Calculator.calculate_Average(container1_MEM_Array)
c1_mem_average_t=Calculatorcalculate_Average(container1_MEM_Array_T)
c2_cpu_average=Calculator.calculate_Average(container2_CPU_Array)
c2_mem_average=Calculator.calculate_Average(container2_MEM_Array)
c2_mem_average_t=Calculator.calculate_Average(container2_MEM_Array_T)
print("-----------------------------------")
print("------Test Ende--------------------")
print("-----------------------------------")
print(f"-----HTTP Abfragen gesammt: {queriesTotal}")
print("-----------------------------------")
print("-----------------------------------")
print(f"-----{container1} : ")
print(f"CPU {c1_cpu_average}% | Diff: {round((c1_cpu_average - container1_start_CPU),2) }%")
print(f"MEM: {c1_mem_average}% | Diff: {round((c1_mem_average - container1_start_MEM ),2)}%")
print(f"MEM: {c1_mem_average_t}MB | Diff: { round((c1_mem_average_t - container1_start_MEM_T),2) }MB")
print(f"-----{container2} : ")
print(f"CPU {c2_cpu_average}% | Diff: {round((c2_cpu_average - container2_start_CPU),2) }%")
print(f"MEM: {c2_mem_average}%| Diff: {round((c2_mem_average - container2_start_MEM ),2)}%")
print(f"MEM: {c2_mem_average_t}MB| Diff: {round((c2_mem_average_t - container2_start_MEM_T),2) }MB")
print("-----------------------------------")
What did i miss? The monitoring and query objects are subclasses of Threading. If i comment one of them out other one is running but they don’t run simultaneously.
Can you help me with this ?
New contributor
schuse is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3