Loki — 로그를 색인하지 않는 로그 저장소 · 질의 시점에 이름을 다시 붙인다 · 이론
level="error" 가 0건을 돌려준 이유
한 줄 요약
파서가 꺼낸 이름이 이미 있는 스트림 라벨과 부딪히면 Loki 는 조용히 _extracted 를 붙여 밀어낸다. label_format·line_format·keep·drop 은 그 뒤를 정리하는 도구이고, 넷 다 응답만 바꿀 뿐 색인은 건드리지 않는다.
왜 이게 필요했나
수집기가 파드마다 level 라벨을 붙이고 있었다. 값은 전부 info 였다 — 수집기 입장에서는 그 파일이 애플리케이션의 표준 출력이니 info 로 본 것이다. 그런데 애플리케이션은 본문에 자기 수준을 level=error 로 함께 찍었다.
조사하던 사람이 {app="payment"} | logfmt | level="error" 를 던졌고 결과는 0건이었다. "오류가 하나도 없네" 라고 보고했고, 실제로는 그 시간에 30건이 있었다. 파서가 꺼낸 level 이 스트림 라벨 level 과 부딪혀 level_extracted 로 이름이 바뀌어 있었기 때문이다. 에러가 없다고 말한 근거가 사실은 "이름이 부딪혔다" 였다.
어떻게 동작하나
파서가 라벨을 만들 때 이미 같은 이름이 있으면, Loki 는 나중에 꺼낸 쪽에 _extracted 접미를 붙인다. 원래 라벨은 그대로 남는다. 경고도 오류도 없다. 그래서 새 스트림을 처음 질의할 때는 결과 하나를 펼쳐 metric(또는 stream) 의 키 목록을 눈으로 보는 습관이 필요하다.
정리하는 도구는 넷이다.
| 문법 | 하는 일 |
| --- | --- |
| label_format 새이름=기존라벨 또는 label_format 이름=\{{.필드}}\`` | 라벨을 다시 이름 붙이거나 템플릿으로 만든다 |
| line_format \{{.a}} {{.b}}\`` | 줄의 본문 자체를 다시 쓴다 |
| keep a, b | 적은 라벨만 남긴다 |
| drop a, b | 적은 라벨을 버린다 |
템플릿은 Go 의 text/template 이다. {{.필드}} 로 값을 넣고, {{.a | trim}} 같은 파이프도 쓸 수 있다. line_format 은 본문을 통째로 갈아 끼우므로 그 뒤의 줄 필터는 새 본문을 본다 — 순서가 곧 의미다.
네 문법 모두 질의 결과에만 작용한다. 색인에 저장된 스트림은 한 글자도 바뀌지 않는다. 그래서 label_format 으로 라벨을 늘려도 스트림 수는 늘지 않고 비용도 늘지 않는다. 카디널리티가 걱정되는 값은 라벨로 색인하지 말고 본문에 두었다가 질의할 때 이렇게 꺼내 쓰면 된다 — 이것이 "색인하지 않는다" 는 설계가 실제로 이득이 되는 자리다.
지표 질의에서는 이 도구들이 더 중요해진다. sum by (...) 에 쓰고 싶은 이름이 본문에만 있으면 label_format 으로 먼저 만들어 줘야 하고, 값이 제각각인 라벨이 남아 있으면 계열이 쪼개지므로 keep 이나 drop 으로 정리해야 한다.
현장에서 만나는 모습
이름 충돌은 level 에서 가장 자주 난다. 수집기·런타임·애플리케이션이 저마다 '수준' 을 말하고 싶어 하기 때문이다. 팀 규약으로 "수집기가 붙이는 라벨에는 접두어를 둔다"(예: k8s_) 를 정해 두면 이 사고 자체가 사라진다.
두 번째는 대시보드의 읽기 어려운 로그 패널이다. 줄이 200자짜리 JSON 이면 사람이 훑을 수 없다. line_format 으로 필요한 네다섯 칸만 남기면 같은 패널이 갑자기 쓸모 있어진다. 다만 그 패널에서 본문 검색을 하려는 사람이 있다면, line_format 을 줄 필터 뒤에 두어야 한다고 주석을 달아 두는 편이 친절하다.
세 번째는 "라벨을 추가했는데 왜 비용이 그대로인가" 라는 질문이다. 정상이다. 질의 시점의 라벨은 저장되지 않는다.
다음 실습에서 할 것
스트림 라벨 level 과 본문의 level= 이 일부러 어긋나 있는 자료를 파드의 Loki 에 넣고, level="error" 가 0건을 돌려주는 것을 직접 본다. _extracted 이름을 찾아 세고, label_format 으로 덮어써 원하는 이름으로 거른 뒤, line_format 으로 줄을 다시 쓰고, keep 으로 계열을 묶어 수준별 건수를 낸다. 마지막에는 라벨을 바꿔도 색인의 스트림 수가 그대로인 것을 확인한다.