알림 피로는 실재합니다: 현명한 개발자는 이렇게 해결합니다

모든 알림이 똑같이 긴급해 보이면 그 무엇도 긴급하게 느껴지지 않습니다. 단계별 알림으로 모니터링 구성을 개선하는 방법과 Echobell과 잘 맞는 도구를 소개합니다.

목차

여기에는 이름이 있습니다. 바로 알림 피로입니다. 모니터링 도구가 너무 많은 알림을 보내는 나머지, 정말 중요한 알림까지 뇌가 자동으로 걸러 내기 시작하는 현상을 가리킵니다.

시작은 대개 사소합니다. 5xx 오류마다 이메일 알림을 설정합니다. 그다음에는 빌드가 실패할 때마다 Slack 알림을 켭니다. 이어서 Datadog 핑, Sentry 이메일, UptimeRobot 문자까지 더해집니다. 한 달이 지나면 휴대폰이 하루에 50번씩 울리지만 그중 무엇도 긴급하게 느껴지지 않습니다. 진짜 문제는 따로 있습니다. 정말로 무언가 망가졌을 때, 이미 그것을 무시하도록 스스로를 훈련시켜 놓았다는 점입니다.

알림 피로는 대응 시간을 무너뜨립니다. 그리고 느린 대응 시간은 제품을 무너뜨립니다.

대부분의 모니터링 구성이 신호보다 소음을 만들어 내는 이유

근본적인 문제는 대부분의 알림 도구가 모든 이벤트를 똑같이 취급한다는 데 있습니다. 10% 확률로 실패하는 불안정한 테스트가 "결제 API가 모든 사용자에게 500을 반환하고 있다"와 똑같은 알림 형식으로 전달됩니다. 둘 중 하나는 새벽 2시에 전화를 받아야 하는 일입니다. 다른 하나는 주간 요약 리포트에 실리는 편이 낫습니다.

모든 것이 똑같이 취급되면 사람은 모든 것을 무시하기 시작합니다.

해법은 알림을 줄이는 것이 아니라 더 똑똑하게 전달하는 것입니다. 같은 이벤트라도 심각도가 다르거나 발생 빈도가 다르면 휴대폰에서도 서로 다른 긴급도로 나타나야 합니다.

3단계 접근법

Echobell은 세 가지 전달 방식을 제공하며, 이 세 가지를 모두 잘 활용하는 것이 핵심입니다:

  • 일반(Active): 표준 푸시 알림입니다. 즉각적인 조치가 필요 없는 정보성 이벤트에 적합합니다.
  • 긴급(Time-Sensitive): iOS 집중 모드를 뚫고 전달됩니다. 한두 시간 안에 확인해야 하는 일에 적합합니다.
  • 전화(Calling): 걸려 온 전화처럼 휴대폰을 울립니다. "지금 당장 해결하지 않으면 실제 피해가 생긴다"에 해당하는 경우에만 사용하세요.

목표는 대응이 늦어질 때 실제 결과가 뒤따르는 이벤트, 즉 매출 손실이나 연쇄 장애, 사용자 데이터 위험 같은 상황을 위해 전화 단계를 아껴 두는 것입니다. 그 밖의 모든 것은 긴급 이하로 내립니다.

Sentry: Python 예외 하나하나에 호출당하지 않기

Sentry는 알림 피로의 대표적인 사례입니다. 기본 설정에서는 새로운 이슈 유형이 생길 때마다 이메일을 보냅니다. 활발히 개발 중인 코드베이스라면 평범한 한 주에도 소방 호스처럼 알림이 쏟아집니다.

더 현명한 구성은 다음과 같습니다:

  1. Sentry에서 Alerts → Create Alert → Issue Alert로 이동합니다
  2. 조건을 추가합니다: The issue is seen more than 10 times in 1 hour
  3. 액션을 추가합니다: Send a notification via webhook → Echobell 채널 URL을 붙여 넣습니다
  4. 채널의 알림 유형을 time-sensitive로 설정합니다

결제 흐름의 처리되지 않은 예외, 인증 실패, 데이터 손상처럼 정말로 치명적인 경로에는 임계값을 더 낮춘 별도의 알림과 calling 단계의 Echobell 채널을 따로 만드세요. 그 채널은 해당 경로에서 문제가 생겼을 때만 울립니다.

그 결과 일상적인 이슈는 Sentry 대시보드에 조용히 쌓이고, 프로덕션을 망가뜨리는 문제만 휴대폰을 울립니다.

Prometheus와 AlertManager: 심각도로 라우팅하기

Prometheus를 운영 중이라면 이미 AlertManager가 라우팅을 맡고 있습니다. AlertManager에 Echobell을 Webhook 수신자로 추가하면 알림을 곧바로 보낼 수 있습니다.

alertmanager.yml에 다음과 같이 작성합니다:

receivers:
  - name: echobell-critical
    webhook_configs:
      - url: https://hook.echobell.one/t/<channel-token>
        send_resolved: true

  - name: slack-warnings
    slack_configs:
      - api_url: YOUR_SLACK_WEBHOOK

route:
  group_by: ['alertname', 'job']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: slack-warnings
  routes:
    - match:
        severity: critical
      receiver: echobell-critical

이렇게 구성하면 severity: critical 알림은 Echobell로 전달되어 휴대폰을 울리고, 경고는 Slack으로 가서 아침까지 기다립니다. Prometheus 규칙은 하나도 바꿀 필요가 없습니다. AlertManager에 라우팅 계층만 추가하면 됩니다.

Echobell 채널 자체는 전화(Calling) 유형으로 설정하세요. AlertManager가 critical로 분류했다면 실제로 벨이 울릴 만한 일입니다.

AWS CloudWatch: SNS → Lambda → Echobell

CloudWatch에는 기본 Webhook 출력이 없지만, SNS와 작은 Lambda 함수를 이용하면 몇 분 만에 해결할 수 있습니다.

  1. SNS 토픽을 만들고 CloudWatch 경보에 연결합니다
  2. 해당 토픽을 구독하는 Lambda 함수를 만듭니다:
import json
import urllib.request

def lambda_handler(event, context):
    message = json.loads(event['Records'][0]['Sns']['Message'])
    alarm_state = message.get('NewStateValue', 'UNKNOWN')

    payload = {
        "title": f"AWS: {message['AlarmName']}",
        "body": message.get('NewStateReason', 'No details'),
        "notificationType": "calling" if alarm_state == "ALARM" else "active"
    }

    req = urllib.request.Request(
        'https://hook.echobell.one/t/<channel-token>',
        data=json.dumps(payload).encode(),
        headers={'Content-Type': 'application/json'},
        method='POST'
    )
    urllib.request.urlopen(req)

이 패턴은 SNS를 지원하는 모든 AWS 서비스에 적용됩니다. RDS 이벤트, ECS 서비스 장애, 청구 임계값 알림, EC2 인스턴스 상태 변경이 모두 여기에 해당합니다. Lambda 하나를 추가해 SNS에 연결해 두면, 모든 CloudWatch 경보가 실제로 발생하는 순간 전화로 바뀝니다.

알림 라우팅을 팀의 결정으로 만들기

단계별 알림의 진짜 힘은 라우팅 결정을 명시적으로 드러내는 데 있습니다. 한 사람이 예전에 설정해 두고 아무도 찾지 못하는 무언가로 남겨 두어서는 안 됩니다.

소규모 엔지니어링 팀에 적합한 실용적인 구조는 다음과 같습니다:

채널유형구독 대상
production-api-critical전화온콜 엔지니어
production-api-warnings긴급개발팀 전체
staging-all일반개발팀(선택)
background-jobs일반관심 있는 사람 누구나

온콜 순번이 바뀌면 당번에서 빠지는 사람이 치명적 채널의 구독을 해제하고, 새로 들어오는 사람이 구독합니다. 순번 인수인계는 이것이 전부입니다. 설정 파일도, 관리자 페이지도 필요 없습니다.

Echobell 채널은 링크로 공유할 수 있으므로, 새 팀원이 구독하는 데 10초 정도면 충분합니다.

신호 대 소음 테스트

새 알림을 추가하기 전에 한 가지만 자문해 보세요. 금요일 새벽 3시에 이 알림이 울린다면, 나는 실제로 무엇을 할 것인가?

  • "일어나서 지금 바로 고친다" → 전화
  • "아침에 출근하자마자 처리한다" → 긴급 또는 일반
  • "아마 아무것도 하지 않고 다시 잠든다" → 그 알림이 애초에 필요한지 다시 생각해 보세요

대부분의 모니터링 구성은 첫 번째 범주에 너무 많은 것을 넣고 두 번째 범주에는 충분히 넣지 않습니다. 대다수 이벤트의 올바른 답은 "내일 처리한다"이며, 벨을 울리지 않고 잠금 화면에 표시되는 긴급 알림이야말로 그런 상황에 딱 맞는 도구입니다.

한 번에 하나씩

지금의 구성이 알림 피로를 낳고 있다면, 가장 빠른 해결책은 전면적인 개편이 아닙니다. 가장 시끄러운 소스를 하나 고르고, 아마도 Sentry 이메일이거나 모두가 음소거해 둔 Slack 채널일 텐데, 각 이벤트 유형을 전화, 긴급, 일반 중 하나로 분류하세요.

하나의 소스, 한 주. 신호를 잃지 않으면서 소음이 줄어드는지 확인해 보세요.

그런 다음 다음 소스로 넘어가면 됩니다.

잘 조율된 알림 구성은 요란하지 않게 일상적인 업무를 조용히 개선해 주는 그런 것들 중 하나입니다. 휴대폰을 두려워하지 않게 되고, 휴대폰이 울리면 정말로 중요한 일이라고 믿게 됩니다.


관련 글

관련 글