Loki — 로그를 색인하지 않는 로그 저장소 · 로그를 숫자로 바꾼다 · 이론
p50 과 p95 가 같게 나오는 이유
한 줄 요약
LogQL 의 지표 질의는 로그를 숫자로 바꾼다. 그런데 파서가 만든 라벨이 그대로 계열을 가르기 때문에, 라벨을 정리하지 않으면 분위수와 합계가 조용히 무의미해진다.
왜 이게 필요했나
어떤 팀이 지연 히스토그램을 아직 계측하지 못한 서비스의 p95 를 Loki 로 재려 했다. 로그에는 dur_ms=... 가 찍혀 있으니 quantile_over_time(0.95, {app="checkout"} | logfmt | unwrap dur_ms [5m]) 이면 될 것 같았다. 그래프는 잘 그려졌고 숫자도 그럴듯했다.
문제는 p50 과 p95 가 거의 같게 나온다는 것이었다. 로그에는 분명히 1.5초짜리 꼬리가 있었는데 p95 가 60밀리초대에 머물렀다. 원인은 로그에 함께 찍히던 bytes=... 필드였다. 그 값이 줄마다 달라서, logfmt 가 만든 bytes 라벨이 줄 하나마다 계열 하나를 만들어 버렸다. 계열마다 표본이 한 개뿐이니 어느 분위수를 물어도 그 줄의 값이 그대로 나온다.
어떻게 동작하나
LogQL 의 지표 질의는 두 갈래다.
로그 범위 집계는 줄을 센다. count_over_time, rate, bytes_over_time, bytes_rate 가 여기 속한다. 파서가 필요 없고, 필요하다면 필터로 셀 줄을 고른다.
unwrap 범위 집계는 줄에서 꺼낸 숫자를 다룬다. | unwrap <라벨> 로 어느 값을 쓸지 정한 뒤 avg_over_time, max_over_time, quantile_over_time, sum_over_time, rate_counter 를 건다. 값이 단위가 붙은 문자열이면 duration_seconds(...) 나 bytes(...) 로 감싸 변환할 수 있다.
두 갈래 모두 계열의 정체성은 라벨이 정한다. 스트림 라벨뿐 아니라 그 질의에서 파서가 만든 라벨까지 전부 포함된다. 그래서 unwrap 을 쓸 때는 거의 언제나 라벨을 정리해야 한다 — | keep <쓸 라벨> 로 남길 것만 남기거나, | drop <버릴 라벨> 로 값이 제각각인 필드를 떼어 낸다. 아니면 바깥에 sum by (...)·max(...) 같은 집계를 둘러 계열을 묶는다.
여기서 프로메테우스와 다른 점이 하나 있다. 프로메테우스의 histogram_quantile 은 미리 버킷으로 요약된 자료에서 분위수를 추정하지만, Loki 의 quantile_over_time 은 원본 값을 전부 훑는다. 그래서 더 정확한 대신 훨씬 비싸다. 넓은 구간에 걸면 읽는 양이 그대로 비용이 된다.
마지막으로, 로그로 지표를 만드는 일은 임시 방편이라는 것을 잊지 않는 편이 좋다. 같은 숫자를 지표로 내보내면 한 줄이 몇 바이트로 줄고 질의도 상수 시간에 가까워진다. 로그 기반 지표는 계측이 없거나 과거를 되짚어야 할 때 쓰는 도구다.
현장에서 만나는 모습
가장 자주 나는 사고가 위의 '계열 폭발' 이다. 증상이 특이하다 — 오류도 없고 그래프도 그려지는데 p50 과 p99 가 붙어 다닌다. 의심되면 계열 수부터 센다. 계열이 줄 수와 비슷하면 답은 나왔다.
두 번째는 대시보드 비용이다. quantile_over_time 패널 하나를 24시간 구간으로 걸어 두고 30초마다 새로 고치면, 그 패널 혼자서 하루치 로그를 매 30초 다시 읽는다. 로그 기반 분위수 패널은 구간을 짧게 두고, 긴 구간이 필요하면 레코딩 규칙으로 미리 접어 두는 편이 낫다.
세 번째는 단위다. dur=1.5s 와 dur_ms=1500 이 같은 서비스에서 섞여 나오면 unwrap 은 둘을 그대로 더한다. 필드 이름에 단위를 박아 두는 습관이 이 사고를 막는다.
다음 실습에서 할 것
두 서비스의 로그를 파드의 Loki 에 넣고, 줄을 세는 질의와 값을 꺼내는 질의를 각각 만든다. unwrap 으로 p95 를 구하려다 계열이 줄 수만큼 쪼개지는 것을 직접 보고 계열 수를 센 뒤, 라벨을 정리해 p50 과 p95 가 갈라지는 것을 확인한다. 마지막에는 같은 숫자를 지표로 내보냈을 때와 견주어 무엇을 고를지 근거와 함께 적는다.