Profile picture

[Python] 서버 상태 리포트 받기

JaehyoJJAng2024년 12월 10일

개요

서버를 운영하다 보면 '내 서버가 지금 잘 돌아가고 있나' 하는 궁금증과 불안감이 몰려옵니다.

중요한 순간에 서버가 멈추기라도 하면 끝이겠죠?

매번 터미널에 접속해서 top, df, free 같은 명령어를 입력하는 것도 일이구요!


그 외에 쉘 스크립트를 작성하는 방법도 있겠네요!


하지만 오늘은 파이썬을 사용해서 위의 목적을 쉽게 달성해보려고 합니다!

psutil 이라는 라이브러리를 사용하면 정말 편리하게 서버의 리소스를 가져올 수 있거든요!


왜 파이썬이죠?

위에서 언급했듯이 쉘 스크립트를 사용해서 모니터링하는게 더 낫지 않을까 생각하실 수도 있습니다.


하지만 파이썬은! 다음과 같은 특징을 가지고 있죠.

  • 쉬운 코드, 높은 가독성: 문법이 직관적이라 나중에 코드를 다시 보거나 수정하기가 훨씬 수월합니다.
  • 강력한 라이브러리: psutil, requests처럼 강력한 도구(라이브러리) 덕분에 복잡한 시스템 정보도 몇 줄의 코드로 간단하게 가져올 수 있습니다.
  • 자유로운 확장성: "CPU 사용량이 80%를 넘으면 경고 메시지 색깔을 바꿔줘" 와 같은 복잡한 조건이나, "특정 서비스가 죽으면 자동으로 재시작해줘" 같은 기능 추가도 자유롭습니다.

솔직히 쉘 스크립트로 작성하면 awkgrep 등으로 복잡한 정규표현식을 활용해 원하는 리소스를 필터링해서 가져와야 합니다.

해보신 분은 아실거에요!


🛠️ 1단계: 파이썬 환경 준비하기

가장 먼저 스크립트에 필요한 라이브러리 두 개를 설치해줍시다.

pip install psutil requests
  • psutil: 시스템의 CPU, 메모리, 디스크 등 하드웨어 정보를 손쉽게 가져오는 라이브러리입니다.
  • requests: 디스코드 웹훅(Webhook)으로 HTTP 요청을 보내 메시지를 전송할 때 사용합니다.

✍️ 2단계: 서버 모니터링 파이썬 스크립트 작성하기

이제 핵심인 파이썬 코드를 작성할 차례입니다.

server_monitor.py와 같은 이름으로 파일을 만들고 아래 코드를 붙여넣어 보세요.

코드 한 줄 한 줄에 어떤 의미가 담겨있는지 주석으로 상세히 설명해 두었습니다.

#!/usr/bin/env python3
import psutil       # 시스템 정보용 라이브러리
import requests     # HTTP 요청용 라이브러리
import socket       # 서버 호스트 이름 확인용
import os

# --------------------------------------------------
# 👇 여기에 자신의 디스코드 웹훅 URL을 넣어주세요!
# --------------------------------------------------
WEBHOOK_URL = "https://discord.com/api/webhooks/xxxxxxxx/yyyyyyyyyyyy"


def get_system_stats():
    """
    서버의 핵심 자원(CPU, 메모리, 디스크) 사용률을 튜플 형태로 반환합니다.
    """
    # 1초간의 평균 CPU 사용률을 가져옵니다.
    cpu_usage = psutil.cpu_percent(interval=1)
    
    # 가상 메모리(RAM) 정보를 가져옵니다.
    memory_info = psutil.virtual_memory()
    memory_percent = memory_info.percent
    
    # 루트('/') 경로의 디스크 사용량 정보를 가져옵니다.
    disk_info = psutil.disk_usage('/')
    disk_percent = disk_info.percent
    
    return cpu_usage, memory_percent, disk_percent


def send_discord_message(cpu, memory, disk):
    """
    측정한 시스템 정보를 포맷에 맞춰 디스코드로 전송합니다.
    """
    # 메시지에 서버 호스트 이름을 포함시켜 어느 서버의 알림인지 쉽게 파악합니다.
    hostname = socket.gethostname()
    
    # 기본 메시지 색상은 초록색으로 설정합니다.
    message_color = 0x00ff00 

    # 메모리나 디스크 사용량이 80%를 넘으면 주황색(경고), 90%를 넘으면 빨간색(위험)으로 변경
    if memory > 90 or disk > 90:
        message_color = 0xff0000  # 빨간색
    elif memory > 80 or disk > 80:
        message_color = 0xffa500  # 주황색

    # 디스코드 '임베드(Embed)' 형식을 사용해 깔끔한 메시지를 구성합니다.
    embed = {
        "title": f"🖥️ {hostname} 서버 일일 리포트",
        "description": "오늘의 서버 상태 요약입니다.",
        "color": message_color,
        "fields": [
            {"name": "✅ CPU 사용률", "value": f"`{cpu:.2f}%`", "inline": True},
            {"name": "✅ 메모리 사용률", "value": f"`{memory}%`", "inline": True},
            {"name": "✅ 디스크 사용률 ('/')", "value": f"`{disk}%`", "inline": True},
        ]
    }
    
    # 전송할 최종 데이터 (봇 이름, 임베드 메시지)
    data = {
        "username": "나만의 서버 비서",
        "embeds": [embed]
    }
    
    try:
        # requests.post를 사용해 웹훅 URL로 JSON 데이터를 전송합니다.
        response = requests.post(WEBHOOK_URL, json=data)
        
        # HTTP 응답 코드가 2xx가 아니면 예외를 발생시켜 에러를 탐지합니다.
        response.raise_for_status()
        print("✅ 디스코드로 메시지를 성공적으로 전송했습니다.")
    except requests.exceptions.RequestException as e:
        print(f"❌ 메시지 전송에 실패했습니다: {e}")


# 이 스크립트가 직접 실행될 때만 아래 코드를 실행
if __name__ == "__main__":
    print("서버 상태 점검을 시작합니다...")
    cpu_percent, memory_percent, disk_percent = get_system_stats()
    send_discord_message(cpu_percent, memory_percent, disk_percent)

마무리

위 스크립트의 진가는 '자동화'에 있습니다!

cron을 활용하거나 systemd에 위 스크립트를 서비스로 등록도 해보세요!

    Tag -

Loading script...