로그는 남기지 않으면 존재하지 않는 것과 같다
로그는 남기지 않으면 존재하지 않는 것과 같다
운영 중 장애보다 더 무서운 건, 왜 터졌는지 모르는 장애다. 에러가 발생했다는 사실 자체보다, 그 원인을 추적할 수 없다는 상황이 훨씬 치명적이다. 문제가 재현되지 않고, 관련 정보도 남아 있지 않다면 그 장애는 사실상 “관측되지 않은 이벤트”가 된다. 그리고 관측되지 않은 문제는 해결할 수도, 예방할 수도 없다.
이 지점에서 로그, 메트릭, 트레이싱은 단순한 부가 기능이 아니라 시스템을 이해하기 위한 핵심 도구가 된다. 이 세 가지는 모두 “관측 가능성(Observability)”을 구성하는 요소지만, 각각의 역할은 명확하게 다르다.
로그는 가장 기본적인 형태의 기록이다. 특정 시점에 어떤 일이 발생했는지를 텍스트 형태로 남긴다. 에러 메시지, 요청 파라미터, 처리 결과 같은 정보들이 여기에 포함된다. 디버깅 과정에서 로그는 “무슨 일이 있었는가”를 가장 구체적으로 알려주는 단서가 된다. 다만 로그는 기본적으로 이벤트 중심이기 때문에, 전체 흐름을 파악하기 위해서는 여러 로그를 조합해서 해석해야 한다.
메트릭은 시스템의 상태를 수치로 표현한다. CPU 사용률, 응답 시간, 에러율, 요청 수 같은 값들이 시간에 따라 어떻게 변하는지를 보여준다. 메트릭의 강점은 “이상이 발생했는가”를 빠르게 감지할 수 있다는 점이다. 특정 지표가 평소와 다르게 튀는 순간, 문제가 시작되었음을 알 수 있다. 하지만 메트릭만으로는 “왜 그런 일이 발생했는가”까지는 알기 어렵다.
트레이싱은 요청 단위의 흐름을 추적한다. 하나의 요청이 여러 서비스와 컴포넌트를 거치면서 어떻게 처리되는지를 시간 순서대로 보여준다. 특히 마이크로서비스 환경에서는 이 정보가 매우 중요하다. 어느 서비스에서 지연이 발생했는지, 어떤 호출이 병목이 되었는지를 한눈에 파악할 수 있기 때문이다. 트레이싱은 “어디에서 문제가 발생했는가”를 좁혀주는 역할을 한다.
실제 디버깅 상황을 떠올려보면 이 세 가지가 어떻게 함께 사용되는지 더 명확해진다. 먼저 메트릭을 통해 특정 시점에 에러율이 급증하거나 응답 시간이 증가한 것을 확인한다. 이로써 문제가 발생했다는 사실과 시점을 알 수 있다. 다음으로 트레이싱을 통해 어떤 요청 경로에서 지연이 발생했는지, 특정 서비스가 비정상적으로 느려졌는지를 확인한다. 마지막으로 해당 구간의 로그를 살펴보면서 실제로 어떤 예외가 발생했는지, 어떤 데이터가 문제였는지를 구체적으로 파악한다.
이 흐름이 자연스럽게 이어지지 않는다면 디버깅은 급격히 어려워진다. 로그가 부족하면 원인을 알 수 없고, 메트릭이 없으면 문제 발생 자체를 늦게 인지하게 되고, 트레이싱이 없으면 범위를 좁히는 데 시간이 오래 걸린다. 결국 세 가지는 대체 관계가 아니라 서로를 보완하는 관계다.
중요한 건 단순히 도구를 도입하는 것이 아니라, 어떤 정보를 남길 것인지에 대한 기준을 세우는 것이다. 로그를 과하게 남기면 노이즈가 되고, 부족하게 남기면 단서가 사라진다. 메트릭도 마찬가지로, 의미 있는 지표를 정의하지 않으면 숫자만 쌓일 뿐이다. 트레이싱 역시 핵심 경로를 중심으로 설계하지 않으면 오히려 분석이 더 복잡해질 수 있다.
그래서 좋은 관측 시스템은 “많이 남기는 시스템”이 아니라, “필요한 정보를 정확하게 남기는 시스템”이다. 장애가 발생했을 때, 최소한의 탐색으로 원인에 도달할 수 있는 구조를 만드는 것이 목표다.
결국 로그를 남긴다는 것은 단순히 기록을 쌓는 일이 아니다. 미래의 나, 혹은 다른 누군가가 문제를 해결할 수 있도록 단서를 남기는 일이다. 그 단서가 없다면, 아무리 큰 장애도 결국은 “아무 일도 없었던 것”처럼 지나가게 된다.