Loki — 로그를 색인하지 않는 로그 저장소 · 파서로 본문에서 값을 꺼낸다 · 실습
오류는 하나도 없는데 5xx 건수가 실제의 3분의 1이었다
목표
파드 안의 진짜 Loki 에서 네 가지 LogQL 파서를 직접 붙여 보고, 파싱 오류가 난 줄과 오류 없이 조용히 값을 못 꺼낸 줄을 각각 세어 진짜 5xx 건수를 구합니다.
왜 중요한가
Loki 는 본문을 색인하지 않는다. 그래서 본문 속 값으로 거르려면 질의할 때마다 파서로 꺼내야 하고, 파서를 잘못 고르면 숫자가 조용히 줄어든다. json 은 실패를 __error__ 라벨로 신고하지만 logfmt 는 신고하지 않는다 — 형식이 다른 줄을 만나면 아무 라벨도 만들지 않고 지나가고, 라벨이 없으면 뒤따르는 라벨 필터는 그 줄을 조용히 버린다. 대시보드에는 오류도 경고도 안 뜬다. 그래서 새 스트림을 질의하기 전에 늘 두 숫자를 먼저 재야 한다 — 파싱이 실패한 줄 수와, 실패하지도 않았는데 값이 안 나온 줄 수.
단계
1. /root/lk-parsers 에서 Loki 를 띄우고 date +%s 를 /root/lk-parsers/anchor.txt 에 적은 뒤 python3 /opt/lab/d5/gen.py parsers "$(cat anchor.txt)" 로 자료를 넣으세요. 그리고 기준 시각에서 과거 한 시간 동안 {app="mixed"} 와 {app="orders"} 가 각각 몇 줄인지 세어 /root/lk-parsers/01-boot.txt 에 mixed=<정수> 와 orders=<정수> 두 줄로 적으세요.
2. orders 스트림에서 status 가 500 인 줄이 몇 줄인지 logfmt 파서로 세세요. 질의는 /root/lk-parsers/02-logfmt.logql, 답은 /root/lk-parsers/02-logfmt.txt 에 lines=<정수> 로 적습니다.
3. mixed 스트림에 json 파서를 붙여, 파싱에 성공한 줄과 __error__ 라벨이 붙은 줄을 각각 세세요. 답은 /root/lk-parsers/03-json.txt 에 ok=<정수> 와 err=<정수> 두 줄로 적고, __error__ 의 실제 값 하나를 /root/lk-parsers/03-json-name.txt 에 한 줄로 적으세요.
4. mixed 스트림에 logfmt 파서를 붙였을 때 오류는 나지 않았는데 status 라벨이 만들어지지 않은 줄이 몇 줄인지 세세요. 질의는 /root/lk-parsers/04-silent.logql, 답은 /root/lk-parsers/04-silent.txt 에 lines=<정수> 로 적습니다.
5. 본문에 legacy 가 든 줄만 골라 pattern 파서로 상태 코드를 꺼내고, 그 값이 500 인 줄을 세세요. 질의는 /root/lk-parsers/05-pattern.logql, 답은 /root/lk-parsers/05-pattern.txt 에 lines=<정수> 로 적습니다. 질의에는 pattern 파서가 반드시 들어가야 합니다.
6. 같은 레거시 줄에서 regexp 파서로 걸린 시간(밀리초)을 꺼내, 1000 보다 큰 줄을 세세요. 질의는 /root/lk-parsers/06-regexp.logql, 답은 /root/lk-parsers/06-regexp.txt 에 lines=<정수> 로 적습니다. 질의에는 regexp 파서가 반드시 들어가야 합니다.
7. mixed 스트림의 줄을 형식 세 가지로 갈라 세어 /root/lk-parsers/tally.tsv 를 만드세요. 머리글 없이 세 줄이고 각 줄은 탭으로 나눈 두 칸 <형식><탭><줄수> 입니다. 형식 이름은 순서대로 json, legacy, logfmt 이고, 세 줄의 합은 1단계에서 센 mixed 전체 줄 수와 같아야 합니다.
8. mixed 스트림에서 상태 코드가 500 인 줄의 진짜 총 건수를 구해 /root/lk-parsers/08-total.txt 에 total=<정수> 로 적고, 그 다음 줄에 reason= 으로 시작하는 한 문장(공백 뺀 40자 이상)을 적으세요. 왜 파서 하나로는 이 숫자를 셀 수 없는지 자기 말로 씁니다.
참고
- 작업 디렉터리는
/root/lk-parsers입니다. Loki 는 1단계에서 직접 띄웁니다. - 자료 생성기는
/opt/lab/d5/gen.py이고parsers자료를 씁니다. 채점기는 이 파일을 읽지 않습니다. - 질의는 역따옴표로 감싸는 쪽이 안전합니다 — 큰따옴표 안에서는 역슬래시가 이스케이프로 해석됩니다.
- 흔한 실수:
since=1h로 재는 것. 시간이 흐르면 답이 달라져 재채점에서 떨어집니다.anchor.txt의 기준 시각으로start·end를 주세요. - 흔한 실수:
| __error__=""를 습관적으로 붙이는 것. 깨진 줄을 세기 전에 지우면 형식이 섞여 있다는 사실 자체가 안 보입니다. - [로그 질의와 파서](https://grafana.com/docs/loki/latest/query/log_queries/) · [LogQL 개요](https://grafana.com/docs/loki/latest/query/) · [라벨](https://grafana.com/docs/loki/latest/get-started/labels/) · [HTTP API](https://grafana.com/docs/loki/latest/reference/loki-http-api/)
단계 8개
- 형식이 섞인 스트림을 손에 쥔다
- 형식이 깔끔할 때는 logfmt 한 줄이면 된다
- json 파서는 실패를 신고한다
- 오류도 없이 아무것도 안 꺼낸 줄을 센다
- 자리가 고정된 줄에는 pattern 이 맞다
- 정규식 파서로 숫자를 꺼내 비교한다
- 응용 ① — 형식별로 몇 줄인지 표로 만든다
- 응용 ② — 진짜 5xx 건수와 그 사실을 남긴다