알림 센터
알림 센터는 Gately 내부 이벤트 버스를 구독하여 DDNS 변경, 인증서 만료, WAF 차단, 프로세스 이상 등의 이벤트를 규칙에 따라 Webhook, Telegram, Bark, ntfy, Gotify, Pushover, Discord, Slack, ServerChan, PushPlus, WeCom, DingTalk, Feishu, 이메일로 푸시합니다. 관리 UI는 사이드바 「시스템」 그룹 → 「알림 센터」에 있습니다.
동작 방식
- 각 모듈은 상태가 바뀔 때 프로세스 내 이벤트 버스에 이벤트를 발행하며, 발행은 비즈니스 로직을 막지 않습니다.
- 알림 센터는 이벤트를 받으면 규칙을 하나씩 대조합니다. 규칙이 활성화되어 있고, 이벤트 레벨이 규칙의 최소 레벨 이상이며, 이벤트 유형이 규칙의 이벤트 목록과 일치해야 합니다.
- 일치한 규칙은 음소거 중복 제거를 거친 뒤 규칙에서 선택한 활성 채널로 메시지를 전달합니다. 한 이벤트가 여러 규칙에 일치하더라도 같은 채널로는 한 번만 보냅니다.
- 전달 결과(성공 또는 실패 사유)는 「최근 전송」에 기록되며 메모리에 최근 200건을 보관합니다. 실패는 모듈 로그에도 기록됩니다.
한 번의 전달 타임아웃은 45초입니다.
채널
「채널 추가」를 누르고 유형을 선택한 뒤 필드를 입력합니다. 모든 채널에는 이름(필수), 메모, 사용 스위치가 있습니다. 비밀 값 필드는 저장한 뒤 다시 표시되지 않으며 편집할 때 비워 두면 기존 값을 유지합니다.
| 유형 | 필수 필드 | 선택 필드 |
|---|---|---|
| Webhook | 요청 주소 | 요청 메서드(기본 GET, GET / POST / PUT / PATCH 선택 가능), 요청 헤더(한 줄에 Key: Value), 요청 본문, 성공 판정 내용, 타임아웃(초, 기본 20), 인증서 검증 건너뛰기 |
| Telegram | Bot Token, Chat ID | API 주소(비우면 https://api.telegram.org 사용) |
| Bark | 장치 Key | 서비스 주소(비우면 https://api.day.app 사용) |
| WeCom | 봇 주소 | 없음 |
| DingTalk | 봇 주소 | 서명 키(봇에서 「서명」을 켠 경우 입력) |
| Feishu | 봇 주소 | 서명 키(봇에서 「서명 검증」을 켠 경우 입력) |
| 이메일 | 서버, 수신자, 그리고 발신자 또는 사용자 이름 중 하나 이상 | 암호화 방식, 포트, 사용자 이름, 비밀번호 |
| ntfy | 토픽 | 서비스 주소(비우면 https://ntfy.sh 사용), 액세스 토큰 |
| Gotify | 서비스 주소, 애플리케이션 토큰 | 없음 |
| Pushover | 애플리케이션 토큰, 사용자 Key | 없음 |
| Discord | Webhook 주소 | 없음 |
| Slack | Webhook 주소 | 없음 |
| ServerChan | SendKey | 없음 |
| PushPlus | Token | 없음 |
주소 필드에는 http:// 또는 https://로 시작하는 전체 주소가 필요합니다.
Webhook 템플릿 변수
요청 주소와 요청 본문에서 다음 변수를 쓸 수 있으며, 중괄호로 변수 이름을 감싸 씁니다(# 접두사 표기도 호환됩니다).
| 변수 | 내용 |
|---|---|
title | 제목, 형식은 [Gately] 이벤트 제목 |
message | 이벤트의 상세 설명 |
text | 설명, 출처, 레벨, 시간을 포함한 전체 본문 |
type | 이벤트 유형. 예: ddns.changed |
source | 이벤트 출처 |
level | 레벨 info, warn, error |
time | RFC 3339 형식의 시간 |
이벤트에 포함된 추가 필드(ip, container 등)도 변수로 쓸 수 있으며, 위 표와 이름이 겹치면 위 표가 우선합니다. 주소에 들어가는 변수 값은 URL 이스케이프됩니다.
이메일
| 암호화 방식 | 값 | 기본 포트 |
|---|---|---|
| STARTTLS | starttls | 587 |
| SSL/TLS | tls | 465 |
| 암호화 없음 | none | 25 |
포트를 0으로 두면 암호화 방식에 따른 기본 포트를 사용합니다. 수신자는 여러 명을 쉼표로 구분해 입력할 수 있습니다. 이메일은 UTF-8 인코딩의 일반 텍스트이며, 서버가 AUTH를 지원하고 사용자 이름이 입력되어 있으면 PLAIN 인증을 사용합니다. 발신자를 비우면 사용자 이름을 사용합니다.
서명과 응답 코드
- DingTalk: 서명 키를 입력하면 요청에
timestamp와sign이 자동으로 포함됩니다. - Feishu: 서명 키를 입력하면 요청 본문에
timestamp와sign이 자동으로 포함됩니다. - WeCom, DingTalk, Feishu, Bark는 응답의 비즈니스 반환 코드를 확인하며, HTTP 200이어도 비즈니스상 실패하면 전달 실패로 기록합니다.
규칙
「규칙 추가」를 누릅니다.
| 필드 | 설명 |
|---|---|
| 이름 | 필수 |
| 이벤트 | 최소 하나. 구체적인 이벤트 유형을 선택할 수 있으며 *는 모든 이벤트를 뜻하고 ddns.*처럼 와일드카드를 입력할 수도 있습니다. 와일드카드는 Go path.Match 문법을 따릅니다 |
| 최소 레벨 | info(정보), warn(경고), error(오류). 비우면 정보입니다. 이벤트 레벨이 이 값보다 낮으면 푸시하지 않습니다 |
| 채널 | 최소 하나 |
| 음소거(초) | 같은 규칙에서 같은 출처의 같은 유형 이벤트는 이 시간 안에 한 번만 푸시하고 그동안의 중복 이벤트는 버립니다. 0이면 중복 제거를 하지 않습니다 |
| 사용 | 스위치 |
팁
WAF 차단과 업스트림 상태 변화는 자주 발생할 수 있으므로 이런 규칙에는 음소거 시간을 300초 이상으로 설정하기를 권장합니다.
규칙 템플릿
규칙을 새로 만들 때 템플릿을 누르면 이벤트, 레벨, 음소거 시간이 미리 채워지며, 채널을 선택해 저장하면 됩니다.
| 템플릿 | 이벤트 |
|---|---|
| 주요 장애 | DDNS 갱신 실패, 인증서 갱신 실패, 업스트림 사용 불가, 하위 프로세스 비정상 종료, 백업 실패, 컨테이너 종료 |
| 인증서 만료 | 인증서 곧 만료, 갱신 실패(음소거 24시간) |
| 주소 변경 | DDNS 레코드 갱신, STUN 주소 변경 |
| 서비스 상태 | 업스트림 사용 불가 및 복구, 컨테이너 종료, 하위 프로세스 종료 |
| 보안 및 로그인 | 로그인 실패, IP 차단, 로그인 성공, 민감한 콘텐츠 접근 |
| 설정 변경 | 관리 콘솔에서 이루어진 모든 설정 변경 |
이벤트 유형
| 이벤트 유형 | 이름 | 레벨 | 발생 조건 |
|---|---|---|---|
ddns.changed | 동적 DNS: 레코드 갱신됨 | 정보 | DDNS 작업이 레코드를 성공적으로 갱신함 |
ddns.failed | 동적 DNS: 갱신 실패 | 오류 | DDNS 작업의 갱신이 실패함 |
stun.changed | STUN: 통과 주소 변경 | 정보 | STUN 규칙의 통과 주소가 바뀜 |
ssl.expiring | 인증서: 곧 만료 | 경고 | 인증서의 남은 유효 기간이 7일 미만이며 같은 인증서는 24시간에 최대 한 번 알림 |
ssl.renew_failed | 인증서: 갱신 실패 | 오류 | 인증서 발급 또는 갱신이 실패함 |
waf.blocked | WAF: 요청 차단 | 경고 | WAF가 요청 하나를 차단함. ip, host, path 필드 포함 |
upstream.down | 리버스 프록시: 업스트림 사용 불가 | 오류 | 웹 서비스의 백엔드가 사용 불가로 판정됨 |
upstream.up | 리버스 프록시: 업스트림 복구 | 정보 | 사용 불가였던 백엔드가 복구됨 |
docker.exited | Docker: 컨테이너 종료 | 경고 또는 오류 | 컨테이너가 0이 아닌 종료 코드로 종료됨(경고) 또는 메모리 부족으로 종료됨(오류) |
process.exited | 하위 프로세스 비정상 종료 | 오류 | Gately가 관리하는 하위 프로세스가 비정상 종료되어 자동으로 재시작될 예정이며 출처는 해당 프로세스의 로그 이름 |
backup.done | 백업: 완료 | 정보 | 예약 또는 수동 백업이 모든 대상에 성공함. 설정 백업 참고 |
backup.failed | 백업: 실패 | 오류 | 백업 압축에 실패하거나 어느 대상에 쓰지 못함 |
auth.failed | 인증: 연속 실패 | 경고 | 관리 콘솔 로그인에 실패함. ip 필드 포함 |
auth.banned | 인증: IP 차단됨 | 경고 | 웹 서비스 인증이 연속으로 실패하여 자동 차단이 발동함 |
login.success | 관리 콘솔: 로그인 성공 | 정보 | 관리 콘솔 로그인에 성공함. ip, user 필드 포함 |
audit.change | 관리 콘솔: 설정 변경 | 정보 | 관리 콘솔에서 이루어진 모든 변경 작업. actor, ip, method, path 필드 포함. 감사 로그와 설정 기록 참고 |
audit.access | 관리 콘솔: 민감한 콘텐츠 접근 | 경고 | 백업, 진단 번들, 인증서 개인 키 다운로드 또는 터미널 열기 등. 필드는 위와 같음 |
notify.test | 테스트 알림 | 정보 | 채널의 「테스트」 버튼이 만들며 규칙 매칭에는 참여하지 않음 |
테스트 전송
채널 카드의 「테스트」 버튼은 해당 채널로 「테스트 알림」이라는 제목의 메시지를 직접 보냅니다. 규칙을 거치지 않으며 채널이 활성화되어 있지 않아도 됩니다. 전송에 성공하면 「테스트 알림을 보냈습니다」라고 표시되고, 실패하면 구체적인 오류가 표시됩니다. 테스트 결과도 「최근 전송」에 나타나며 규칙 열에는 「테스트」로 표시됩니다.
해당 API는 POST /api/notify/channels/{key}/test이며 API 토큰의 notify:write 권한으로 호출할 수 있습니다.