Loki — 로그를 색인하지 않는 로그 저장소 · 질의가 얼마를 읽는가 · 실습
같은 답을 내는 두 질의가 하나는 4분, 하나는 2초였다
목표
Loki 응답에 실려 오는 stats.summary 를 읽어 질의가 실제로 몇 줄·몇 바이트를 읽었는지 재고, 무엇이 그 숫자를 줄이고 무엇이 줄이지 않는지 직접 확인합니다.
왜 중요한가
Loki 의 색인에는 라벨 조합과 청크의 시간 범위만 들어 있다. 본문은 색인되지 않는다. 그래서 질의는 늘 같은 순서로 돈다 — 선택자가 열 청크를 고르고, 시간 구간이 그중 겹치는 것만 남기고, 남은 것을 전부 읽어 필터를 적용한다. 앞의 두 단계만 읽는 양을 정하고 뒤는 이미 읽은 것을 버리는 일이다. 이 순서를 모르면 줄 필터를 앞에 두거나 limit 을 줄이면서 질의가 빨라지기를 기다리게 된다. 비용이 바이트로 매겨지는 저장소에서는 이 차이가 곧 청구서다.
단계
1. /root/lk-filters 에서 Loki 를 띄우고 date +%s 를 /root/lk-filters/anchor.txt 에 적은 뒤 python3 /opt/lab/d5/gen.py filters "$(cat anchor.txt)" 로 자료를 넣으세요. 그리고 {app=~"edge|cart|ship|batch"} 를 기준 시각에서 과거 한 시간 구간으로 질의해 응답의 stats.summary 에서 읽은 줄 수와 바이트를 /root/lk-filters/01-base.txt 에 processed=<정수> 와 bytes=<정수> 두 줄로 적으세요.
2. 같은 한 시간 구간에서 네 스트림 전체를 대상으로 본문에 SETTLE-LATE 가 든 줄을 찾는 질의를 /root/lk-filters/02-marker.logql 에 쓰고, 결과 줄 수와 읽은 줄 수를 /root/lk-filters/02-marker.txt 에 lines=<정수> 와 processed=<정수> 두 줄로 적으세요.
3. 같은 답(같은 줄)을 내면서 스트림 선택자만 좁힌 질의를 /root/lk-filters/03-stream.logql 에 쓰고, 결과 줄 수와 읽은 줄 수를 /root/lk-filters/03-stream.txt 에 lines=<정수>·processed=<정수> 로 적으세요. 그리고 /root/lk-filters/03-ratio.txt 에 ratio=<소수 둘째 자리> 한 줄로 2단계 대비 읽은 줄 수의 비율을 적습니다.
4. 3단계와 같은 질의를 구간만 30분(기준 시각에서 과거 1800초)으로 바꿔 던지세요. 결과 줄 수와 읽은 줄 수를 /root/lk-filters/04-window.txt 에 lines=<정수>·processed=<정수> 로 적고, /root/lk-filters/04-note.txt 에 tradeoff= 로 시작하는 한 문장(공백 뺀 40자 이상)을 적어 구간을 좁힐 때 무엇을 얻고 무엇을 잃는지 자기 말로 쓰세요.
5. 네 스트림 전체·한 시간 구간에서 두 질의를 던져 읽은 줄 수를 견주세요. 하나는 필터가 전혀 없는 {app=~"edge|cart|ship|batch"}, 다른 하나는 거기에 줄 필터 두 개를 더한 질의입니다. 결과를 /root/lk-filters/05-linefilter.txt 에 네 줄로 적습니다 — plain_processed=, plain_lines=, filtered_processed=, filtered_lines=.
6. 네 스트림 전체·한 시간 구간에 | logfmt | status="500" 을 붙인 질의를 던져 세 숫자를 /root/lk-filters/06-parser.txt 에 적으세요 — processed=<읽은 줄 수>, post_filter=<필터를 통과해 남은 줄 수>, lines=<결과 줄 수>. 세 숫자를 1단계 기준선과 견주어, 무엇이 같고 무엇이 달라졌는지 보세요.
7. 지금까지 잰 것을 /root/lk-filters/cost.tsv 로 정리하세요. 머리글 없이 네 줄이고 각 줄은 탭으로 나눈 세 칸 <방법><탭><읽은줄수><탭><결과줄수> 입니다. 방법 이름은 순서대로 all(2단계), stream(3단계), window(4단계), parser(6단계)입니다.
8. /root/lk-filters/08-budget.logql 에 질의를 하나 쓰세요. 조건은 셋입니다 — (1) 기준 시각에서 과거 한 시간 구간으로 던졌을 때 2단계와 똑같은 줄을 돌려줄 것, (2) 읽은 줄 수가 1단계 기준선의 3분의 1 이하일 것, (3) limit 에 기대지 말 것. 그리고 /root/lk-filters/08-budget.txt 에 processed=<정수> 한 줄로 그 질의가 읽은 줄 수를 적으세요.
참고
- 작업 디렉터리는
/root/lk-filters입니다. Loki 는 1단계에서 직접 띄웁니다. - 자료 생성기는
/opt/lab/d5/gen.py이고filters자료를 씁니다. 채점기는 이 파일을 읽지 않습니다. - 통계는
curl ... | jq '.data.stats.summary'로 봅니다. 이 실습이 보는 칸은totalLinesProcessed·totalBytesProcessed·totalPostFilterLines입니다.execTime은 같은 질의도 돌릴 때마다 달라지니 판단 근거로 쓰지 마세요. - 정답지가 만드는
cost.sh는 편의용 도우미입니다. 직접curl로 던져도 됩니다. - 흔한 실수:
since=1h로 재는 것. 시간이 흐르면 답이 달라져 재채점에서 떨어집니다. - 흔한 실수: 싸진 질의가 답까지 바꿨는데 모르고 넘어가는 것. 비용을 줄일 때마다 결과 줄 수를 함께 확인하세요.
- [LogQL 개요](https://grafana.com/docs/loki/latest/query/) · [로그 질의](https://grafana.com/docs/loki/latest/query/log_queries/) · [라벨](https://grafana.com/docs/loki/latest/get-started/labels/) · [구조](https://grafana.com/docs/loki/latest/get-started/architecture/) · [HTTP API](https://grafana.com/docs/loki/latest/reference/loki-http-api/)
단계 8개
- 네 스트림을 넣고 기준선을 잰다
- 다섯 줄을 찾으려고 몇 줄을 읽었나
- 선택자를 좁히면 읽는 양이 준다
- 구간을 좁히면 읽는 양은 줄고 답도 줄어든다
- 줄 필터를 더해도 읽는 양은 그대로다
- 파서를 붙여도 읽는 양은 그대로다
- 응용 ① — 네 방법의 비용표
- 응용 ② — 예산 안에서 같은 답을 내는 질의