가시성 (1) - 그 개념에 대하여

백엔드 개발자들끼리 이야기하다보면 "어떻게 모니터링하냐"는 주제는 반드시 등장하는 것 같습니다. 특정 기능을 만들어서 배포하면 마치 자식을 학교에 보내놓은 부모의 마음처럼 가서 친구들하고 잘 지내는지, 급식은 잘 먹었는지 궁금하지 않을 수 없기 때문입니다. 결국 대화는 가시성에 대한 내용으로 옮겨갑니다.
그러다 문득 내가 가시성을 과연 제대로 이해하고 있는게 맞나 궁금해졌습니다. 호기심이 동한김에 가시성에 대한 시리즈를 시작합니다.
가시성
가시성(observability)이란?
가시성(Observability) 은 시스템이 스스로 내보내는 신호만으로 내부 상태를 재구성하고 특정 현상의 원인을 추론할 수 있는 능력을 뜻합니다. 처음엔 제어공학 용어였지만, 오늘날 소프트웨어, 클라우드 세계에서는 그 아래와 같은 특징이 나타났습니다.
| 특징 | 설명 |
| 출력 기반 진단 | 로그, 메트릭, 트레이스, 이벤트, 프로파일링 등 외부 출력 만 보고 내부를 추적할 수 있음. |
| 액션 가능성 (Actionability) | 데이터를 단순히 모아서 리포팅하는게 목적이 아니라 쿼리, 시각화, 알림을 통해 문제를 신속히 파악하고 조치할 수 있도록 함. |
| 미지의 질문(Unknown-Unknowns) 대응 | 미리 정의된 대시보드, 경보만으로는 알 수 없는 새로운 현상을 탐지, 분석할 수 있어야함 |
| 시스템 내재적 품질 | 가시성은 시스탬에 내재된 특성이므로 설계 단계부터 풍부한 외부 출력을 내보내도록 만들어야함 |
가시성은 모니터링과 다른 개념이다.
가시성과 모니터링은 미지의 질문에 대응할 수 있도록 해주느냐, 그리고 그 목표가 무엇이냐 즉, 요구되는 내용이 근본적으로 다릅니다.
| 구분 | 모니터링 | 가시성 |
| 원하는 것 | 문제가 발생했는지 파악하는것, 즉 알려진 미지(Known Unkowns)를 기록하고 리포팅하는 것 | 알려지지 않은 미지(Unkown Unkowns)에 대응해서 왜 문제가 발생했는지, 다른 이상 징후는 없는지 알아내는 것 |
| 목표 | SLA 준수, 빠른 감지 | 근본 원인 분석(RCA), MTTR 단축, 시스템 개선 |
| 데이터 수집 방식 | 사전 정의된 메트릭 위주 | 보다 포괄적인 데이터 스트림, 로그, 트레이스, 이벤트 |
| 세분화 | 일반적으로 호스트와 에이전트를 설치하고 외부 관점에서 메트릭을 캡쳐 | 일반적으로 코드 수준에서 측정되어 모니터링이 달성하기 어려운 세분화 수준을 제공 |
엄밀하게 따지자면 모니터링과 가시성은 다른 개념입니다. 예를 들어 AWS에서 기본적으로 제공하는 EC2, RDS 등의 모니터링 화면은 모니터링의 적절한 예시일 것입니다. 반면 데이터독과 같은 플랫폼은 RCA 까지 제공하는 가시성의 적절한 예시입니다.
하지만 저는 아직까지 백엔드 개발자 실무에서 이를 엄격하게 구분한적이 없습니다. Goole의 SRE 가이드의 분산 시스템 모니터링 섹터에서 가시성에 대한 엄밀한 정의 없이 Root cause 를 다루고 있는걸 보면 실무자에게 모니터링과 가시성은 굳이 엄밀히 구분지을 필요가 없는 개념일지도 모릅니다. 어쩌면 이미 모니터링툴이라고 사용하고 있는 많은 솔루션들에 가시성의 개념이 녹아있기 때문일지도 모르지요.
정말 가시성이 필요한가?
개발자들과 이야기를 하다보면 지금도 로그로 오류를 잡고 AWS CloudWath 대시보드로 모두 파악이 되는데 굳이 가시성이라는 분야에 투자를 또 해야하나? 이야기가 나옵니다. 그런데 이렇게 생각을 해보면 어떨까요?
시간이 곧 돈이다.
시스템 장애에 따른 비용은 MTTR(Mean Time To Recovery) x SPT(Sales Per Time) + a 를 따를 것입니다.
a 는 시스템 장애에 실망해서 떠나가는 고객들이 만들어냈을 잠재 매출이며 a MTTR에 대한 함수입니다. 즉, 장애복구에 시간이 길어지면 길어질 수록 이탈 고객도 많아지는 것이지요.
모니터링만으로는 장애발생 근본 원인(Root Cause)를 빠르게 밝히기 어렵습니다. 로그를 뒤져서 밝혀내는 것보다 한번에 파악이 가능한 경우가 MTTR을 줄일 수 있겠죠? 가시성을 확보한다면 MTTR을 줄이는 것은 물론이고 잠재적인 오류 발생 가능성도 파악할 수 있습니다.
복잡성의 기울기
단일 시스템을 다룰때는 로그만으로 대응이 가능해집니다. 하지만 마이크로서비스로 구축되었고 심지어 이벤트 기반 아키텍처라면 단일 로그 스트림으로는 오류 원인을 찾기 굉장히 힘들어집니다.
서비스가 하나씩 추가되어 시스템 토폴로지가 계단식으로 복잡해질 때 가시성에 대한 투자는 선형이 아니 지수적인 가치를 만들어낼것입니다.
조직의 속도와 개발자 경험
릴리스 주기가 짧아질수록 신규 코드, 인프라가 무슨 부작용을 일으키는지 빠르게 파악해야합니다. 그래야 배포 속도를 유지하고 개발자들도 용기를 가질 수 있습니다. 또한 가시성 없이 계속 시스템이 복잡해진다면 디버깅 -> 야근 -> 이직률 상승이라는 악순환이 발생할 수 있습니다.
결국 가시성이란 장애에 대응하는 속도(MTTR)를 줄임으로써 서비스 품질 유지(매출), 개발 조직의 안정성 향상까지 기여할 수 있는 개념입니다.
가시성을 확보하는 방법
가시성이 중요하다는 건 알겠는데, 실제로 어떤 신호(signal)를 모아야 MTTR을 줄일 수 있는 걸까요?
현대적인 가시성은 보통 3대 시그널과 +a 를 많이 이야기합니다. Logs ,Metrics, Traces 그리고 Profiling이 그것입니다.
| 시그널 | From | What |
| Logs | 어플리케이션 라이브러리 | 상태 변화, 예외 스택 수집 |
| Metrics | 라이브러리 Exprter 가 주기적으로 전송 | 수량, 속도(QPS, CPU, P99 지연) 등, 이를 통해 알림과 대시보드를 만듦 |
| Traces | 요청-응답 체인에 따라 자동 삽입된 스캔 | 분산 호출 순서, 지연 구간, 오류 지점 파악 |
| Profiling | 커널 이벤트와 애플리케이션 스택 | 함수, 메서드 라인 단위 CPU 메모리, I/O Hotspot 파악 |
이상의 시그널을 이용해서 “에러가 났다(Logs) → 어느 구간이 느렸다(Metrics) → 어떤 호출 체인에서 지연이 컸다(Traces) → 해당 함수가 CPU를 먹었다(Profiling)” 식의 원인 추적 체인이 완성됩니다.
참고
- CNCF, Observability: https://glossary.cncf.io/observability/?utm_source=chatgpt.com
- Wikipedia, Observability: https://en.wikipedia.org/wiki/Observability_%28software%29?utm_source=chatgpt.com
- Splunk, Observability: https://www.splunk.com/en_us/blog/learn/observability.html?utm_source=chatgpt.com