← 목록

운영 서버 Port 모니터링 및 다중 알람 서비스 구축

2분 간격으로 운영 서버 포트 상태를 확인하고 이상 감지 시 SMS/Email/전화 알람을 자동 발송하는 야간 모니터링 시스템 구축

2024-07-15AWSMonitoringPythonAutomation

개요

기존 모니터링 앱에 SMS / Email / 전화 알람 서비스를 추가하고 AWS에 배포했다.

운영 서버에 대한 야간 모니터링을 통해 긴급 상황 발생 시 담당자에게 즉시 알림을 전달하는 것이 목적이다.


동작 방식

2분마다 대상 서버 포트 확인
    ↓
응답 코드 200 아닌 경우
또는 5초 이상 응답 없음
또는 5초 이상 연결 실패
    ↓
SMS / Email / 전화 알람 발송

알람 트리거 조건

조건설명
HTTP 응답 코드 != 200서버 오류 응답
응답 시간 > 5초서버 과부하 또는 지연
연결 실패 (5초 이상)서버 다운 또는 네트워크 단절

수행 주기


모니터링 대상

설정 파일을 통해 대상을 유동적으로 추가/삭제할 수 있다.

# monitoring_targets.yaml
targets:
  - name: "[SERVICE-A] AP1"
    url: "http://[internal-ip-1]:[port-1]"
  - name: "[SERVICE-A] AP2"
    url: "http://[internal-ip-2]:[port-1]"
  - name: "[SERVICE-B] AP1"
    url: "http://[internal-ip-1]:[port-2]"
  - name: "[SERVICE-B] AP2"
    url: "http://[internal-ip-2]:[port-2]"
  - name: "[SERVICE-B] AP1 Health"
    url: "http://[internal-ip-1]:[port-3]/hello"
  - name: "[SERVICE-B] AP2 Health"
    url: "http://[internal-ip-2]:[port-3]/hello"

알람 수단

SMS, Email, 전화 중 다중 선택 가능하며, 수신 대상은 설정 파일로 유동적으로 관리한다.

SMS

def send_sms(recipients: list, message: str):
    sns = boto3.client('sns')
    for phone in recipients:
        sns.publish(
            PhoneNumber=phone,
            Message=message,
        )
 
# 사용 예시
send_sms(
    recipients=['[phone-1]', '[phone-2]', '[phone-3]'],
    message="운영 서버 포트 접속 에러입니다. 대응 부탁드립니다."
)

Email (SES)

def send_email(subject: str, body: str):
    ses = boto3.client('ses')
    ses.send_email(
        Source='[sender-email]',
        Destination={'ToAddresses': ['[team-email]']},
        Message={
            'Subject': {'Data': subject},
            'Body': {'Text': {'Data': body}}
        }
    )
 
# 사용 예시
send_email(
    subject='[긴급][운영 APP] Connection Timeout',
    body='운영 서버 포트 접속 에러입니다.'
)

전화 (Amazon Connect / Twilio)

def make_call(recipients: list, message: str):
    # 순차적으로 전화 발신
    for phone in recipients:
        client.calls.create(
            to=phone,
            from_='[caller-number]',
            tts_message=message
        )
 
# 순차 발신: 담당자1 → 담당자2 → 담당자3 → ...

포트 확인 핵심 로직

import requests
import time
 
TIMEOUT = 5  # 5초
 
def check_port(name: str, url: str) -> dict:
    try:
        start = time.time()
        response = requests.get(url, timeout=TIMEOUT)
        elapsed = time.time() - start
 
        if response.status_code != 200:
            return {
                'name': name,
                'status': 'ERROR',
                'reason': f'HTTP {response.status_code}',
                'elapsed': elapsed
            }
 
        if elapsed > TIMEOUT:
            return {
                'name': name,
                'status': 'SLOW',
                'reason': f'응답 지연 {elapsed:.1f}초',
                'elapsed': elapsed
            }
 
        return {'name': name, 'status': 'OK', 'elapsed': elapsed}
 
    except requests.exceptions.ConnectTimeout:
        return {'name': name, 'status': 'TIMEOUT', 'reason': '연결 시간 초과'}
    except requests.exceptions.ConnectionError:
        return {'name': name, 'status': 'DOWN', 'reason': '연결 실패'}

설정 파일 기반 수신자 관리

알람 수신 대상을 코드 변경 없이 설정 파일로 관리한다.

# alarm_config.yaml
sms:
  enabled: true
  recipients:
    - "[phone-1]"
    - "[phone-2]"
    - "[phone-3]"
 
email:
  enabled: true
  from: "[sender-email]"
  to:
    - "[team-email]"
 
call:
  enabled: true
  recipients:
    - "[phone-1]"  # 1순위
    - "[phone-2]"  # 2순위
    - "[phone-3]"  # 3순위

배포 구성

Docker Container (Port Monitor)
    ├── 2분 간격 배치 실행
    ├── monitoring_logs.json 기록
    └── 이상 감지 시 알람 발송
        ├── AWS SNS (SMS)
        ├── AWS SES (Email)
        └── 전화 발신 서비스

운영 서버 내 Docker 컨테이너로 배포하여 별도 인프라 없이 운영한다.

로그 확인

# 특정 환경 모니터링 로그 확인
docker exec -it [container-id] grep -c "[SERVICE-NAME] Prod" monitoring_logs.json

설계 포인트

설정 파일 기반 유연성 수신자 목록, 모니터링 대상, 알람 수단을 모두 설정 파일로 관리해 코드 변경 없이 운영 중 수정 가능하다.

다중 알람 채널 SMS, Email, 전화를 독립적으로 활성화/비활성화할 수 있어 상황에 맞는 알람 전략을 유연하게 구성할 수 있다.

순차 전화 발신 전화 알람은 담당자 우선순위에 따라 순차적으로 발신해 책임자가 반드시 인지하도록 설계했다.


정리


배운 점

이 시스템을 만들고 나서 알게 된 건 감지보다 전달이 어렵다는 점이다. 포트가 죽었는지 확인하는 코드는 몇 줄이면 끝난다. 정작 오래 고민한 부분은 "이 알림을 새벽 세 시에 누구 휴대폰으로 울리게 할 것인가"였다. 모니터링은 기술 문제로 시작해서 운영 정책 문제로 끝난다.

설정 파일로 대상과 수신자를 빼둔 선택은 시간이 지날수록 값을 했다. 담당자가 바뀌거나 서버가 늘어날 때마다 코드를 고치고 다시 배포했다면 이 시스템은 오래 못 갔을 것이다. 운영 도구에서 바뀌는 건 로직이 아니라 대상이다.

다만 이때는 감지 조건이 단순했다. 응답이 없으면 알린다, 그뿐이었다. 뒤에 CloudWatch 알람 기반 EC2/ECS 통합 모니터링 구축에서 심각도를 나누게 되는데, 그 필요를 느끼게 된 계기가 바로 이 단계에서 쌓인 알림 피로였다.


이어 읽기