Open Deace0 opened 3 weeks ago
כן, התמונה מכסה את הנושאים הבאים ללימוד מתקדם של Python:
Generators, Iterators, and Coroutines:
Threading and Multiprocessing:
AsyncIO:
עליך להמשיך לעיין ולהתעמק בכל אחד מהנושאים הללו, תוך התמקדות בכלים והטכניקות שיעזרו לשפר את הביצועים והיעילות של הקוד שלך, במיוחד כשמדובר בקנה מידה גדול.
אם תרצה, אפשר להתמקד באחד הנושאים או לדון בו בפירוט נוסף.
כדי ליישם נושאים כמו מחוללים (Generators), איטרטורים (Iterators), ושותפים (Coroutines) בקוד שלך, נתחיל מהבנת השימוש בהם כדי לשפר את הביצועים והיעילות של סוכן הניטור (monitor agent) שלך.
מחוללים (Generators) יכולים לשמש כדי ליצור סדרת ערכים בצורה יעילה יותר מבחינת זיכרון מאשר רשימות (Lists) סטטיות. במקרה שלך, נוכל להשתמש בהם לניטור נתונים באופן רציף, לדוגמה, לקבלת מדדי CPU, זיכרון ודיסק.
נוסיף פונקציה המשתמשת ב-Generator לניטור משאבים בקוד שלך:
# monitor.py
import time
import logging
from vm_monitor.cpu_monitor import CPUMonitor
from vm_monitor.memory_monitor import MemoryMonitor
from vm_monitor.disk_monitor import DiskMonitor
logging.basicConfig(
filename='/home/dell/Desktop/monitor_agent/logs/log.log',
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
)
def monitor_resources():
cpu_usage = CPUMonitor.get_usage()
memory_usage = MemoryMonitor.get_usage()
disk_usage = DiskMonitor.get_usage()
logging.info(f"CPU Usage: {cpu_usage}%")
logging.info(f"Memory Usage: {memory_usage}%")
logging.info(f"Disk Usage: {disk_usage}%")
yield cpu_usage, memory_usage, disk_usage
def monitor_resources_periodically(interval=10):
for usage_data in monitor_resources():
print(
f"CPU Usage: {usage_data[0]}%, "
f"Memory Usage: {usage_data[1]}%, "
f"Disk Usage: {usage_data[2]}%"
)
time.sleep(interval)
if __name__ == "__main__":
monitor_resources_periodically()
monitor_resources
מוגדר כ-Generator המשתמש ב-yield להחזיר את המדדים לניטור באופן רציף.monitor_resources_periodically
קורא ל-Generator כל 10 שניות (ניתן לשינוי) כדי להדפיס ולעדכן את המדדים.במקרה זה, נשתמש ב-AsyncIO ו-Coroutines כדי לבצע פעולות ניטור בצורה א-סינכרונית, מה שמאפשר לנו לשפר את הביצועים על ידי ביצוע מספר פעולות בו זמנית.
# monitor_async.py
import asyncio
import logging
from vm_monitor.cpu_monitor import CPUMonitor
from vm_monitor.memory_monitor import MemoryMonitor
from vm_monitor.disk_monitor import DiskMonitor
logging.basicConfig(
filename='/home/dell/Desktop/monitor_agent/logs/log_async.log',
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
)
async def monitor_cpu():
cpu_usage = CPUMonitor.get_usage()
logging.info(f"CPU Usage: {cpu_usage}%")
print(f"CPU Usage: {cpu_usage}%")
await asyncio.sleep(1) # לדמות השהייה של קריאת ניטור
async def monitor_memory():
memory_usage = MemoryMonitor.get_usage()
logging.info(f"Memory Usage: {memory_usage}%")
print(f"Memory Usage: {memory_usage}%")
await asyncio.sleep(1) # לדמות השהייה של קריאת ניטור
async def monitor_disk():
disk_usage = DiskMonitor.get_usage()
logging.info(f"Disk Usage: {disk_usage}%")
print(f"Disk Usage: {disk_usage}%")
await asyncio.sleep(1) # לדמות השהייה של קריאת ניטור
async def monitor_resources():
await asyncio.gather(
monitor_cpu(),
monitor_memory(),
monitor_disk()
)
if __name__ == "__main__":
asyncio.run(monitor_resources())
monitor_cpu
, monitor_memory
, monitor_disk
) מוגדרת כ-Coroutine על ידי שימוש במילת המפתח async
.asyncio.gather
, המאפשר ריבוי משימות.asyncio.run
מריץ את כל המשימות הא-סינכרוניות בצורה יעילה.שילוב של טכניקות אלה בפרויקט שלך יכול לעזור לך לייעל את הניטור ולשפר את השימוש במשאבים בצורה משמעותית.
כדי ליישם את השינויים שנאמרו ב-CR (Code Review), עליך לעדכן את הקוד שלך בהתאם להמלצות שניתנו. הנה כיצד לבצע את התיקונים השונים:
ההמלצה הייתה לא לשים את הפונקציות בתוך מחלקות אם אין צורך בכך, במיוחד כאשר הן מכילות רק מתודה אחת ואין לך צורך לשמור על מצב מסוים.
ב-vm_monitor/cpu_monitor.py
:
import psutil
def get_cpu_usage(interval=1):
"""Returns the current CPU usage as a percentage."""
return psutil.cpu_percent(interval=interval)
ב-vm_monitor/disk_monitor.py
:
import psutil
def get_disk_usage(path="/"):
"""Returns the current disk usage as a percentage."""
disk_info = psutil.disk_usage(path)
return disk_info.percent
ב-vm_monitor/memory_monitor.py
:
import psutil
def get_memory_usage():
"""Returns the current memory usage as a percentage."""
memory_info = psutil.virtual_memory()
return memory_info.percent
@lru_cache
כיוון שהפונקציות הללו צריכות להחזיר מידע מעודכן בכל קריאה, אין צורך להשתמש במטמון (lru_cache
) על פונקציות אלה.
במקום להגדיר את הגדרות הלוגים בקוד הראשי, ניתן ליצור קובץ חדש כמו logs_utils.py
ולשים בו את פונקציות ההגדרה.
ב-logs_utils.py
:
import os
import logging
def create_log_directory(log_dir):
"""
Creates the log directory if it does not exist.
Args:
log_dir (str): The directory where logs should be saved.
"""
try:
if not os.path.exists(log_dir):
os.makedirs(log_dir)
print(f"Created logs directory at {log_dir}")
else:
print(f"Log directory already exists at {log_dir}")
except OSError as e:
print(f"Error creating log directory: {e}")
raise
def configure_logging(log_dir, log_file="log.log"):
"""
Configures the logging settings.
Args:
log_dir (str): The directory where logs should be saved.
log_file (str): The log file name. Defaults to 'log.log'.
"""
log_path = os.path.join(log_dir, log_file)
logging.basicConfig(
filename=log_path,
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
)
monitor.py
העברת קוד של יצירת תיקיית הלוגים והגדרת הלוגים לפונקציות ב-logs_utils.py
.
ב-monitor.py
:
import logging
from vm_monitor.cpu_monitor import get_cpu_usage
from vm_monitor.memory_monitor import get_memory_usage
from vm_monitor.disk_monitor import get_disk_usage
from logs_utils import create_log_directory, configure_logging
def monitor_resources():
cpu_usage = get_cpu_usage()
memory_usage = get_memory_usage()
disk_usage = get_disk_usage()
logging.info(f"CPU Usage: {cpu_usage}%")
logging.info(f"Memory Usage: {memory_usage}%")
logging.info(f"Disk Usage: {disk_usage}%")
def monitor_resources_periodically(interval=10):
create_log_directory("/home/dell/Desktop/monitor_agent/logs")
configure_logging("/home/dell/Desktop/monitor_agent/logs")
while True:
monitor_resources()
time.sleep(interval)
if __name__ == "__main__":
print("Starting monitoring script...")
monitor_resources_periodically()
logging.basicConfig
במקום זאת, יצירת אובייקט Logger
ייעודי שיכול לשמש עבור לוגים שונים עם פורמטים ורמות שונות במידת הצורך.
העדכונים כוללים שיפור מבנה הקוד לפי עקרונות Object-Oriented Programming והגדרת לוגים בצורה מודולרית ונכונה יותר, מה שיאפשר גמישות וניהול טובים יותר של התכנית בעתיד.
A