10. 실행과 모니터링¶
자동화는 만드는 것보다 조용히 멈춘 걸 알아채는 것이 어렵습니다. 이 문서는 그 부분을 다룹니다.
대시보드 — 전체 상황 보기¶
로그인 후 처음 보이는 화면입니다.
| 지표 | 뜻 |
|---|---|
| 전체 워크플로우 | 만들어둔 워크플로우 수 |
| 전체 실행 | 지금까지 실행된 총 횟수 |
| 성공률 | 성공률 |
| 진행 중 실행 | 지금 돌고 있는 실행 수 |
아래 최근 실행에 최근 실행이 나옵니다. 성공률이 갑자기 떨어졌다면 여기부터 보세요.
실행 이력 보기¶
워크플로우 상세 → 개요 탭 아래쪽에 그 워크플로우의 실행 이력이 있습니다.
실행 하나를 클릭하면 노드별로 이런 걸 볼 수 있습니다.
- 각 노드의 상태 (성공/실패/재시도 중)
- 그 노드가 받은 입력
- 그 노드가 낸 출력
- 실패했다면 에러 메시지
디버깅의 90%는 여기서 끝납니다. 실패한 노드의 바로 앞 노드 출력을 보면 표현식 경로가 틀렸는지, 값이 비어 있었는지 대부분 바로 보입니다.
상태 읽기¶
실행 전체
| 상태 | 뜻 |
|---|---|
RUNNING |
돌고 있음 |
COMPLETED |
끝까지 성공 |
FAILED |
도중에 실패 |
CANCELLED |
취소됨 |
노드 하나하나
| 상태 | 뜻 |
|---|---|
PENDING |
차례를 기다리는 중 |
RUNNING |
실행 중 |
COMPLETED |
성공 |
FAILED |
실패 |
RETRYING |
재시도 중 |
CANCELLED |
실행이 실패로 끝나면서 정리됨 |
SKIPPED |
조건 분기에서 선택되지 않아 실행되지 않음 |
CANCELLED는 그 노드 자체의 문제가 아닙니다. 다른 노드가 실패해서 실행이 종료될 때
아직 돌고 있던 노드가 정리된 상태입니다. 진짜 원인은 FAILED 노드에 있습니다.
SKIPPED는 정상입니다. CONDITIONAL이 다른 가지를 골라서 이쪽 길이 안 쓰인 것뿐입니다.
JOINT와 LOOP_END는 SKIPPED를 "끝난 것"으로 인정하므로 실행이 여기서 멈추지 않습니다.
→ 06. 흐름 제어
재시도와 타임아웃¶
외부 API는 가끔 실패합니다. 일시적인 실패로 자동화 전체가 멈추지 않도록 두 가지 장치가 있습니다.
- id: fetch-orders
name: 주문 조회
type: CALL
integration: http_request
timeout: 10s
retry-policy:
max-attempts: 3
backoff:
type: EXPONENTIAL
initial-delay: 500ms
multiplier: 2.0
max-delay: 10s
retry-on: ["429", "5xx"]
input:
...
timeout — 언제까지 기다릴지¶
이 시간을 넘으면 노드를 실패 처리합니다. 쓸 수 있는 형식은 500ms · 10s · 5m 입니다 (숫자 + ms/s/m).
| 노드 종류 | 권장 |
|---|---|
| 빠른 API 조회 | 5s ~ 10s |
| 무거운 조회·리포트 API | 30s ~ 1m |
AI 호출 (llm_chat) |
30s ~ 2m |
타임아웃을 안 걸면 응답 없는 API를 하염없이 기다리다 실행이 오래 매달릴 수 있습니다. 외부 호출에는 걸어두는 편이 좋습니다.
retry-policy — 몇 번 다시 해볼지¶
| 항목 | 필수 | 설명 |
|---|---|---|
max-attempts |
✅ | 최대 시도 횟수 (최초 시도 포함). 3이면 최초 1회 + 재시도 2회 |
backoff.type |
✅ | FIXED (매번 같은 간격) 또는 EXPONENTIAL (점점 길게) |
backoff.initial-delay |
✅ | 첫 재시도까지 대기 시간 |
backoff.multiplier |
EXPONENTIAL일 때 배수. 기본 2.0 |
|
backoff.max-delay |
대기 시간 상한 | |
retry-on |
어떤 실패일 때 재시도할지. 비우면 재시도 가능한 실패 전부 |
EXPONENTIAL로 initial-delay: 500ms, multiplier: 2.0이면 대기 시간이 500ms → 1s → 2s → 4s로 늘어납니다.
⚠️ retry-on 은 두 종류를 따로 거릅니다¶
retry-on에 쓸 수 있는 값은 두 갈래이고, 각 갈래는 서로를 건드리지 않습니다.
| 갈래 | 쓸 수 있는 값 | 뜻 |
|---|---|---|
| HTTP 상태 | "429" · "503" (정확한 코드) · "5xx" · "4xx" (범위) |
응답은 왔는데 상태 코드가 실패 |
| 실패 종류 | "timeout" · "connect-error" |
응답 자체가 없는 실패 (상태 코드가 없음) |
한 갈래에 아무것도 안 적으면 그 갈래는 전부 재시도됩니다. 이게 가장 헷갈리는 지점입니다.
retry-on: ["5xx"]
# → 상태는 5xx 만 재시도. 하지만 실패 종류 쪽에 적은 게 없으므로
# 타임아웃 · 연결 오류는 여전히 전부 재시도됩니다.
retry-on: ["5xx", "connect-error"]
# → 상태는 5xx 만, 실패 종류는 연결 오류만. 타임아웃은 재시도하지 않습니다.
retry-on: ["timeout"]
# → "타임아웃만 재시도"가 아닙니다. 상태 쪽에 적은 게 없으므로
# 429 · 5xx 를 포함한 상태 실패가 전부 재시도됩니다.
retry-on: ["TIMEOUT"]
# ❌ 대문자는 없는 값입니다. 저장이 거부됩니다 (소문자 "timeout")
발송 노드처럼 재시도를 정말 좁혀야 한다면 두 갈래를 다 적으세요.
재시도를 걸면 안 되는 경우¶
같은 요청을 두 번 보내면 안 되는 일에는 재시도를 걸지 마세요.
| 노드 | 재시도 |
|---|---|
| 조회 (GET) | ✅ 안전 |
| 데이터 변환 | ✅ 안전 |
| 메시지 발송 | ⚠️ 두 번 갈 수 있음 |
| 결제·주문 생성 | ❌ 위험 |
메시지 발송은 두 갈래를 다 적어서 좁히는 게 안전합니다.
retry-on: ["429", "5xx", "connect-error"]
# 연결이 아예 안 된 경우(= 아직 안 갔음)만 재시도하고,
# 타임아웃(= 갔는데 응답을 못 받았을 수 있음)은 재시도하지 않습니다.
워크플로우 켜고 끄기¶
지우지 않고 잠시 멈추는 기능입니다. 매일 도는 스케줄러가 잘못된 알림을 계속 보내고 있는데 워크플로우는 살려두고 싶을 때 씁니다.
어디서 끄나¶
워크플로우 목록과 상세 화면의 토글로 켜고 끕니다. 켜져 있으면 켜짐, 꺼져 있으면 꺼짐입니다.
꺼두면 무엇이 막히나¶
| 실행 경로 | 꺼진 상태에서 |
|---|---|
| 스케줄(cron) 발화 | ❌ 발화하지 않음 |
| 웹훅 수신 | ❌ 409로 거절 |
| AI 비서(MCP) 실행 | ❌ 거절 |
| 화면에서 실행 버튼 | ✅ 통과 |
수동 실행만 열어둔 이유는 끄고 → 고치고 → 테스트하고 → 다시 켜는 흐름이 성립해야 하기 때문입니다. 고친 걸 확인하려고 다시 켜는 순간 cron이 같이 살아나면 곤란하니까요.
알아둘 것¶
- 막는 것은 새 실행뿐입니다. 이미 시작된 실행은 끝까지 갑니다. 멈추려면 실행 이력에서 취소하세요.
- 끈다고 저장이 풀리지는 않습니다. 실행 중인 워크플로우는 여전히 저장할 수 없습니다.
- YAML을 다시 저장해도 켜짐/꺼짐은 그대로입니다. 켜짐 상태는 워크플로우 정의(YAML)가 아니라
운영 상태라서
YAML탭 왕복에 영향을 받지 않습니다.
⚠️ GitHub 웹훅을 오래 꺼두면¶
GitHub은 웹훅 전송 실패가 쌓이면 그 웹훅을 자동으로 비활성화합니다. 꺼진 동안 이음새가
409를 돌려주므로 GitHub 입장에서는 실패로 쌓입니다.
오래 꺼두었다가 다시 켰다면, GitHub 쪽 웹훅이 아직 살아 있는지 리포지토리 설정에서 확인하세요.
실패 알림 설정 — 꼭 하세요¶
매일 도는 자동화가 조용히 멈춰도 아무도 모릅니다. 이걸 막는 기능입니다.
사이드바 알림으로 들어가서 설정합니다.
| 항목 | 설명 |
|---|---|
| 웹훅 URL | 실패 알림을 받을 주소. http:// 또는 https://로 시작해야 합니다 |
| 알림 활성화 | 꺼두면 실패해도 알림이 가지 않습니다 |
워크플로우 실행이 실패로 끝나면 이 주소로 한 번 POST가 갑니다.
Slack 수신 웹훅 만들기¶
- api.slack.com/apps에서 앱을 만들거나 기존 앱을 엽니다.
- Incoming Webhooks를 켭니다.
- Add New Webhook to Workspace로 알림 받을 채널을 고릅니다.
- 나온
https://hooks.slack.com/services/...주소를 알림 화면에 붙여넣습니다.
Discord도 채널 설정 → 연동 → 웹훅에서 같은 방식으로 주소를 만들 수 있습니다.
이미 URL이 설정되어 있으면 화면에 가려진 형태로 표시됩니다. 입력창을 비워둔 채 저장하면 기존 URL이 유지되고 켜기/끄기만 바뀝니다.
워크플로우 안의 Slack 발송과는 다른 기능입니다. 여기 설정은 "자동화가 실패했다"는 시스템 알림이고,
slack_post_message노드는 자동화가 정상 동작해서 보내는 업무 메시지입니다.
워크플로우 수정과 실행 중인 작업¶
실행이 시작될 때 그 순간의 워크플로우 모양이 저장되고, 그 실행은 끝까지 그 모양대로 돕니다.
- 오래 걸리는 실행이 도는 중에 워크플로우를 고쳐도 이미 도는 실행은 영향받지 않습니다.
- 수정 내용은 다음 실행부터 적용됩니다.
- MCP로 워크플로우를 수정할 때는 실행 중인 게 있으면 거부됩니다. 끝나기를 기다리거나 취소한 뒤 다시 시도하세요.
점검 체크리스트¶
새 자동화를 켤 때 한 번씩 확인하면 좋습니다.
- [ ] 외부 호출 노드에
timeout을 걸었나 - [ ] 조회 노드에
retry-policy를 걸었나 - [ ] 발송·결제 노드에 불필요한 재시도를 걸지 않았나
- [ ] 알림 화면에 실패 알림 웹훅을 설정했나
- [ ] 스케줄 트리거에
timezone: "Asia/Seoul"을 넣었나 - [ ] API 키를 YAML에 직접 적지 않고
${secrets.*}로 넣었나 - [ ] 배열을 넘기는 곳에
| raw를 붙였나 - [ ] 첫 실행을 실제로 돌려보고 실행 이력에서 결과를 확인했나
- [ ] 공개된 웹훅이라면
WEBHOOK_SECRET으로 서명 검증을 켰나
다음 → 11. AI 비서로 만들기 (MCP)