도입부: 익숙한 작업일수록 “당연히 될 것”이라는 방심이 사고로 이어지곤 합니다. 이 글에서는 ‘당연히’를 전제로 하지 않기 위해 제가 무엇을 안전장치로 바라보게 되었는지, 그리고 가장 작은 비용으로 먼저 도입할 수 있는 실천 항목을 정리해봅니다.
1) 사고는 “실패”보다 “당연함”에서 시작됩니다
익숙한 일·동일한 환경에서는 뇌가 자동완성을 해버립니다. “전에 했으니까 이번에도 당연히 되겠지”라는 전제는 작업 속도를 올려주지만, 그 전제가 깨지는 순간엔 원인 추적이 어려운 형태의 사고로 이어지기 쉽습니다.
저도 한 번 사고를 겪고 나니 “당연히”라는 말을 하기 어려워졌고, 전반적인 불안이 커졌습니다. 그런데 이 불안을 줄이는 방법은 “더 조심하기” 같은 마음가짐보다, **당연히 동작하도록 만드는 장치(프로세스/도구/증거)**를 추가하는 쪽이 더 효과적이었습니다.
핵심 전환은 이거였습니다.
- “당연히 된다”가 아니라 **“실패는 발생한다”**를 기본값으로 둡니다.
- 중요한 건 실패 자체가 아니라 피해를 제한하고, 빨리 원인을 재구성하는 것입니다.
2) 최소 안전장치 1순위는 “작업 계획 + 원복/복구”일까요?
대화에서 제가 처음 떠올린 최소 안전장치는 작업 계획과 원복/복구 방법이었습니다. 이 접근이 좋은 이유는, 안전장치를 “실패 방지”가 아니라 실패했을 때의 피해 제한 관점으로 보기 때문입니다.
다만 여기엔 함정도 있습니다.
- 원복이 준비되면 심리적으로 더 과감해질 수 있습니다(리스크 보상).
- 특히 아래 유형은 “원복 가능”이 착시가 되기 쉽습니다.
- 데이터 마이그레이션/스키마 변경
- 외부 연동 변경(서드파티 API, 메시지 발행, 결제/알림 등)
- 시간이 지나면서 상태가 계속 변하는 작업(배치/정산/동기화)
그래서 “원복”을 말하려면, 단위를 단순히 배포/서버가 아니라 데이터 + 외부효과까지 포함해 정의해야 합니다.
원복이 어려울 때의 현실적인 대안
원복이 사실상 불가능하다면, “되돌리기”보다 아래가 더 실용적일 때가 많습니다.
- 정지(킬스위치): 기능 자체를 즉시 끕니다.
- 격리(트래픽 차단): 문제 구간으로 들어오는 요청을 차단/우회합니다.
- 보정(보상 트랜잭션): 이미 발생한 외부효과를 상쇄하는 후속 처리를 준비합니다.
- 롤포워드(수정 배포): 되돌리는 대신 빠르게 고쳐서 앞으로 나아갑니다.
- 기능 플래그/단계적 배포: 영향 범위를 작게 만든 뒤 관측하며 확장합니다.
3) “원복보다 먼저” 필요한 것: 무엇이 일어났는지 아는 능력(Observability)
대화를 하면서 더 본질적인 문제가 드러났습니다.
“추상적으로 결과가 나오기 때문에 실제 어떤 작업이 일어났는지 모르는 부분”
이 상황에서는 작업 계획서나 원복 절차보다 먼저, 증거가 남아야 합니다.
즉, 관측 가능성(observability) 부족이 사고의 핵심 원인이 될 수 있습니다.
원복/복구는 결국 “무슨 일이 있었는지”를 알아야 실행할 수 있습니다. 그런데 결과만 추상적으로 보이고, 실제로 어떤 요청이 어디로 전파됐는지(의존 시스템), 어떤 데이터가 어떻게 바뀌었는지(변경 이력)가 안 보이면 복구는 추측이 됩니다.
그래서 최소 안전장치의 우선순위는 이렇게 재정렬되는 느낌이었습니다.
- 증거를 남긴다(로그/트레이스/감사 로그)
- 실패했을 때 피해를 멈춘다(킬스위치/격리)
- 그 다음에야 원복/복구/보정이 실효성을 가집니다
4) 제가 제안하는 “가장 먼저 도입할 최소 안전장치”: 1줄 구조화 로그
“관측”은 거창하게 시작하면 오래 걸립니다. 그래서 저는 “최소 안전장치”라는 질문에 이렇게 답하고 싶습니다.
- 모든 걸 남기려 하지 말고
- 사고 시 원인을 재구성할 수 있는 ‘최소 증거 1줄’을 먼저 정합니다
대화에서 제가 꼽았던 키워드는 코드, 시간, 로그였습니다. 이를 운영에서 쓸 수 있게 바꾸면 아래 조합이 됩니다.
- 언제:
timestamp - 어떤 코드:
version(commit sha, build number) - 어떤 흔적:
structured log(요청/변경/외부호출의 연결고리)
예시(필드 설계의 뼈대):
{
"timestamp": "2026-04-20T12:34:56.789Z",
"service": "order-api",
"env": "prod",
"version": "git:1a2b3c4",
"request_id": "req-9f2c...",
"actor": "system|user:123",
"action": "OrderConfirm",
"target": {"type": "order", "id": "O20260420-0001"},
"dependency_call": {"name": "payment.authorize", "status": "success", "latency_ms": 120},
"result": "success"
}
이 1줄이 주는 효과는 명확합니다.
- “무슨 코드가(버전)”
- “언제”
- “누가/무엇을 대상으로”
- “어떤 외부 의존 호출을 했고”
- “결과가 뭐였는지”
가 연결됩니다. “추상적 결과”가 “재구성 가능한 사건”으로 바뀝니다.
어디에 먼저 찍을까?
가장 좋은 시작점은 보통 진입점(API/배치 시작점) 또는 가장 치명적인 의존 시스템을 호출하는 지점입니다.
왜냐하면 사고는 대개 “내 서비스 안”보다 “의존 시스템과의 경계”에서 커지기 때문입니다.
5) 인사이트: ‘당연히’를 없애는 게 아니라, ‘당연히 동작하게’ 만들어야 합니다
사고 이후 불안이 커지는 건 자연스러운 반응입니다. 하지만 그 불안을 “더 조심하자”로만 풀면, 결국 사람의 집중력에 안전을 외주 주는 셈이 됩니다.
제가 얻은 결론은 이렇습니다.
- “당연히 된다”는 믿음을 버리는 순간, 불안이 커질 수 있습니다.
- 대신 당연히 동작하도록 만드는 장치(증거/정지/복구)를 추가하면,
- 불안은 “막연함”에서 “통제 가능한 리스크”로 바뀝니다.
그리고 그 첫 단추는 의외로 작게 시작할 수 있습니다.
저는 작업 계획/원복도 중요하지만, 그보다 먼저 무슨 일이 일어났는지 알 수 있는 최소 로그 1줄이 가장 강력한 최소 안전장치라고 느꼈습니다.
마무리
“당연함의 함정”을 피하려면 “당연히”를 금지어로 만드는 게 목적이 아니라, 실패를 전제로도 시스템이 버티도록 만드는 게 목적입니다. 오늘 작업부터라도 코드(버전)·시간·구조화 로그로 사건을 재구성할 수 있는 최소 증거를 남겨보면, 불안은 줄고 재발방지는 훨씬 현실적으로 시작할 수 있습니다.