Loki — 로그를 색인하지 않는 로그 저장소 · 한도와 잘린 답 · 실습
사고 시작 시각을 40분 늦게 보고했다
목표
Loki 의 질의 한도를 직접 넘어 보며 조용히 잘리는 경우와 400 으로 거절되는 경우를 가르고, 한도 안에서 넓은 구간을 빠짐없이 훑는 방법을 만듭니다.
왜 중요한가
로그 질의의 결과 수는 세 손잡이가 정한다. 요청의 limit 은 조용히 자르고, 서버의 max_entries_limit_per_query 와 max_query_length 는 400 으로 거절한다. 거절은 바로 보이지만 조용히 잘린 답은 '이게 전부' 처럼 보인다. 게다가 direction 이 무엇이 잘려 나갈지를 정해서, 기본값인 backward 로 사고의 시작을 찾으면 정확히 찾고 싶은 것이 잘려 나간다. 넓은 구간을 훑어야 할 때의 답은 한도를 올리는 것이 아니라 구간을 잘라 여러 번 묻고 합치는 것이다 — 각 조각이 한도보다 작다는 것이 합계를 믿을 수 있게 만든다.
단계
1. /root/lk-query-limits 에서 Loki 를 띄우고 date +%s 를 /root/lk-query-limits/anchor.txt 에 적은 뒤 python3 /opt/lab/d5/gen.py querylimits "$(cat anchor.txt)" 로 자료를 넣으세요. 그리고 {app="gateway"} 를 기준 시각에서 과거 두 시간 구간으로 로그 질의해 전체 줄 수를 /root/lk-query-limits/01-total.txt 에 total=<정수> 한 줄로 적으세요. limit 은 5000 으로 주고, 돌려받은 수가 그 값보다 작은지 반드시 확인하세요.
2. 같은 두 시간 구간을 limit=100, direction=backward 로 로그 질의해 돌려받은 줄 수와 그중 가장 이른 줄의 나노초 타임스탬프를 /root/lk-query-limits/02-cut.txt 에 두 줄로 적으세요 — returned=<정수> 와 oldest_ts=<나노초>. 응답 어디에도 '잘렸다' 는 표시가 없다는 것을 직접 확인하세요.
3. 같은 질의를 limit=6000 으로 던져 보세요. 응답의 상태 코드와 본문에 적힌 한도값, 그리고 서버 /config 에서 읽은 그 설정의 값을 /root/lk-query-limits/03-entries.txt 에 세 줄로 적으세요 — code=<정수>, limit_in_body=<정수>, limit_in_config=<정수>.
4. 같은 질의를 60일 구간으로 던져 보세요. 상태 코드와 서버 /config 의 구간 길이 한도를 /root/lk-query-limits/04-length.txt 에 세 줄로 적습니다 — code=<정수>, param=<설정 이름>, value=<서버가 찍은 값 그대로>.
5. 같은 질의를 두 시간 구간과 30분 구간으로 각각 던져 응답 통계의 splits 를 재고, 서버의 조각 간격 설정도 읽어 /root/lk-query-limits/05-splits.txt 에 세 줄로 적으세요 — splits_2h=<정수>, splits_30m=<정수>, interval=<서버가 찍은 값 그대로>.
6. limit 을 50·500·5000 세 번 주어 같은 질의를 던지고, 결과를 /root/lk-query-limits/detect.tsv 에 머리글 없이 세 줄, 탭으로 나눈 세 칸 <limit><탭><returned><탭><truncated> 로 적으세요. truncated 는 yes 또는 no 이고, 판정 기준은 1단계에서 구한 진짜 총계입니다.
7. /root/lk-query-limits/scan.sh 를 만들어 두 시간 구간을 30분씩 네 조각으로 나눠 각각 질의하고 합계를 내세요. 각 조각은 limit=5000 으로 던지고, 조각의 결과 수가 limit 과 같으면 INCOMPLETE 를 함께 출력해야 합니다. 스크립트를 돌린 결과를 /root/lk-query-limits/07-scan.txt 에 sum=<정수> 와 chunks=4 두 줄로 적습니다. 합계는 1단계의 총계와 같아야 합니다.
8. 두 시간 구간에서 status=500 인 줄 중 가장 최근 50건을 가져오는 질의를 설계해 /root/lk-query-limits/08-latest.txt 에 세 줄로 적으세요 — returned=<정수>, newest_ts=<나노초>, oldest_ts=<나노초>. 50건보다 적게 있다면 있는 만큼만 나오면 됩니다.
참고
- 작업 디렉터리는
/root/lk-query-limits입니다. Loki 는 1단계에서 직접 띄웁니다. - 자료 생성기는
/opt/lab/d5/gen.py이고querylimits자료를 씁니다. 채점기는 이 파일을 읽지 않습니다. - 400 응답의 본문을 버리지 마세요 — 어떤 한도를 얼마나 넘겼는지 숫자까지 적혀 나옵니다.
curl -w '\n%{http_code}'로 본문과 코드를 함께 받으면 편합니다. - 줄 수를 정확히 세야 할 때는 로그 질의 대신
sum(count_over_time(...))지표 질의를 쓰세요. 지표 질의에는 limit 이 적용되지 않습니다. - 흔한 실수: 구간을 쪼갤 때 경계를 겹치거나 빠뜨리는 것. 왼쪽 끝 포함·오른쪽 끝 제외로 맞추면 합계가 정확해집니다.
- [HTTP API](https://grafana.com/docs/loki/latest/reference/loki-http-api/) · [설정 문서](https://grafana.com/docs/loki/latest/configure/) · [요청 검증과 속도 제한](https://grafana.com/docs/loki/latest/operations/request-validation-rate-limits/) · [로그 질의](https://grafana.com/docs/loki/latest/query/log_queries/)
단계 8개
- 두 시간치를 넣고 진짜 총계를 구한다
- limit 은 아무 말 없이 자른다
- 서버 한도는 대놓고 거절한다
- 구간이 너무 길어도 거절한다
- 질의는 시간 조각으로 쪼개져 돈다
- 잘렸는지 알아채는 법
- 응용 ① — 구간을 쪼개 빠짐없이 센다
- 응용 ② — 가장 최근 오류 50건을 정확히 가져온다