어?
야근 시작 5분전 나온 한마디
개요
- 프로그래머는 사실 프로그래밍을 하는 시간보다 뭔가 터지면 수습하는게 절반 이상
- 이슈 대처도 오래걸리지만, 더 오래걸리는 것은 원인 분석 및 재발 방지 대책 수립
- 이런 이슈와 관련된 사이클이 비효율적이면 다른 프로젝트도 같이 끌고 내려가는 데스 스파이럴이 만들어짐
- 억까와 무한 츠쿠요미로 인한 모두의 사기저하로 이어지면서 컴퓨터만 보면 하기 싫어지면서 짜증이 남
필요성
- 실수로 부터 배운다지만, 뭘 잘못했는지 모르면 그건 그냥 멍청이다.
- 이슈 대처를 하고 배운게 재시작 뿐이라면 현자타임이 온다.
- 내일 서버가 터지지 않도록 새벽기도를 드리게 되면서 수면 장애가 온다.
- 자기 자신을 믿을수 없게 되면서
if (true) { return }
같은 Constant코드도 터질수 있다면서 FBI가 자기를 감시한다고 믿는 사람들처럼 변한다
(실제로 감시 당한 분도 있지만, 대부분은 아니었다)
원인
- 사실, 이슈 대응이 오래 걸리는 원인은 많지 않음.
대표적으로 아래 부분이 거의 9할 이상을 차지
- 어디까지 영향을 받았는지 몰라서
- 어디가 문제인지 몰라서
- 고쳤다고 생각했는데 또 터져서
- 당연한 이야기지만, 왜 이게 해결이 안되는지 고민
-> 이슈 대응하느라 시간이 없어서...
개선 방안
많이 남겨도 모르던데...
- 무작정 로그를 다 남기면 서버가 터진다.
- I/O는 프로그램을 느리게 만드는 제 1 악성 민원자
- 특히 Network I/O와 File I/O는 컴이 할일도 못하게 만드는 발목잡기 세계 챔피언이다
- I/O를 잘못쓰게되면 모든 스레드가 한 두개의 리소스(파일/ConnPool)를 위해 대기를 하게 되면서 웹서버가 터지는 대환장 쇼 발생
- 그렇다고 로그를 적게 남기면 뭐가 터졌는지 모름
- 자바의 긴 스택트레이스를 보고 모두가 왜 이슈가 터졌는지 아는것도 아니다.
- 비동기 프로그래밍에서 완전한 스택트레이스를 볼수있는것도 아니고
- 로그를 이상하게 남기면 상형문자보다 가독성이 떨어진다. 적어도 상형 문자는 상상이라도 가능하지만
1
이라는 로그는 길거리에 떨어진 쓰레기보다 못함.
- 로그는 읽고 이슈에 대한 정보를 추론할 수 있어야 로그. 그냥 아무렇게나 로그를 남기면 환경파괴범으로 기소를 받아야 한다.
- 로그를 남길때 다음과 같은 기준으로 남기도록 하자
- 주요 행동의 시작 끝 (요청 시작, 끝)
- 주요 작업 지점 (파싱, 외부 요청, 조건 분기)
- 예외 처리
- 그리고 로그의 실행 지점/과정을 더 정확히 알 수 있도록 로그 라이브러리를 개조하자
- Function Name
- Call Tree
- Thread Name
- 그리고 로그가 뭘 처리하다 터졌는지 알 수 있도록 기록을 남기도록 하자
- 키 (제발 키좀 기록하자)
- 넣을 데이터 (소량)
- 토큰 뒤 5자리 (달라졌는지 알수는 있게)
- SHA 뒤 5자리 (보안상 민감하지 않으면 앞자리)
MSA라서 로그 읽기 힘들어서 적게 남기는데...
- MSA는 배포와 관리가 쉬워지는거지 서버가 안터지는게 아니다
- 제 1 법칙,
클라이언트를 믿지 마라
가 천문학적으로 스케일이 커지는게 MSA
- 여기서 로그를 적게 남기는건 스스로 눈을 감는것과 같다
- MSA가 로그 관리가 힘든건 알지만, 자기만 힘든건 아니다. 모두가 평등하게 화났기 때문에, 솔루션도 존재
- fluent-bit을 이용한 Log Parsing
- fluent-bit to Kafka 를 이용한 Log Consolidation
- kafka에서 로그를 빼내와서 적재하는 Log Storage
- Log Storage에서 이슈를 분석하는 Cloudwatch / Elastic Search 를 이용한 Log Aggregation
- 여기서 중요한건, MSA같이 여러 서비스에서 로그를 통합하는 경우, 한줄 한줄이 매우 중요해진다
- 로그 정규화로는 안됨. 모든 로그가 Document가 되어야 한다.
- 다음과 같은 정보가 없으면 MSA로그는 사실상 쓰레기에 돈낭비라고 봐야한다
- 그룹화에 사용되는 키
Trace ID
X-AMZ-Trace-Id, Request-Id, 사용자 ID 등 로그를 묶을 수 있는 키 없이는 로그는 쓰레기.
로그가 어디서, 어떻게 와서, 어떤 사용자의 어떤 리퀘스트인지 어디서든 추적을 할 수 있어야 한다
- Standard Timestamp
UTC시간 또는 UNIX Timestamp로 찍은게 아닌 로그는 쓰레기. 타임존 없이 어떻게 로그의 시간을 판별할 것인지?
- Pre-defined Event ID
로그를 중구난방으로 찍으면, 로그 그룹화 및 탐색이 어려워진다.
이벤트 기록을 정규화 하여 특정 이슈 기준으로 로그를 탐색할 수 있도록 해야한다.
- Event Context
로그에 대한 정보를 JSON으로 기록한다. 이벤트 내 특정 조건만 검색할때 도움이 된다.
로그 남기면 성능 떨어지는데...
- 물론 로깅이라는 행위 자체가 성능에 영향을 준다.
- 하지만 안하고 서버가 터지면 면접에 떨어진 취준생 같은 느낌을 받게 된다. 왜 떨어졌는지 아무도 안알려주는 그 느낌을 느끼게 된다.
- 로그가 Thorughput을 낮춘다면, 로그를 더 컴팩트하게 남기면된다.
- Messagepack같은 바이너리 기반 로그를 남겨보자.
- 물론 바이너리 기반을 하게된다면 로그를 바로 읽을 수 없다. (특히, 바이너리 포맷을 정하지 않으면, 이게 무슨 로그인지 영영 알수 없는 경우도 생김)
저장할데가...
- .gz는 괜히 나온게 아니다. 기간이 지났으면 .gz로 압축해서 저장하도록 하자.
- 압축 알고리즘은 반복문구를 최대한 압축해준다. 로그는 반복되는게 많으므로 500메가짜리 로그가 잘 압축하면 20메가까지 낮아지는 경우도 많음.
- AWS S3는 1기가에 0.03달러다. 2022년이 강달러지만, 30원이 없어서 50일 어치 로그를 저장 못하는 건...
다른 의미로 걱정을 해야할 때인듯 하다.
생각
- 로그를 잘 짜면, 로그 스트림을 실시간 데이터 스트림처럼 활용해서 다음과 같은 용도로도 사용이 가능하다
- Kafka 스트림에서 특정 메세지만 분리해서 사용자 세션 분석도 가능
- 실시간 추천 등 여러가지 이벤트를 넣는데에도 좋음
- 로그 분석을 해서 특정 시퀀스에 맞으면 웹소켓을 통한 추천을 한다던가 여러가지로 유용한 케이스가 많음
- 메트릭으로도 변환 가능
- 로그가 잘 연결된다면 성능 문제도 감지가 가능
- 특정 이벤트간의 타임 델타가 특정 시간 이상인경우 검색
- 노드간 응답속도가 느린경우 검색
- 파싱 실패가 많이 일어나는 구간 검색 등.
- 유용한 로그에서 자신의 실수를 돌아보며 실력 향상 가능
- 실제로 오랫동안 내가 맞다고 생각한게 로그 기록을 보다가 틀렸다는 것을 깨달은게 한두번이 아니었다.
- 여러 서비스가 유기적으로 통신하면서 발생하는 오류에 대한 케이스를 많이 배울 수 있었다.
- 이렇게 좋은데 왜 안할까?
- 이 부분은 계속 연구중이다. 다른 분들에게도 제대로 추천하고 도입할 수 있도록 확실하게 어필 가능한 부분이 무엇인지 고민해보자.