Ver3.0 ๐ป ์์คํ ๋ชจ๋ํฐ๋ง ํด ์๋ฒฝ ๊ฐ์ด๋

๐ป ์์คํ ๋ชจ๋ํฐ๋ง ํด ์๋ฒฝ ๊ฐ์ด๋
CPU์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ค์๊ฐ์ผ๋ก ์ถ์ ํ๋ ๋ชจ๋ํฐ๋ง ํด ์์ค์ฝ๋ ์์ ์ ๋ณต! ๐
๐ฏ ์ ์์คํ ๋ชจ๋ํฐ๋ง ํด์ด ํ์ํ ๊น?
์น๊ตฌ์ผ, ์ปดํจํฐ๊ฐ ๊ฐ์๊ธฐ ๋๋ ค์ง๊ฑฐ๋ ํ๋ก๊ทธ๋จ์ด ๋จนํต์ด ๋ ๋ ๋ต๋ตํ๋ ๊ฒฝํ ์์ง? ๐ค
๊ทธ๋ด ๋ ํ์ํ ๊ฒ ๋ฐ๋ก ์์คํ
๋ชจ๋ํฐ๋ง ํด์ด์ผ!
CPU๊ฐ ์ผ๋ง๋ ์ผํ๊ณ ์๋์ง, ๋ฉ๋ชจ๋ฆฌ๋ ์ผ๋ง๋ ์ฌ์ฉ ์ค์ธ์ง ์ค์๊ฐ์ผ๋ก ํ์ธํ ์ ์๋ค๋ฉด
๋ฌธ์ ์ ์์ธ์ ๋น ๋ฅด๊ฒ ์ฐพ์๋ผ ์ ์๊ฑฐ๋ . ๋ง์น ์๋์ฐจ ๊ณ๊ธฐํ์ฒ๋ผ ๋ง์ด์ผ! ๐๐จ
์ค๋์ ์ง์ ๋ง๋ค์ด๋ณผ ์ ์๋ ์์คํ
๋ชจ๋ํฐ๋ง ํด์ ์์ค์ฝ๋๋ฅผ ํํค์ณ๋ณผ ๊ฑฐ์ผ.
์ด๋ณด์๋ ์ดํดํ ์ ์๊ฒ ์น์ ํ๊ฒ ์ค๋ช
ํด์ค ํ
๋ ๊ฑฑ์ ๋ง! ๐
๐ ๏ธ ์์คํ ๋ชจ๋ํฐ๋ง ํด์ ํต์ฌ ๊ตฌ์ฑ์์
๋ชจ๋ํฐ๋ง ํด์ ๋ง๋ค๊ธฐ ์ ์ ์ด๋ค ๋ถํ๋ค์ด ํ์ํ์ง ์์๋ณด์!
๋ง์น ๋ ๊ณ ๋ธ๋ก์ ์กฐ๋ฆฝํ๋ฏ์ด, ๊ฐ ๋ถ๋ถ์ ์ดํดํ๋ฉด ์ ์ฒด ๊ทธ๋ฆผ์ด ๋ณด์ผ ๊ฑฐ์ผ. ๐งฉ
๐ 1. ๋ฐ์ดํฐ ์์ง ๋ชจ๋
์์คํ
์ ๋ณด๋ฅผ ์ค์๊ฐ์ผ๋ก ๊ฐ์ ธ์ค๋ ํต์ฌ ์์ง์ด์ผ.
์ด์์ฒด์ ์ ๋ํํ๋ฉด์ CPU ์ฌ์ฉ๋ฅ , ๋ฉ๋ชจ๋ฆฌ ์ํ ๊ฐ์ ์ ๋ณด๋ฅผ ์์งํ์ง.
Windows Linux macOS
๊ฐ ์ด์์ฒด์ ๋ง๋ค ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ด ์กฐ๊ธ์ฉ ๋ค๋ฅด๋ค๋ ์ ! ๊ธฐ์ตํด๋ฌ. ๐ฏ
๐ 2. ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐ ๋ถ์ ๋ชจ๋
์์งํ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋์ด ์ดํดํ๊ธฐ ์ฌ์ด ํํ๋ก ๊ฐ๊ณตํ๋ ๋ถ๋ถ์ด์ผ.
๋ฐ์ดํธ๋ฅผ ๊ธฐ๊ฐ๋ฐ์ดํธ๋ก ๋ณํํ๊ฑฐ๋, ํ๊ท ๊ฐ์ ๊ณ์ฐํ๋ ๋ฑ์ ์์
์ ์ํํด.
์ด ๊ณผ์ ์ด ์์ผ๋ฉด ์ซ์ ๋๋ฏธ๋ง ๋ณด๊ฒ ๋ ๊ฑฐ์ผ! ๐
๐ 3. ์๊ฐํ ์ธํฐํ์ด์ค
๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ํ, ์ฐจํธ, ๊ฒ์ด์ง ๊ฐ์ ์๊ฐ์ ์์๋ก ํํํ๋ ๋ถ๋ถ!
์ซ์๋ง ๋ณด๋ ๊ฒ๋ณด๋ค ๊ทธ๋ํ๋ก ๋ณด๋ฉด ํจ์ฌ ์ง๊ด์ ์ด์์? ๐
์ค์๊ฐ์ผ๋ก ์
๋ฐ์ดํธ๋๋ ๋์ ์ธ UI๊ฐ ํต์ฌ์ด์ผ.
๐ 4. ์๋ฆผ ๋ฐ ๋ก๊น ์์คํ
CPU๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์ด ์ํ ์์ค์ ๋๋ฌํ๋ฉด ๊ฒฝ๊ณ ๋ฅผ ๋ณด๋ด์ฃผ๋ ๊ธฐ๋ฅ!
๋ํ ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋กํด์ ๋์ค์ ๋ถ์ํ ์ ์๊ฒ ํด์ฃผ์ง.
๋ฌธ์ ๊ฐ ์ธ์ ๋ฐ์ํ๋์ง ์ถ์ ํ ์ ์์ด์ ์ ๋ง ์ ์ฉํด. ๐
๐ก Python์ผ๋ก ๋ง๋๋ ์์คํ ๋ชจ๋ํฐ๋ง ํด
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํด๋ณผ๊น?
Python์ ์์คํ
๋ชจ๋ํฐ๋ง์ ์ต์ ํ๋ ์ธ์ด์ผ. ๊ฐ๊ฒฐํ๊ณ ๊ฐ๋ ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ๋ง๊ฑฐ๋ ! ๐
๋จผ์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ถํฐ ์ค์นํด๋ณด์.
๋ค์ํ ์ ๋ฌธ๊ฐ๋ค์ด ์ด๋ณด์๋ฅผ ์ํ ๋ง์ถคํ ๊ฐ์๋ฅผ ์ ๊ณตํ๊ณ ์๊ฑฐ๋ . ๐
๐ง ํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
# psutil: ์์คํ
์ ๋ณด ์์ง์ ์ํ ํต์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
pip install psutil
# matplotlib: ๊ทธ๋ํ ์๊ฐํ๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
pip install matplotlib
# tkinter: GUI ์ธํฐํ์ด์ค (Python ๊ธฐ๋ณธ ๋ด์ฅ)
# ๋ณ๋ ์ค์น ๋ถํ์
psutil์ ์ ๋ง ๊ฐ๋ ฅํ ๋๊ตฌ์ผ!
CPU, ๋ฉ๋ชจ๋ฆฌ, ๋์คํฌ, ๋คํธ์ํฌ ๋ฑ ๊ฑฐ์ ๋ชจ๋ ์์คํ
์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ด.
ํฌ๋ก์ค ํ๋ซํผ์ ์ง์ํด์ Windows, Linux, macOS ๋ชจ๋์์ ๋์ผํ๊ฒ ์๋ํ์ง. ๐
๐ ๊ธฐ๋ณธ ๋ชจ๋ํฐ๋ง ์ฝ๋ - CPU ์ฌ์ฉ๋ฅ
import psutil
import time
def monitor_cpu():
"""CPU ์ฌ์ฉ๋ฅ ์ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํ๋ ํจ์"""
print("=== CPU ๋ชจ๋ํฐ๋ง ์์ ===\n")
try:
while True:
# ์ ์ฒด CPU ์ฌ์ฉ๋ฅ (1์ด ๊ฐ๊ฒฉ์ผ๋ก ์ธก์ )
cpu_percent = psutil.cpu_percent(interval=1)
# ๊ฐ ์ฝ์ด๋ณ ์ฌ์ฉ๋ฅ
cpu_per_core = psutil.cpu_percent(interval=1, percpu=True)
# ํ์ฌ ์๊ฐ
current_time = time.strftime("%H:%M:%S")
# ๊ฒฐ๊ณผ ์ถ๋ ฅ
print(f"[{current_time}] ์ ์ฒด CPU ์ฌ์ฉ๋ฅ : {cpu_percent}%")
print(f"์ฝ์ด๋ณ ์ฌ์ฉ๋ฅ : {cpu_per_core}")
print("-" * 50)
time.sleep(2) # 2์ด๋ง๋ค ์
๋ฐ์ดํธ
except KeyboardInterrupt:
print("\n๋ชจ๋ํฐ๋ง์ ์ข
๋ฃํฉ๋๋ค.")
if __name__ == "__main__":
monitor_cpu()
โ 1์ด ๋์์ ํ๊ท CPU ์ฌ์ฉ๋ฅ ์ ์ธก์ ํด. interval ๊ฐ์ด ํด์๋ก ๋ ์ ํํ์ง๋ง ์๋ต์ด ๋๋ ค์ ธ.
percpu=True
โ ๊ฐ CPU ์ฝ์ด๋ณ๋ก ์ฌ์ฉ๋ฅ ์ ๋ฆฌ์คํธ๋ก ๋ฐํํด. ๋ฉํฐ์ฝ์ด ์์คํ ์์ ์ ์ฉํ์ง!
KeyboardInterrupt
โ Ctrl+C๋ฅผ ๋๋ฌ์ ํ๋ก๊ทธ๋จ์ ์์ ํ๊ฒ ์ข ๋ฃํ ์ ์๊ฒ ํด์ค. ๐
๐ ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง ์ฝ๋
import psutil
def monitor_memory():
"""๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ํํฉ์ ๋ชจ๋ํฐ๋งํ๋ ํจ์"""
# ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด
memory = psutil.virtual_memory()
# ์ค์ ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด
swap = psutil.swap_memory()
# ๋ฐ์ดํธ๋ฅผ GB๋ก ๋ณํํ๋ ํจ์
def bytes_to_gb(bytes_value):
return round(bytes_value / (1024**3), 2)
print("=== ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง ===\n")
# ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด ์ถ๋ ฅ
print(f"๐ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ: {bytes_to_gb(memory.total)} GB")
print(f"๐ ์ฌ์ฉ ์ค: {bytes_to_gb(memory.used)} GB")
print(f"๐ ์ฌ์ฉ ๊ฐ๋ฅ: {bytes_to_gb(memory.available)} GB")
print(f"๐ ์ฌ์ฉ๋ฅ : {memory.percent}%")
print()
# ์ค์ ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด ์ถ๋ ฅ
print(f"๐พ ์ค์ ์ ์ฒด: {bytes_to_gb(swap.total)} GB")
print(f"๐พ ์ค์ ์ฌ์ฉ: {bytes_to_gb(swap.used)} GB")
print(f"๐พ ์ค์ ์ฌ์ฉ๋ฅ : {swap.percent}%")
# ๋ฉ๋ชจ๋ฆฌ ์ํ ํ๋จ
if memory.percent > 90:
print("\nโ ๏ธ ๊ฒฝ๊ณ : ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์ด ๋งค์ฐ ๋์ต๋๋ค!")
elif memory.percent > 75:
print("\nโก ์ฃผ์: ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์ด ๋์ ํธ์
๋๋ค.")
else:
print("\nโ
๋ฉ๋ชจ๋ฆฌ ์ํ๊ฐ ์ํธํฉ๋๋ค.")
if __name__ == "__main__":
monitor_memory()
๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง์์ ์ค์ํ ๊ฑด available๊ณผ free์ ์ฐจ์ด์ผ!
free๋ ์์ ํ ๋น์ด์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋ฏธํ๊ณ ,
available์ ์บ์๋ ๋ฒํผ๋ก ์ฌ์ฉ ์ค์ด์ง๋ง ํ์ํ๋ฉด ์ฆ์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๊น์ง ํฌํจํด.
์ค์ ๋ก๋ available ๊ฐ์ด ๋ ์ค์ํ์ง! ๐ฏ
๐จ GUI ๊ธฐ๋ฐ ๋ชจ๋ํฐ๋ง ํด ๋ง๋ค๊ธฐ
์ฝ์ ์ฐฝ์์ ์ซ์๋ง ๋ณด๋ ๊ฑด ์ข ์ฌ์ฌํ์ง?
์ด์ ๋ฉ์ง ๊ทธ๋ํฝ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ๋ชจ๋ํฐ๋ง ํด์ ๋ง๋ค์ด๋ณด์! ๐ผ๏ธ
tkinter๋ฅผ ์ฌ์ฉํ๋ฉด ์๊ฐ๋ณด๋ค ์ฝ๊ฒ GUI๋ฅผ ๋ง๋ค ์ ์์ด.
๐ฅ๏ธ ์ค์๊ฐ ์ ๋ฐ์ดํธ GUI ๋ชจ๋ํฐ
import tkinter as tk
from tkinter import ttk
import psutil
import threading
import time
class SystemMonitor:
def __init__(self, root):
self.root = root
self.root.title("์์คํ
๋ชจ๋ํฐ๋ง ํด v1.0")
self.root.geometry("600x400")
self.root.resizable(False, False)
# ๋ชจ๋ํฐ๋ง ํ์ฑํ ํ๋๊ทธ
self.monitoring = True
# UI ๊ตฌ์ฑ
self.setup_ui()
# ๋ชจ๋ํฐ๋ง ์ค๋ ๋ ์์
self.monitor_thread = threading.Thread(target=self.update_stats, daemon=True)
self.monitor_thread.start()
def setup_ui(self):
"""UI ๊ตฌ์ฑ ์์ ์ค์ """
# ํ์ดํ ํ๋ ์
title_frame = tk.Frame(self.root, bg="#667eea", height=80)
title_frame.pack(fill=tk.X)
title_label = tk.Label(
title_frame,
text="๐ป ์์คํ
๋ชจ๋ํฐ",
font=("Arial", 24, "bold"),
bg="#667eea",
fg="white"
)
title_label.pack(pady=20)
# ๋ฉ์ธ ์ปจํ
์ธ ํ๋ ์
content_frame = tk.Frame(self.root, bg="#f8f9fa")
content_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
# CPU ์น์
cpu_frame = tk.LabelFrame(
content_frame,
text="๐ฅ CPU ์ฌ์ฉ๋ฅ ",
font=("Arial", 12, "bold"),
bg="#f8f9fa",
padx=10,
pady=10
)
cpu_frame.pack(fill=tk.X, pady=(0, 10))
self.cpu_label = tk.Label(
cpu_frame,
text="์ธก์ ์ค...",
font=("Arial", 16),
bg="#f8f9fa"
)
self.cpu_label.pack()
self.cpu_progress = ttk.Progressbar(
cpu_frame,
length=500,
mode='determinate'
)
self.cpu_progress.pack(pady=5)
# ๋ฉ๋ชจ๋ฆฌ ์น์
memory_frame = tk.LabelFrame(
content_frame,
text="๐พ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ",
font=("Arial", 12, "bold"),
bg="#f8f9fa",
padx=10,
pady=10
)
memory_frame.pack(fill=tk.X, pady=(0, 10))
self.memory_label = tk.Label(
memory_frame,
text="์ธก์ ์ค...",
font=("Arial", 16),
bg="#f8f9fa"
)
self.memory_label.pack()
self.memory_progress = ttk.Progressbar(
memory_frame,
length=500,
mode='determinate'
)
self.memory_progress.pack(pady=5)
# ์์ธ ์ ๋ณด ์น์
detail_frame = tk.LabelFrame(
content_frame,
text="๐ ์์ธ ์ ๋ณด",
font=("Arial", 12, "bold"),
bg="#f8f9fa",
padx=10,
pady=10
)
detail_frame.pack(fill=tk.BOTH, expand=True)
self.detail_text = tk.Text(
detail_frame,
height=6,
font=("Courier", 10),
bg="#ffffff",
relief=tk.FLAT
)
self.detail_text.pack(fill=tk.BOTH, expand=True)
def update_stats(self):
"""์์คํ
ํต๊ณ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ์
๋ฐ์ดํธ"""
while self.monitoring:
try:
# CPU ์ ๋ณด ์์ง
cpu_percent = psutil.cpu_percent(interval=1)
cpu_count = psutil.cpu_count()
# ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด ์์ง
memory = psutil.virtual_memory()
memory_percent = memory.percent
memory_used = round(memory.used / (1024**3), 2)
memory_total = round(memory.total / (1024**3), 2)
# UI ์
๋ฐ์ดํธ
self.root.after(0, self.update_ui, cpu_percent, memory_percent,
cpu_count, memory_used, memory_total)
time.sleep(1)
except Exception as e:
print(f"์ค๋ฅ ๋ฐ์: {e}")
break
def update_ui(self, cpu_percent, memory_percent, cpu_count, memory_used, memory_total):
"""UI ์์ ์
๋ฐ์ดํธ"""
# CPU ์
๋ฐ์ดํธ
self.cpu_label.config(text=f"{cpu_percent}%")
self.cpu_progress['value'] = cpu_percent
# ์์ ๋ณ๊ฒฝ (์ฌ์ฉ๋ฅ ์ ๋ฐ๋ผ)
if cpu_percent > 80:
self.cpu_label.config(fg="red")
elif cpu_percent > 60:
self.cpu_label.config(fg="orange")
else:
self.cpu_label.config(fg="green")
# ๋ฉ๋ชจ๋ฆฌ ์
๋ฐ์ดํธ
self.memory_label.config(text=f"{memory_percent}%")
self.memory_progress['value'] = memory_percent
if memory_percent > 80:
self.memory_label.config(fg="red")
elif memory_percent > 60:
self.memory_label.config(fg="orange")
else:
self.memory_label.config(fg="green")
# ์์ธ ์ ๋ณด ์
๋ฐ์ดํธ
detail_info = f"""
CPU ์ฝ์ด ์: {cpu_count}๊ฐ
CPU ์ฌ์ฉ๋ฅ : {cpu_percent}%
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ: {memory_used} GB / {memory_total} GB
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ : {memory_percent}%
์
๋ฐ์ดํธ ์๊ฐ: {time.strftime("%H:%M:%S")}
"""
self.detail_text.delete(1.0, tk.END)
self.detail_text.insert(1.0, detail_info.strip())
def on_closing(self):
"""ํ๋ก๊ทธ๋จ ์ข
๋ฃ ์ ์ฒ๋ฆฌ"""
self.monitoring = False
self.root.destroy()
def main():
root = tk.Tk()
app = SystemMonitor(root)
root.protocol("WM_DELETE_WINDOW", app.on_closing)
root.mainloop()
if __name__ == "__main__":
main()
โ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ฉด์ UI๋ ๊ณ์ ๋ฐ์ํ ์ ์๊ฒ ํด์ค.
threading ์์ด while ๋ฃจํ๋ฅผ ๋๋ฆฌ๋ฉด UI๊ฐ ๋ฉ์ถฐ๋ฒ๋ ค! ๐ฑ
root.after() ๋ฉ์๋
โ ๋ค๋ฅธ ์ค๋ ๋์์ tkinter UI๋ฅผ ์ง์ ์์ ํ๋ฉด ์ ๋ผ.
after()๋ฅผ ์ฌ์ฉํด์ ๋ฉ์ธ ์ค๋ ๋์์ UI๋ฅผ ์ ๋ฐ์ดํธํด์ผ ํด.
daemon=True
โ ๋ฉ์ธ ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋๋ฉด ์ค๋ ๋๋ ์๋์ผ๋ก ์ข ๋ฃ๋๊ฒ ํด์ค. ๐
๋ฉ์ธ ์ค๋ ๋์์ ๋ฌดํ ๋ฃจํ๋ฅผ ๋๋ฆฌ๋ฉด UI๊ฐ ์๋ตํ์ง ์๊ฒ ๋ผ.
๋ํ ํ๋ก๊ทธ๋จ ์ข ๋ฃ ์ ์ค๋ ๋๋ฅผ ์ ๋๋ก ์ ๋ฆฌํ์ง ์์ผ๋ฉด ์ข๋น ํ๋ก์ธ์ค๊ฐ ๋จ์ ์ ์์ด. ๐ป
๐ ๊ทธ๋ํ๋ก ์๊ฐํํ๊ธฐ
์ซ์์ ํ๋ก๊ทธ๋ ์ค ๋ฐ๋ ์ข์ง๋ง, ์๊ฐ์ ๋ฐ๋ฅธ ๋ณํ๋ฅผ ๋ณด๋ ค๋ฉด ๊ทธ๋ํ๊ฐ ์ต๊ณ ์ผ!
matplotlib๋ฅผ ์ฌ์ฉํด์ ์ค์๊ฐ ๊ทธ๋ํ๋ฅผ ๊ทธ๋ ค๋ณด์. ๐
๐ฏ ์ค์๊ฐ ๋ผ์ธ ์ฐจํธ ๊ตฌํ
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import psutil
import tkinter as tk
from collections import deque
class RealtimeMonitor:
def __init__(self, root):
self.root = root
self.root.title("์ค์๊ฐ ์์คํ
๋ชจ๋ํฐ")
self.root.geometry("900x600")
# ๋ฐ์ดํฐ ์ ์ฅ์ฉ deque (์ต๋ 60๊ฐ ๋ฐ์ดํฐ ํฌ์ธํธ)
self.cpu_data = deque([0] * 60, maxlen=60)
self.memory_data = deque([0] * 60, maxlen=60)
self.time_data = deque(range(60), maxlen=60)
# ๊ทธ๋ํ ์ค์
self.setup_plot()
# ์ ๋๋ฉ์ด์
์์
self.ani = animation.FuncAnimation(
self.fig,
self.update_plot,
interval=1000, # 1์ด๋ง๋ค ์
๋ฐ์ดํธ
blit=False
)
def setup_plot(self):
"""๊ทธ๋ํ ์ด๊ธฐ ์ค์ """
# Figure ์์ฑ
self.fig, (self.ax1, self.ax2) = plt.subplots(2, 1, figsize=(9, 6))
self.fig.patch.set_facecolor('#f8f9fa')
# CPU ๊ทธ๋ํ ์ค์
self.ax1.set_title('CPU ์ฌ์ฉ๋ฅ (%)', fontsize=14, fontweight='bold')
self.ax1.set_ylim(0, 100)
self.ax1.set_xlim(0, 60)
self.ax1.grid(True, alpha=0.3)
self.ax1.set_facecolor('#ffffff')
self.line1, = self.ax1.plot([], [], 'b-', linewidth=2, label='CPU')
self.ax1.legend(loc='upper right')
self.ax1.set_ylabel('์ฌ์ฉ๋ฅ (%)')
# ๋ฉ๋ชจ๋ฆฌ ๊ทธ๋ํ ์ค์
self.ax2.set_title('๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ (%)', fontsize=14, fontweight='bold')
self.ax2.set_ylim(0, 100)
self.ax2.set_xlim(0, 60)
self.ax2.grid(True, alpha=0.3)
self.ax2.set_facecolor('#ffffff')
self.line2, = self.ax2.plot([], [], 'r-', linewidth=2, label='Memory')
self.ax2.legend(loc='upper right')
self.ax2.set_xlabel('์๊ฐ (์ด)')
self.ax2.set_ylabel('์ฌ์ฉ๋ฅ (%)')
# ๋ ์ด์์ ์กฐ์
plt.tight_layout()
# tkinter์ ๊ทธ๋ํ ์ฝ์
self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)
self.canvas.draw()
self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
def update_plot(self, frame):
"""๊ทธ๋ํ ๋ฐ์ดํฐ ์
๋ฐ์ดํธ"""
# ์์คํ
์ ๋ณด ์์ง
cpu_percent = psutil.cpu_percent(interval=0.1)
memory_percent = psutil.virtual_memory().percent
# ๋ฐ์ดํฐ ์ถ๊ฐ
self.cpu_data.append(cpu_percent)
self.memory_data.append(memory_percent)
# ๊ทธ๋ํ ์
๋ฐ์ดํธ
self.line1.set_data(range(60), list(self.cpu_data))
self.line2.set_data(range(60), list(self.memory_data))
# ํ์ฌ ๊ฐ ํ์
self.ax1.set_title(
f'CPU ์ฌ์ฉ๋ฅ : {cpu_percent:.1f}%',
fontsize=14,
fontweight='bold'
)
self.ax2.set_title(
f'๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ : {memory_percent:.1f}%',
fontsize=14,
fontweight='bold'
)
return self.line1, self.line2
def main():
root = tk.Tk()
app = RealtimeMonitor(root)
root.mainloop()
if __name__ == "__main__":
main()
deque๋ ์ ๋ง ์ ์ฉํ ์๋ฃ๊ตฌ์กฐ์ผ!
maxlen์ ์ค์ ํ๋ฉด ์๋์ผ๋ก ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ๋ฒ๋ฆฌ๊ณ ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํด.
๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ด๋ฉด์๋ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง์ง! ๐ฏ
animation.FuncAnimation์ matplotlib์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ด์ผ.
์ง์ ํ ๊ฐ๊ฒฉ๋ง๋ค ์๋์ผ๋ก ํจ์๋ฅผ ํธ์ถํด์ ๊ทธ๋ํ๋ฅผ ์
๋ฐ์ดํธํด์ค.
์ค์๊ฐ ๋ชจ๋ํฐ๋ง์ ๋ฑ ๋ง๋ ๋๊ตฌ์ง! โก
๐ ์๋ฆผ ์์คํ ๊ตฌํํ๊ธฐ
์์คํ
๋ฆฌ์์ค๊ฐ ์ํ ์์ค์ ๋๋ฌํ๋ฉด ์๋ ค์ฃผ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํด๋ณด์!
์ฌ์ฉ์๊ฐ ํ๋ฉด์ ๊ณ์ ๋ณด๊ณ ์์ง ์์๋ ๋ฌธ์ ๋ฅผ ์ธ์งํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฑฐ์ผ. ๐จ
โก ์๊ณ๊ฐ ๊ธฐ๋ฐ ์๋ฆผ ์์คํ
import psutil
import time
import winsound # Windows ์ ์ฉ (๋ค๋ฅธ OS๋ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ)
from datetime import datetime
import json
class AlertSystem:
def __init__(self, cpu_threshold=80, memory_threshold=85):
"""
์๋ฆผ ์์คํ
์ด๊ธฐํ
Args:
cpu_threshold: CPU ์ฌ์ฉ๋ฅ ์๊ณ๊ฐ (%)
memory_threshold: ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์๊ณ๊ฐ (%)
"""
self.cpu_threshold = cpu_threshold
self.memory_threshold = memory_threshold
# ์๋ฆผ ๊ธฐ๋ก
self.alert_history = []
# ์ฐ์ ์๋ฆผ ๋ฐฉ์ง๋ฅผ ์ํ ์ฟจ๋ค์ด (์ด)
self.cooldown = 60
self.last_cpu_alert = 0
self.last_memory_alert = 0
def check_cpu(self):
"""CPU ์ฌ์ฉ๋ฅ ์ฒดํฌ"""
cpu_percent = psutil.cpu_percent(interval=1)
current_time = time.time()
if cpu_percent > self.cpu_threshold:
# ์ฟจ๋ค์ด ์ฒดํฌ
if current_time - self.last_cpu_alert > self.cooldown:
self.trigger_alert(
"CPU",
cpu_percent,
self.cpu_threshold
)
self.last_cpu_alert = current_time
return True
return False
def check_memory(self):
"""๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์ฒดํฌ"""
memory = psutil.virtual_memory()
memory_percent = memory.percent
current_time = time.time()
if memory_percent > self.memory_threshold:
if current_time - self.last_memory_alert > self.cooldown:
self.trigger_alert(
"Memory",
memory_percent,
self.memory_threshold
)
self.last_memory_alert = current_time
return True
return False
def trigger_alert(self, resource_type, current_value, threshold):
"""์๋ฆผ ๋ฐ์"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
alert_info = {
"timestamp": timestamp,
"type": resource_type,
"value": current_value,
"threshold": threshold
}
# ์๋ฆผ ๊ธฐ๋ก ์ ์ฅ
self.alert_history.append(alert_info)
# ์ฝ์ ์ถ๋ ฅ
print("\n" + "="*50)
print(f"โ ๏ธ ๊ฒฝ๊ณ ์๋ฆผ!")
print(f"์๊ฐ: {timestamp}")
print(f"์ ํ: {resource_type}")
print(f"ํ์ฌ ๊ฐ: {current_value:.1f}%")
print(f"์๊ณ๊ฐ: {threshold}%")
print("="*50 + "\n")
# ์๋ฆฌ ์๋ฆผ (Windows)
try:
winsound.Beep(1000, 500) # 1000Hz, 500ms
except:
pass # ๋ค๋ฅธ OS์์๋ ๋ฌด์
# ๋ก๊ทธ ํ์ผ์ ๊ธฐ๋ก
self.save_to_log(alert_info)
def save_to_log(self, alert_info):
"""์๋ฆผ์ ๋ก๊ทธ ํ์ผ์ ์ ์ฅ"""
try:
with open("system_alerts.log", "a", encoding="utf-8") as f:
log_entry = json.dumps(alert_info, ensure_ascii=False)
f.write(log_entry + "\n")
except Exception as e:
print(f"๋ก๊ทธ ์ ์ฅ ์คํจ: {e}")
def get_alert_summary(self):
"""์๋ฆผ ์์ฝ ์ ๋ณด ๋ฐํ"""
if not self.alert_history:
return "์๋ฆผ ๊ธฐ๋ก์ด ์์ต๋๋ค."
cpu_alerts = sum(1 for a in self.alert_history if a['type'] == 'CPU')
memory_alerts = sum(1 for a in self.alert_history if a['type'] == 'Memory')
summary = f"""
๐ ์๋ฆผ ์์ฝ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
์ด ์๋ฆผ ์: {len(self.alert_history)}๊ฐ
CPU ์๋ฆผ: {cpu_alerts}๊ฐ
๋ฉ๋ชจ๋ฆฌ ์๋ฆผ: {memory_alerts}๊ฐ
์ต๊ทผ ์๋ฆผ:
"""
# ์ต๊ทผ 5๊ฐ ์๋ฆผ ํ์
for alert in self.alert_history[-5:]:
summary += f"\n[{alert['timestamp']}] {alert['type']}: {alert['value']:.1f}%"
return summary
def monitor(self, duration=None):
"""
์ง์์ ์ธ ๋ชจ๋ํฐ๋ง ์์
Args:
duration: ๋ชจ๋ํฐ๋ง ์๊ฐ(์ด), None์ด๋ฉด ๋ฌดํ ์คํ
"""
print("๐ ์์คํ
๋ชจ๋ํฐ๋ง์ ์์ํฉ๋๋ค...")
print(f"CPU ์๊ณ๊ฐ: {self.cpu_threshold}%")
print(f"๋ฉ๋ชจ๋ฆฌ ์๊ณ๊ฐ: {self.memory_threshold}%")
print("\n์ข
๋ฃํ๋ ค๋ฉด Ctrl+C๋ฅผ ๋๋ฅด์ธ์.\n")
start_time = time.time()
try:
while True:
# ์๊ฐ ์ ํ ์ฒดํฌ
if duration and (time.time() - start_time) > duration:
break
# CPU ์ฒดํฌ
self.check_cpu()
# ๋ฉ๋ชจ๋ฆฌ ์ฒดํฌ
self.check_memory()
# ํ์ฌ ์ํ ์ถ๋ ฅ
cpu = psutil.cpu_percent(interval=0.1)
memory = psutil.virtual_memory().percent
print(f"[{datetime.now().strftime('%H:%M:%S')}] "
f"CPU: {cpu:.1f}% | Memory: {memory:.1f}%", end='\r')
time.sleep(5) # 5์ด๋ง๋ค ์ฒดํฌ
except KeyboardInterrupt:
print("\n\n๋ชจ๋ํฐ๋ง์ ์ข
๋ฃํฉ๋๋ค.")
print(self.get_alert_summary())
# ์ฌ์ฉ ์์
if __name__ == "__main__":
# ์๋ฆผ ์์คํ
์์ฑ (CPU 80%, ๋ฉ๋ชจ๋ฆฌ 85% ์๊ณ๊ฐ)
alert_system = AlertSystem(cpu_threshold=80, memory_threshold=85)
# ๋ชจ๋ํฐ๋ง ์์
alert_system.monitor()
2. Slack/Discord ์ฐ๋: ์นํ ์ ์ฌ์ฉํด์ ๋ฉ์ ์ ๋ก ์๋ฆผ
3. ๋ฐ์คํฌํฑ ์๋ฆผ: plyer ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์์คํ ํธ๋ ์ด ์๋ฆผ
4. SMS ์๋ฆผ: Twilio API๋ฅผ ์ฌ์ฉํด์ ๋ฌธ์ ๋ฉ์์ง ์ ์ก
ํ๋ก์ ํธ ๊ท๋ชจ์ ํ์์ ๋ฐ๋ผ ์ ํํ๋ฉด ๋ผ! ๐ฏ
๐พ ๋ฐ์ดํฐ ๋ก๊น ๋ฐ ๋ถ์
์ค์๊ฐ ๋ชจ๋ํฐ๋ง๋ ์ค์ํ์ง๋ง, ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๋ ๊ฒ๋ ๋งค์ฐ ์ ์ฉํด!
์ธ์ ์์คํ
๋ถํ๊ฐ ๋์๋์ง, ์ด๋ค ํจํด์ด ์๋์ง ํ์
ํ ์ ์๊ฑฐ๋ . ๐
๐ CSV ํ์ผ๋ก ๋ฐ์ดํฐ ์ ์ฅํ๊ธฐ
import psutil
import csv
import time
from datetime import datetime
import os
class DataLogger:
def __init__(self, log_file="system_log.csv"):
"""
๋ฐ์ดํฐ ๋ก๊ฑฐ ์ด๊ธฐํ
Args:
log_file: ๋ก๊ทธ ํ์ผ ๊ฒฝ๋ก
"""
self.log_file = log_file
self.initialize_log_file()
def initialize_log_file(self):
"""๋ก๊ทธ ํ์ผ ์ด๊ธฐํ (ํค๋ ์์ฑ)"""
# ํ์ผ์ด ์ด๋ฏธ ์กด์ฌํ๋ฉด ๊ฑด๋๋ฐ๊ธฐ
if os.path.exists(self.log_file):
print(f"๊ธฐ์กด ๋ก๊ทธ ํ์ผ์ ์ฌ์ฉํฉ๋๋ค: {self.log_file}")
return
# ์ ํ์ผ ์์ฑ ๋ฐ ํค๋ ์์ฑ
headers = [
"timestamp",
"cpu_percent",
"cpu_count",
"memory_total_gb",
"memory_used_gb",
"memory_percent",
"disk_usage_percent",
"network_sent_mb",
"network_recv_mb"
]
with open(self.log_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(headers)
print(f"์ ๋ก๊ทธ ํ์ผ์ ์์ฑํ์ต๋๋ค: {self.log_file}")
def collect_system_info(self):
"""ํ์ฌ ์์คํ
์ ๋ณด ์์ง"""
# CPU ์ ๋ณด
cpu_percent = psutil.cpu_percent(interval=1)
cpu_count = psutil.cpu_count()
# ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด
memory = psutil.virtual_memory()
memory_total = round(memory.total / (1024**3), 2)
memory_used = round(memory.used / (1024**3), 2)
memory_percent = memory.percent
# ๋์คํฌ ์ ๋ณด
disk = psutil.disk_usage('/')
disk_percent = disk.percent
# ๋คํธ์ํฌ ์ ๋ณด
network = psutil.net_io_counters()
network_sent = round(network.bytes_sent / (1024**2), 2)
network_recv = round(network.bytes_recv / (1024**2), 2)
# ํ์์คํฌํ
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return {
"timestamp": timestamp,
"cpu_percent": cpu_percent,
"cpu_count": cpu_count,
"memory_total_gb": memory_total,
"memory_used_gb": memory_used,
"memory_percent": memory_percent,
"disk_usage_percent": disk_percent,
"network_sent_mb": network_sent,
"network_recv_mb": network_recv
}
def log_data(self):
"""๋ฐ์ดํฐ๋ฅผ ๋ก๊ทธ ํ์ผ์ ๊ธฐ๋ก"""
info = self.collect_system_info()
with open(self.log_file, 'a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([
info["timestamp"],
info["cpu_percent"],
info["cpu_count"],
info["memory_total_gb"],
info["memory_used_gb"],
info["memory_percent"],
info["disk_usage_percent"],
info["network_sent_mb"],
info["network_recv_mb"]
])
return info
def start_logging(self, interval=60, duration=None):
"""
์ฃผ๊ธฐ์ ์ธ ๋ก๊น
์์
Args:
interval: ๋ก๊น
๊ฐ๊ฒฉ (์ด)
duration: ์ด ๋ก๊น
์๊ฐ (์ด), None์ด๋ฉด ๋ฌดํ
"""
print(f"๐ ๋ฐ์ดํฐ ๋ก๊น
์ ์์ํฉ๋๋ค.")
print(f"๋ก๊ทธ ํ์ผ: {self.log_file}")
print(f"๋ก๊น
๊ฐ๊ฒฉ: {interval}์ด")
print("\n์ข
๋ฃํ๋ ค๋ฉด Ctrl+C๋ฅผ ๋๋ฅด์ธ์.\n")
start_time = time.time()
log_count = 0
try:
while True:
# ์๊ฐ ์ ํ ์ฒดํฌ
if duration and (time.time() - start_time) > duration:
break
# ๋ฐ์ดํฐ ๋ก๊น
info = self.log_data()
log_count += 1
# ์งํ ์ํฉ ์ถ๋ ฅ
print(f"[{info['timestamp']}] "
f"๋ก๊ทธ #{log_count} | "
f"CPU: {info['cpu_percent']:.1f}% | "
f"Memory: {info['memory_percent']:.1f}%")
time.sleep(interval)
except KeyboardInterrupt:
print(f"\n\n๋ก๊น
์ ์ข
๋ฃํฉ๋๋ค.")
print(f"์ด {log_count}๊ฐ์ ๋ก๊ทธ๊ฐ ๊ธฐ๋ก๋์์ต๋๋ค.")
# ์ฌ์ฉ ์์
if __name__ == "__main__":
logger = DataLogger("system_log.csv")
# 60์ด๋ง๋ค ๋ก๊น
(๋ฌดํ ์คํ)
logger.start_logging(interval=60)
๐ ๋ก๊ทธ ๋ฐ์ดํฐ ๋ถ์ํ๊ธฐ
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
class LogAnalyzer:
def __init__(self, log_file="system_log.csv"):
"""๋ก๊ทธ ๋ถ์๊ธฐ ์ด๊ธฐํ"""
self.log_file = log_file
self.df = None
self.load_data()
def load_data(self):
"""CSV ํ์ผ์์ ๋ฐ์ดํฐ ๋ก๋"""
try:
self.df = pd.read_csv(self.log_file)
self.df['timestamp'] = pd.to_datetime(self.df['timestamp'])
print(f"โ
{len(self.df)}๊ฐ์ ๋ก๊ทธ๋ฅผ ๋ถ๋ฌ์์ต๋๋ค.")
except FileNotFoundError:
print(f"โ ๋ก๊ทธ ํ์ผ์ ์ฐพ์ ์ ์์ต๋๋ค: {self.log_file}")
except Exception as e:
print(f"โ ๋ฐ์ดํฐ ๋ก๋ ์คํจ: {e}")
def get_statistics(self):
"""๊ธฐ๋ณธ ํต๊ณ ์ ๋ณด ์ถ๋ ฅ"""
if self.df is None or self.df.empty:
print("๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.")
return
print("\n" + "="*60)
print("๐ ์์คํ
์ฌ์ฉ ํต๊ณ")
print("="*60)
# CPU ํต๊ณ
print("\n๐ฅ CPU ์ฌ์ฉ๋ฅ ")
print(f" ํ๊ท : {self.df['cpu_percent'].mean():.2f}%")
print(f" ์ต๋: {self.df['cpu_percent'].max():.2f}%")
print(f" ์ต์: {self.df['cpu_percent'].min():.2f}%")
# ๋ฉ๋ชจ๋ฆฌ ํต๊ณ
print("\n๐พ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ")
print(f" ํ๊ท : {self.df['memory_percent'].mean():.2f}%")
print(f" ์ต๋: {self.df['memory_percent'].max():.2f}%")
print(f" ์ต์: {self.df['memory_percent'].min():.2f}%")
# ๋์คํฌ ํต๊ณ
print("\n๐ฟ ๋์คํฌ ์ฌ์ฉ๋ฅ ")
print(f" ํ๊ท : {self.df['disk_usage_percent'].mean():.2f}%")
# ๋คํธ์ํฌ ํต๊ณ
print("\n๐ ๋คํธ์ํฌ ์ฌ์ฉ๋")
total_sent = self.df['network_sent_mb'].iloc[-1] - self.df['network_sent_mb'].iloc[0]
total_recv = self.df['network_recv_mb'].iloc[-1] - self.df['network_recv_mb'].iloc[0]
print(f" ์ ์ก: {total_sent:.2f} MB")
print(f" ์์ : {total_recv:.2f} MB")
print("\n" + "="*60 + "\n")
def plot_trends(self):
"""์๊ฐ์ ๋ฐ๋ฅธ ํธ๋ ๋ ๊ทธ๋ํ ์์ฑ"""
if self.df is None or self.df.empty:
print("๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.")
return
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('์์คํ
๋ชจ๋ํฐ๋ง ํธ๋ ๋ ๋ถ์', fontsize=16, fontweight='bold')
# CPU ์ฌ์ฉ๋ฅ
axes[0, 0].plot(self.df['timestamp'], self.df['cpu_percent'],
color='#667eea', linewidth=2)
axes[0, 0].set_title('CPU ์ฌ์ฉ๋ฅ ', fontweight='bold')
axes[0, 0].set_ylabel('์ฌ์ฉ๋ฅ (%)')
axes[0, 0].grid(True, alpha=0.3)
axes[0, 0].axhline(y=80, color='r', linestyle='--', alpha=0.5, label='์ํ ์์ค')
axes[0, 0].legend()
# ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ
axes[0, 1].plot(self.df['timestamp'], self.df['memory_percent'],
color='#f5576c', linewidth=2)
axes[0, 1].set_title('๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ', fontweight='bold')
axes[0, 1].set_ylabel('์ฌ์ฉ๋ฅ (%)')
axes[0, 1].grid(True, alpha=0.3)
axes[0, 1].axhline(y=85, color='r', linestyle='--', alpha=0.5, label='์ํ ์์ค')
axes[0, 1].legend()
# ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ (GB)
axes[1, 0].plot(self.df['timestamp'], self.df['memory_used_gb'],
color='#4facfe', linewidth=2)
axes[1, 0].set_title('๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋', fontweight='bold')
axes[1, 0].set_ylabel('์ฌ์ฉ๋ (GB)')
axes[1, 0].grid(True, alpha=0.3)
# ๋์คํฌ ์ฌ์ฉ๋ฅ
axes[1, 1].plot(self.df['timestamp'], self.df['disk_usage_percent'],
color='#43e97b', linewidth=2)
axes[1, 1].set_title('๋์คํฌ ์ฌ์ฉ๋ฅ ', fontweight='bold')
axes[1, 1].set_ylabel('์ฌ์ฉ๋ฅ (%)')
axes[1, 1].grid(True, alpha=0.3)
# ๋ ์ด์์ ์กฐ์
plt.tight_layout()
plt.show()
def find_peak_usage(self, top_n=5):
"""์ต๊ณ ์ฌ์ฉ๋ฅ ์์ ์ฐพ๊ธฐ"""
if self.df is None or self.df.empty:
print("๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.")
return
print("\n" + "="*60)
print(f"๐ CPU ์ฌ์ฉ๋ฅ ์์ {top_n}๊ฐ ์์ ")
print("="*60)
top_cpu = self.df.nlargest(top_n, 'cpu_percent')[['timestamp', 'cpu_percent']]
for idx, row in top_cpu.iterrows():
print(f"{row['timestamp']} - {row['cpu_percent']:.2f}%")
print("\n" + "="*60)
print(f"๐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ ์์ {top_n}๊ฐ ์์ ")
print("="*60)
top_memory = self.df.nlargest(top_n, 'memory_percent')[['timestamp', 'memory_percent']]
for idx, row in top_memory.iterrows():
print(f"{row['timestamp']} - {row['memory_percent']:.2f}%")
print("\n")
# ์ฌ์ฉ ์์
if __name__ == "__main__":
analyzer = LogAnalyzer("system_log.csv")
# ํต๊ณ ์ ๋ณด ์ถ๋ ฅ
analyzer.get_statistics()
# ์ต๊ณ ์ฌ์ฉ๋ฅ ์์ ์ฐพ๊ธฐ
analyzer.find_peak_usage(top_n=5)
# ํธ๋ ๋ ๊ทธ๋ํ ์์ฑ
analyzer.plot_trends()
pandas๋ ๋ฐ์ดํฐ ๋ถ์์ ํ์ ๋๊ตฌ์ผ!
CSV ํ์ผ์ DataFrame์ผ๋ก ์ฝ์ด์ค๋ฉด SQL์ฒ๋ผ ๋ฐ์ดํฐ๋ฅผ ์ฟผ๋ฆฌํ๊ณ ๋ถ์ํ ์ ์์ด.
๋์ฉ๋ ๋ฐ์ดํฐ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ์์ด์ ์ ๋ง ๊ฐ๋ ฅํ์ง! ๐ช
๐ ์น ๊ธฐ๋ฐ ๋ชจ๋ํฐ๋ง ๋์๋ณด๋
๋ฐ์คํฌํฑ ์ฑ๋ ์ข์ง๋ง, ์น ๋ธ๋ผ์ฐ์ ์์ ์ ๊ทผํ ์ ์๋ ๋์๋ณด๋๋ ์ด๋?
์ด๋์๋ ์ ์ํด์ ์์คํ
์ํ๋ฅผ ํ์ธํ ์ ์์ด์ ํธ๋ฆฌํด! ๐
Flask๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋จํ๊ฒ ์น ์๋ฒ๋ฅผ ๋ง๋ค ์ ์์ด.
๐ Flask ๊ธฐ๋ฐ ๋ชจ๋ํฐ๋ง ์๋ฒ
from flask import Flask, render_template, jsonify
import psutil
import json
from datetime import datetime
app = Flask(__name__)
@app.route('/')
def index():
"""๋ฉ์ธ ๋์๋ณด๋ ํ์ด์ง"""
return render_template('dashboard.html')
@app.route('/api/system-info')
def get_system_info():
"""์์คํ
์ ๋ณด API ์๋ํฌ์ธํธ"""
# CPU ์ ๋ณด
cpu_percent = psutil.cpu_percent(interval=1)
cpu_count = psutil.cpu_count()
cpu_freq = psutil.cpu_freq()
# ๋ฉ๋ชจ๋ฆฌ ์ ๋ณด
memory = psutil.virtual_memory()
swap = psutil.swap_memory()
# ๋์คํฌ ์ ๋ณด
disk = psutil.disk_usage('/')
# ๋คํธ์ํฌ ์ ๋ณด
network = psutil.net_io_counters()
# ํ๋ก์ธ์ค ์ ๋ณด (์์ 5๊ฐ)
processes = []
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
try:
processes.append(proc.info)
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
# CPU ์ฌ์ฉ๋ฅ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ
processes.sort(key=lambda x: x['cpu_percent'] or 0, reverse=True)
top_processes = processes[:5]
# JSON ์๋ต ์์ฑ
response = {
'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
'cpu': {
'percent': cpu_percent,
'count': cpu_count,
'frequency': {
'current': cpu_freq.current if cpu_freq else 0,
'min': cpu_freq.min if cpu_freq else 0,
'max': cpu_freq.max if cpu_freq else 0
}
},
'memory': {
'total': round(memory.total / (1024**3), 2),
'available': round(memory.available / (1024**3), 2),
'used': round(memory.used / (1024**3), 2),
'percent': memory.percent
},
'swap': {
'total': round(swap.total / (1024**3), 2),
'used': round(swap.used / (1024**3), 2),
'percent': swap.percent
},
'disk': {
'total': round(disk.total / (1024**3), 2),
'used': round(disk.used / (1024**3), 2),
'free': round(disk.free / (1024**3), 2),
'percent': disk.percent
},
'network': {
'bytes_sent': round(network.bytes_sent / (1024**2), 2),
'bytes_recv': round(network.bytes_recv / (1024**2), 2)
},
'top_processes': top_processes
}
return jsonify(response)
@app.route('/api/cpu-history')
def get_cpu_history():
"""CPU ์ฌ์ฉ๋ฅ ํ์คํ ๋ฆฌ (๊ฐ๋จํ ์์ )"""
# ์ค์ ๋ก๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์บ์์์ ๊ฐ์ ธ์์ผ ํจ
history = []
for i in range(60):
history.append({
'time': i,
'value': psutil.cpu_percent(interval=0.1)
})
return jsonify(history)
if __name__ == '__main__':
print("๐ ๋ชจ๋ํฐ๋ง ์๋ฒ๋ฅผ ์์ํฉ๋๋ค...")
print("๋ธ๋ผ์ฐ์ ์์ http://localhost:5000 ์ผ๋ก ์ ์ํ์ธ์!")
app.run(debug=True, host='0.0.0.0', port=5000)
๐จ HTML ๋์๋ณด๋ ํ ํ๋ฆฟ
<!-- templates/dashboard.html -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>์์คํ
๋ชจ๋ํฐ๋ง ๋์๋ณด๋</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f5f7fa; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; }
.container { max-width: 1400px; margin: 30px auto; padding: 0 20px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin-bottom: 30px; }
.card { background: white; border-radius: 12px; padding: 25px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
.card-title { font-size: 18px; font-weight: bold; margin-bottom: 15px; color: #333; }
.metric { font-size: 36px; font-weight: bold; color: #667eea; margin: 10px 0; }
.progress-bar { width: 100%; height: 20px; background: #e9ecef; border-radius: 10px; overflow: hidden; margin: 10px 0; }
.progress-fill { height: 100%; background: linear-gradient(90deg, #667eea, #764ba2); transition: width 0.3s ease; }
.process-list { list-style: none; }
.process-item { padding: 10px; border-bottom: 1px solid #e9ecef; display: flex; justify-content: space-between; }
.status-good { color: #28a745; }
.status-warning { color: #ffc107; }
.status-danger { color: #dc3545; }
</style>
</head>
<body>
<div class="header">
<h1>๐ป ์์คํ
๋ชจ๋ํฐ๋ง ๋์๋ณด๋</h1>
<p>์ค์๊ฐ ์์คํ
๋ฆฌ์์ค ๋ชจ๋ํฐ๋ง</p>
</div>
<div class="container">
<div class="grid">
<div class="card">
<div class="card-title">๐ฅ CPU ์ฌ์ฉ๋ฅ </div>
<div class="metric" id="cpu-percent">--%</div>
<div class="progress-bar">
<div class="progress-fill" id="cpu-progress" style="width: 0%"></div>
</div>
<p>์ฝ์ด ์: <span id="cpu-count">--</span>๊ฐ</p>
</div>
<div class="card">
<div class="card-title">๐พ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ </div>
<div class="metric" id="memory-percent">--%</div>
<div class="progress-bar">
<div class="progress-fill" id="memory-progress" style="width: 0%"></div>
</div>
<p><span id="memory-used">--</span> GB / <span id="memory-total">--</span> GB</p>
</div>
<div class="card">
<div class="card-title">๐ฟ ๋์คํฌ ์ฌ์ฉ๋ฅ </div>
<div class="metric" id="disk-percent">--%</div>
<div class="progress-bar">
<div class="progress-fill" id="disk-progress" style="width: 0%"></div>
</div>
<p><span id="disk-used">--</span> GB / <span id="disk-total">--</span> GB</p>
</div>
</div>
<div class="card">
<div class="card-title">๐ ์์ ํ๋ก์ธ์ค (CPU ์ฌ์ฉ๋ฅ ๊ธฐ์ค)</div>
<ul class="process-list" id="process-list">
<li class="process-item">๋ก๋ฉ ์ค...</li>
</ul>
</div>
</div>
<script>
function updateDashboard() {
fetch('/api/system-info')
.then(response => response.json())
.then(data => {
// CPU ์
๋ฐ์ดํธ
document.getElementById('cpu-percent').textContent = data.cpu.percent.toFixed(1) + '%';
document.getElementById('cpu-progress').style.width = data.cpu.percent + '%';
document.getElementById('cpu-count').textContent = data.cpu.count;
// ๋ฉ๋ชจ๋ฆฌ ์
๋ฐ์ดํธ
document.getElementById('memory-percent').textContent = data.memory.percent.toFixed(1) + '%';
document.getElementById('memory-progress').style.width = data.memory.percent + '%';
document.getElementById('memory-used').textContent = data.memory.used;
document.getElementById('memory-total').textContent = data.memory.total;
// ๋์คํฌ ์
๋ฐ์ดํธ
document.getElementById('disk-percent').textContent = data.disk.percent.toFixed(1) + '%';
document.getElementById('disk-progress').style.width = data.disk.percent + '%';
document.getElementById('disk-used').textContent = data.disk.used;
document.getElementById('disk-total').textContent = data.disk.total;
// ํ๋ก์ธ์ค ๋ชฉ๋ก ์
๋ฐ์ดํธ
const processList = document.getElementById('process-list');
processList.innerHTML = '';
data.top_processes.forEach(proc => {
const li = document.createElement('li');
li.className = 'process-item';
li.innerHTML = `
<span>${proc.name} (PID: ${proc.pid})</span>
<span>CPU: ${(proc.cpu_percent || 0).toFixed(1)}%</span>
`;
processList.appendChild(li);
});
})
.catch(error => console.error('Error:', error));
}
// ์ด๊ธฐ ๋ก๋
updateDashboard();
// 2์ด๋ง๋ค ์
๋ฐ์ดํธ
setInterval(updateDashboard, 2000);
</script>
</body>
</html>
2. ์๊ฒฉ ๋ชจ๋ํฐ๋ง: ๋คํธ์ํฌ๋ง ์ฐ๊ฒฐ๋์ด ์์ผ๋ฉด ์ด๋์๋ ํ์ธ
3. ๋ฐ์ํ ๋์์ธ: ๋ชจ๋ฐ์ผ, ํ๋ธ๋ฆฟ, ๋ฐ์คํฌํฑ ๋ชจ๋ ์ง์
4. ์ฌ์ด ๊ณต์ : URL๋ง ๊ณต์ ํ๋ฉด ์ฌ๋ฌ ์ฌ๋์ด ๋์์ ๋ชจ๋ํฐ๋ง ๊ฐ๋ฅ
๋ณด์์ด ์ค์ํ๋ค๋ฉด ์ธ์ฆ ์์คํ ์ ์ถ๊ฐํ๋ ๊ฒ๋ ์์ง ๋ง! ๐
๐ง ๊ณ ๊ธ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
๊ธฐ๋ณธ์ ์ธ ๋ชจ๋ํฐ๋ง์ ๋์ด์ ๋ ์ ๋ฌธ์ ์ธ ๊ธฐ๋ฅ๋ค์ ์ถ๊ฐํด๋ณด์!
์ค๋ฌด์์ ์ฌ์ฉํ ์ ์๋ ์์ค์ ํด์ ๋ง๋ค์ด๋ณผ ๊ฑฐ์ผ. ๐
๐ฑ ํ๋ก์ธ์ค๋ณ ์์ธ ๋ชจ๋ํฐ๋ง
import psutil
from datetime import datetime
import time
class ProcessMonitor:
def __init__(self):
"""ํ๋ก์ธ์ค ๋ชจ๋ํฐ ์ด๊ธฐํ"""
self.process_history = {}
def get_process_info(self, pid):
"""ํน์ ํ๋ก์ธ์ค์ ์์ธ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ"""
try:
process = psutil.Process(pid)
# ํ๋ก์ธ์ค ๊ธฐ๋ณธ ์ ๋ณด
info = {
'pid': pid,
'name': process.name(),
'status': process.status(),
'create_time': datetime.fromtimestamp(process.create_time()).strftime('%Y-%m-%d %H:%M:%S'),
'username': process.username(),
'cpu_percent': process.cpu_percent(interval=0.1),
'memory_info': {
'rss': round(process.memory_info().rss / (1024**2), 2), # MB
'vms': round(process.memory_info().vms / (1024**2), 2), # MB
'percent': process.memory_percent()
},
'num_threads': process.num_threads(),
'num_fds': process.num_fds() if hasattr(process, 'num_fds') else 'N/A',
'io_counters': None
}
# I/O ์นด์ดํฐ (์ง์๋๋ ๊ฒฝ์ฐ)
try:
io = process.io_counters()
info['io_counters'] = {
'read_bytes': round(io.read_bytes / (1024**2), 2), # MB
'write_bytes': round(io.write_bytes / (1024**2), 2) # MB
}
except (psutil.AccessDenied, AttributeError):
pass
# ์ฐ๊ฒฐ ์ ๋ณด
try:
connections = process.connections()
info['connections'] = len(connections)
except (psutil.AccessDenied, psutil.NoSuchProcess):
info['connections'] = 'N/A'
return info
except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
return {'error': str(e)}
def get_all_processes(self, sort_by='cpu'):
"""๋ชจ๋ ํ๋ก์ธ์ค ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ"""
processes = []
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent', 'status']):
try:
info = proc.info
info['cpu_percent'] = proc.cpu_percent(interval=0.1)
processes.append(info)
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
# ์ ๋ ฌ
if sort_by == 'cpu':
processes.sort(key=lambda x: x['cpu_percent'] or 0, reverse=True)
elif sort_by == 'memory':
processes.sort(key=lambda x: x['memory_percent'] or 0, reverse=True)
return processes
def monitor_process(self, pid, duration=60, interval=1):
"""ํน์ ํ๋ก์ธ์ค๋ฅผ ์ผ์ ์๊ฐ ๋์ ๋ชจ๋ํฐ๋ง"""
print(f"๐ ํ๋ก์ธ์ค {pid} ๋ชจ๋ํฐ๋ง ์์")
print(f"๊ธฐ๊ฐ: {duration}์ด, ๊ฐ๊ฒฉ: {interval}์ด\n")
start_time = time.time()
samples = []
try:
while (time.time() - start_time) < duration:
info = self.get_process_info(pid)
if 'error' in info:
print(f"โ ์ค๋ฅ: {info['error']}")
break
samples.append({
'timestamp': datetime.now().strftime('%H:%M:%S'),
'cpu': info['cpu_percent'],
'memory': info['memory_info']['percent']
})
print(f"[{samples[-1]['timestamp']}] "
f"CPU: {info['cpu_percent']:.1f}% | "
f"Memory: {info['memory_info']['percent']:.1f}% | "
f"Threads: {info['num_threads']}")
time.sleep(interval)
except KeyboardInterrupt:
print("\n๋ชจ๋ํฐ๋ง์ ์ค๋จํฉ๋๋ค.")
# ํต๊ณ ์ถ๋ ฅ
if samples:
print("\n" + "="*60)
print("๐ ๋ชจ๋ํฐ๋ง ๊ฒฐ๊ณผ ์์ฝ")
print("="*60)
cpu_values = [s['cpu'] for s in samples]
memory_values = [s['memory'] for s in samples]
print(f"CPU ์ฌ์ฉ๋ฅ :")
print(f" ํ๊ท : {sum(cpu_values)/len(cpu_values):.2f}%")
print(f" ์ต๋: {max(cpu_values):.2f}%")
print(f" ์ต์: {min(cpu_values):.2f}%")
print(f"\n๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ :")
print(f" ํ๊ท : {sum(memory_values)/len(memory_values):.2f}%")
print(f" ์ต๋: {max(memory_values):.2f}%")
print(f" ์ต์: {min(memory_values):.2f}%")
def find_memory_hogs(self, top_n=10):
"""๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ํ๋ก์ธ์ค ์ฐพ๊ธฐ"""
processes = self.get_all_processes(sort_by='memory')
print("\n" + "="*60)
print(f"๐พ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์์ {top_n}๊ฐ ํ๋ก์ธ์ค")
print("="*60)
for i, proc in enumerate(processes[:top_n], 1):
print(f"{i}. {proc['name']} (PID: {proc['pid']})")
print(f" ๋ฉ๋ชจ๋ฆฌ: {proc['memory_percent']:.2f}%")
print()
def find_cpu_hogs(self, top_n=10):
"""CPU๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ํ๋ก์ธ์ค ์ฐพ๊ธฐ"""
processes = self.get_all_processes(sort_by='cpu')
print("\n" + "="*60)
print(f"๐ฅ CPU ์ฌ์ฉ๋ ์์ {top_n}๊ฐ ํ๋ก์ธ์ค")
print("="*60)
for i, proc in enumerate(processes[:top_n], 1):
print(f"{i}. {proc['name']} (PID: {proc['pid']})")
print(f" CPU: {proc['cpu_percent']:.2f}%")
print()
# ์ฌ์ฉ ์์
if __name__ == "__main__":
monitor = ProcessMonitor()
# CPU ์ฌ์ฉ๋ ์์ ํ๋ก์ธ์ค
monitor.find_cpu_hogs(top_n=5)
# ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์์ ํ๋ก์ธ์ค
monitor.find_memory_hogs(top_n=5)
# ํน์ ํ๋ก์ธ์ค ๋ชจ๋ํฐ๋ง (์: PID 1234)
# monitor.monitor_process(1234, duration=30, interval=2)
๐ก๏ธ ์จ๋ ๋ชจ๋ํฐ๋ง (ํ๋์จ์ด ์ผ์)
import psutil
def monitor_temperatures():
"""์์คํ
์จ๋ ๋ชจ๋ํฐ๋ง"""
# ์จ๋ ์ผ์๊ฐ ์ง์๋๋์ง ํ์ธ
if not hasattr(psutil, "sensors_temperatures"):
print("โ ์ด ์์คํ
์ ์จ๋ ์ผ์๋ฅผ ์ง์ํ์ง ์์ต๋๋ค.")
return
temps = psutil.sensors_temperatures()
if not temps:
print("โ ์จ๋ ์ผ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.")
return
print("\n" + "="*60)
print("๐ก๏ธ ์์คํ
์จ๋ ์ ๋ณด")
print("="*60 + "\n")
for name, entries in temps.items():
print(f"๐ {name}:")
for entry in entries:
status = ""
if entry.current > 80:
status = " โ ๏ธ ๊ฒฝ๊ณ : ๋์ ์จ๋!"
elif entry.current > 70:
status = " โก ์ฃผ์"
print(f" {entry.label or 'N/A'}: {entry.current}ยฐC{status}")
if entry.high:
print(f" ์ต๋ ์์ ์จ๋: {entry.high}ยฐC")
if entry.critical:
print(f" ์๊ณ ์จ๋: {entry.critical}ยฐC")
print()
def monitor_fans():
"""ํฌ ์๋ ๋ชจ๋ํฐ๋ง"""
if not hasattr(psutil, "sensors_fans"):
print("โ ์ด ์์คํ
์ ํฌ ์ผ์๋ฅผ ์ง์ํ์ง ์์ต๋๋ค.")
return
fans = psutil.sensors_fans()
if not fans:
print("โ ํฌ ์ผ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.")
return
print("\n" + "="*60)
print("๐ ํฌ ์๋ ์ ๋ณด")
print("="*60 + "\n")
for name, entries in fans.items():
print(f"๐ {name}:")
for entry in entries:
print(f" {entry.label or 'N/A'}: {entry.current} RPM")
print()
def monitor_battery():
"""๋ฐฐํฐ๋ฆฌ ์ํ ๋ชจ๋ํฐ๋ง (๋
ธํธ๋ถ)"""
if not hasattr(psutil, "sensors_battery"):
print("โ ๋ฐฐํฐ๋ฆฌ ์ ๋ณด๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.")
return
battery = psutil.sensors_battery()
if battery is None:
print("โ ๋ฐฐํฐ๋ฆฌ๊ฐ ๊ฐ์ง๋์ง ์์์ต๋๋ค. (๋ฐ์คํฌํฑ?)")
return
print("\n" + "="*60)
print("๐ ๋ฐฐํฐ๋ฆฌ ์ ๋ณด")
print("="*60 + "\n")
print(f"๋ฐฐํฐ๋ฆฌ ์๋: {battery.percent}%")
print(f"์ ์ ์ฐ๊ฒฐ: {'์' if battery.power_plugged else '์๋์ค'}")
if battery.secsleft != psutil.POWER_TIME_UNLIMITED:
hours = battery.secsleft // 3600
minutes = (battery.secsleft % 3600) // 60
print(f"๋จ์ ์๊ฐ: {hours}์๊ฐ {minutes}๋ถ")
else:
print("๋จ์ ์๊ฐ: ์ถฉ์ ์ค")
print()
# ์ฌ์ฉ ์์
if __name__ == "__main__":
monitor_temperatures()
monitor_fans()
monitor_battery()
ํนํ ๊ฐ์ ๋จธ์ ์ด๋ ์ผ๋ถ ๋ ธํธ๋ถ์์๋ ์ ๊ทผ์ด ์ ํ๋ ์ ์์ด.
Linux์์๋ lm-sensors ํจํค์ง๊ฐ ์ค์น๋์ด ์์ด์ผ ํ๊ณ ,
Windows์์๋ ๊ด๋ฆฌ์ ๊ถํ์ด ํ์ํ ์ ์์ด. ๐ง
๐ ์ค์ ํ์ฉ ํ๊ณผ ๋ฒ ์คํธ ํ๋ํฐ์ค
์ด์ ์ค์ ๋ก ๋ชจ๋ํฐ๋ง ํด์ ์ด์ํ ๋ ์์๋๋ฉด ์ข์ ํ๋ค์ ๊ณต์ ํ ๊ฒ!
๊ฒฝํ์์ ์ฐ๋ฌ๋์จ ๋
ธํ์ฐ๋ค์ด์ผ. ๐
๐ก 1. ์ ์ ํ ์ํ๋ง ๊ฐ๊ฒฉ ์ค์
๋๋ฌด ์งง์ ๊ฐ๊ฒฉ์ผ๋ก ๋ชจ๋ํฐ๋งํ๋ฉด ์คํ๋ ค ์์คํ
์ ๋ถํ๋ฅผ ์ค ์ ์์ด.
๊ถ์ฅ ๊ฐ๊ฒฉ:
โข ์ค์๊ฐ ๋์๋ณด๋: 1-2์ด
โข ๋ก๊น
: 30-60์ด
โข ์ฅ๊ธฐ ํธ๋ ๋ ๋ถ์: 5-10๋ถ
์ํฉ์ ๋ง๊ฒ ์กฐ์ ํ๋ ๊ฒ ์ค์ํด! โฑ๏ธ
๐ก 2. ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
์ฅ์๊ฐ ์คํ๋๋ ๋ชจ๋ํฐ๋ง ํด์ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์ฃผ์ํด์ผ ํด.
์ฒดํฌ๋ฆฌ์คํธ:
โข ๋ฐ์ดํฐ ๋ฒํผ ํฌ๊ธฐ ์ ํ (deque์ maxlen ํ์ฉ)
โข ์ฃผ๊ธฐ์ ์ธ ๊ฐ๋น์ง ์ปฌ๋ ์
โข ์ค๋๋ ๋ก๊ทธ ํ์ผ ์๋ ์ญ์
โข ํ๋ก์ธ์ค ์ฌ์์ ์ค์ผ์ค๋ง
์์ ์ ์ธ ์ด์์ ์ํด ํ์์ผ! ๐ก๏ธ
๐ก 3. ์๋ฌ ์ฒ๋ฆฌ
์์คํ
๋ชจ๋ํฐ๋ง์ ์์ธ ์ํฉ์ด ๋ง์ด ๋ฐ์ํ ์ ์์ด.
์ฃผ์ ์์ธ:
โข psutil.NoSuchProcess: ํ๋ก์ธ์ค๊ฐ ๊ฐ์๊ธฐ ์ข
๋ฃ๋จ
โข psutil.AccessDenied: ๊ถํ ๋ถ์กฑ
โข psutil.TimeoutExpired: ์๋ต ์๊ฐ ์ด๊ณผ
๋ชจ๋ ์์ธ๋ฅผ ์ ์ ํ ์ฒ๋ฆฌํด์ ํ๋ก๊ทธ๋จ์ด ์ค๋จ๋์ง ์๊ฒ ํด์ผ ํด! ๐จ
๐ก 4. ์ฑ๋ฅ ์ต์ ํ
๋ชจ๋ํฐ๋ง ํด ์์ฒด๊ฐ ์์คํ
๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ฉด ์ ๋๊ฒ ์ง?
์ต์ ํ ํ:
โข ํ์ํ ์ ๋ณด๋ง ์์ง (interval ํ๋ผ๋ฏธํฐ ํ์ฉ)
โข ๋ฉํฐ์ค๋ ๋ฉ๋ณด๋ค๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ณ ๋ ค
โข ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ ์ต์ ํ
โข ์บ์ฑ ์ ๋ต ์๋ฆฝ
๊ฐ๋ณ๊ณ ํจ์จ์ ์ธ ํด์ด ์ต๊ณ ์ผ! โก
๐ก 5. ๋ณด์ ๊ณ ๋ ค์ฌํญ
์์คํ
์ ๋ณด๋ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ์ผ. ๋ณด์์ ์ ๊ฒฝ ์จ์ผ ํด!
๋ณด์ ์ฒดํฌ๋ฆฌ์คํธ:
โข ์น ๋์๋ณด๋์ ์ธ์ฆ ์ถ๊ฐ
โข HTTPS ์ฌ์ฉ
โข ๋ก๊ทธ ํ์ผ ๊ถํ ์ค์
โข API ์๋ํฌ์ธํธ ์ ๊ทผ ์ ์ด
โข ๋ฏผ๊ฐํ ์ ๋ณด ๋ง์คํน
๋ณด์์ ์ ํ์ด ์๋๋ผ ํ์์ผ! ๐
๐ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์! ์ฌ๊ธฐ๊น์ง ์ฝ์๋ค๋ฉด ์ ๋ง ๋๋จํด! ๐
์ฐ๋ฆฌ๋ ์์คํ
๋ชจ๋ํฐ๋ง ํด์ ๋ง๋๋ ์ฌ์ ์ ํจ๊ป ํ์ด.
๊ธฐ๋ณธ์ ์ธ CPU, ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ํฐ๋ง๋ถํฐ ์์ํด์
GUI ์ธํฐํ์ด์ค, ์น ๋์๋ณด๋, ์๋ฆผ ์์คํ
, ๋ฐ์ดํฐ ๋ถ์๊น์ง ๋ค๋ค์ง.
์ด์ ๋๋ง์ ๋ชจ๋ํฐ๋ง ํด์ ๋ง๋ค ์ ์์ ๊ฑฐ์ผ! ๐
1. ๊ธฐ๋ฅ ํ์ฅ: ๋คํธ์ํฌ ๋ชจ๋ํฐ๋ง, ๋์คํฌ I/O ์ถ์ ๋ฑ ์ถ๊ฐ
2. ์๋ฆผ ๊ณ ๋ํ: ์ด๋ฉ์ผ, Slack, Discord ์ฐ๋
3. ๋จธ์ ๋ฌ๋ ์ ์ฉ: ์ด์ ํ์ง, ์์ธก ๋ถ์
4. ํด๋ผ์ฐ๋ ์ฐ๋: AWS CloudWatch, Azure Monitor ํตํฉ
5. ์ปจํ ์ด๋ ๋ชจ๋ํฐ๋ง: Docker, Kubernetes ์ง์
๊ฐ๋ฅ์ฑ์ ๋ฌด๊ถ๋ฌด์งํด! ๐ซ
์ค๋ฌด ๊ฒฝํ์ด ํ๋ถํ ๊ฐ๋ฐ์๋ค์ด ๋์ ์ฝ๋๋ฅผ ํ ๋จ๊ณ ์ ๊ทธ๋ ์ด๋์์ผ์ค ์ ์์ด.
ํผ์ ๊ณ ๋ฏผํ์ง ๋ง๊ณ ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ์๋ณด๋ ๊ฒ๋ ํ๋ช ํ ์ ํ์ด์ง! ๐ค
์์คํ
๋ชจ๋ํฐ๋ง์ ๋จ์ํ ์ซ์๋ฅผ ๋ณด๋ ๊ฒ ์๋์ผ.
์์คํ
์ ๊ฑด๊ฐ ์ํ๋ฅผ ํ์
ํ๊ณ , ๋ฌธ์ ๋ฅผ ์๋ฐฉํ๋ฉฐ,
์ต์ ์ ์ฑ๋ฅ์ ์ ์งํ๊ธฐ ์ํ ํ์ ๋๊ตฌ์ง.
์ค๋ ๋ฐฐ์ด ๋ด์ฉ์ ๋ฐํ์ผ๋ก ๋ฉ์ง ๋ชจ๋ํฐ๋ง ํด์ ๋ง๋ค์ด๋ด!
๊ทธ๋ฆฌ๊ณ ๊ณ์ ๋ฐ์ ์์ผ ๋๊ฐ๋ฉด์ ๋ ๋ง์ ๊ฒ์ ๋ฐฐ์ฐ๊ฒ ๋ ๊ฑฐ์ผ. ๐
์ฝ๋ฉ์ ๊ฒฐ๊ตญ ์ค์ ์ด์ผ. ์ง์ ๋ง๋ค์ด๋ณด๊ณ , ์คํจํ๊ณ , ๊ฐ์ ํ๋ฉด์
์ง์ง ์ค๋ ฅ์ด ๋์ด๋๋ ๊ฑฐ๋๊น ๋ง์ด์ผ! ๐ช
ํ์ด์ ๋น์ด! ํ์ดํ
! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.