Envoy 내부 구조 · 사고가 난 뒤에 읽을 글 · 실습
로그 형식을 설계하고 오류만 따로 모은다
목표
접근 로그의 형식·모양·싱크·필터 네 가지를 차례로 설계하고, 각각이 실제 로그 파일에 어떻게 나타나는지 확인한다.
왜 중요한가
접근 로그는 관측 설정 중에서 유일하게 되돌릴 수 없는 부분이다. 사고가 난 뒤에 '업스트림 주소도 남길걸' 이라고 깨달아도 그 사고의 로그에는 없다. 그래서 형식을 고르는 기준은 취향이 아니라 질문이다 — 새벽 세 시에 이 한 줄만 보고 원인을 좁힐 수 있는가. 여기에 더해 파일 싱크가 버퍼에 모았다 비운다는 사실, 값이 없는 자리에 무엇이 찍히는지, 필터를 어느 층에 적어야 하는지는 문서를 읽어서는 잘 남지 않고 한 번 겪어야 남는다.
단계
1. 업스트림 둘을 띄우세요 — 8091 는 ok, 8092 는 fail. /root/envd-log/log-text.yaml 에 /ping(direct_response pong), /bad(클러스터 bad), /(클러스터 good) 세 라우트와 파일 접근 로그 싱크를 두세요 — 경로는 /root/envd-log/access.log, 형식은 %RESPONSE_CODE%|%REQ(:PATH)%|%UPSTREAM_HOST% 입니다. --file-flush-interval-msec 200 을 붙여 띄우고 /hello 를 한 번 요청한 뒤 로그가 남을 때까지 기다려 확인하세요.
2. /root/envd-log/log-wide.yaml 을 만드세요 — 로그 경로는 /root/envd-log/wide.log, 형식은 여덟 칸입니다: %RESPONSE_CODE%|%REQ(:METHOD)%|%REQ(:PATH)%|%PROTOCOL%|%DURATION%|%UPSTREAM_HOST%|%RESPONSE_FLAGS%|%BYTES_SENT%. 그 설정으로 띄운 뒤 /hello·/ping·/bad/x 를 한 번씩 요청해 세 줄이 남는 것을 확인하세요.
3. /root/envd-log/log-miss.yaml 을 만드세요 — 경로는 /root/envd-log/miss.log, 형식은 %RESPONSE_CODE%|%REQ(:PATH)%|%UPSTREAM_HOST%|%REQ(X-TENANT)% 입니다(마지막 칸은 요청 헤더 x-tenant). 띄운 뒤 /ping 과 /hello 를 헤더 없이 한 번씩 요청하고, /root/envd-log/03-missing.txt 에 ping_upstream=(/ping 줄의 세 번째 칸), ping_tenant=(네 번째 칸), hello_tenant= 세 줄을 적으세요.
4. /root/envd-log/log-json.yaml 을 만드세요 — 경로는 /root/envd-log/access.json, 형식은 json_format 이고 열쇠는 code·path·upstream·flags·duration_ms 다섯 개입니다. 띄운 뒤 /hello 와 /bad/x 를 한 번씩 요청하고, jq 로 읽히는지 확인하세요.
5. /root/envd-log/log-err.yaml 을 만드세요 — 싱크 하나만 두되 filter.status_code_filter 로 500 이상만 남기고(비교 연산자 GE, 값 500), 경로는 /root/envd-log/errors.json, 열쇠는 code·path·upstream·flags 입니다. 띄운 뒤 /hello 두 번과 /bad/x 한 번을 요청하고 /root/envd-log/05-filter.txt 에 lines=(errors.json 의 줄 수)와 codes=(그 줄들의 code 값을 공백으로) 두 줄을 적으세요.
6. /root/envd-log/log-two.yaml 을 만드세요 — 싱크 두 개입니다. 하나는 텍스트로 모든 요청을 /root/envd-log/all.log 에(형식 %RESPONSE_CODE%|%REQ(:PATH)%|%UPSTREAM_HOST%), 다른 하나는 JSON 으로 500 이상만 /root/envd-log/only5xx.json 에 남깁니다. 띄운 뒤 /hello 세 번과 /bad/x 두 번을 요청하고 /root/envd-log/06-two.txt 에 all=·err=·ratio_ok=(all 과 err 의 차) 세 줄을 적으세요.
7. /root/envd-log/log-reqid.yaml 을 만드세요 — 경로는 /root/envd-log/reqid.log, 형식은 %RESPONSE_CODE%|%REQ(:PATH)%|%REQ(X-REQUEST-ID)% 입니다. 띄운 뒤 /given 은 헤더 x-request-id: envd-777 을 붙여, /none 은 아무 헤더 없이 요청하세요. /root/envd-log/07-reqid.txt 에 given=(첫 요청 줄의 세 번째 칸), none_len=(둘째 요청 줄 세 번째 칸의 글자 수), none_is_given=(그 값이 envd-777 과 같으면 yes, 아니면 no) 세 줄을 적으세요.
8. /root/envd-log/08-report.md 에 fields=(2단계 형식의 칸 수), missing_marker=(3단계에서 값이 없을 때 찍힌 문자), all_lines=·error_lines=(6단계의 두 값) 네 줄을 적고, 그 아래 배운 것을 네 줄 이상 적으세요.
참고
- Envoy 를 띄울 때
--file-flush-interval-msec 200을 함께 주세요. 기본값은 10초라 요청 직후에는 로그가 비어 있는 것처럼 보입니다. - 그래도 고정
sleep은 쓰지 마세요.줄 수가 N 이상이 될 때까지도는 루프로 기다립니다. - 다시 띄우기 전에는
pkill -x envoy로 정리하고, 기동은/ready가 LIVE 를 돌려줄 때까지 도는 루프로 기다리세요. - 칸을 세거나 뽑을 때는
awk -F'|'를, JSON 을 확인할 때는jq -c .를 쓰세요. - Envoy 는 로그 파일에 덧붙입니다. 형식을 바꿔 다시 띄우기 전에 그 파일을 지우세요 — 안 그러면 옛 형식의 줄과 새 형식의 줄이 한 파일에 섞입니다.
- 흔한 실수 — 싱크의
filter를typed_config안에 적는 것. 그 자리에는 없는 필드라 설정이 통째로 거절됩니다.name과 같은 층에 적습니다.
단계 8개
- 로그를 파일로 남기고, 늦게 나오는 이유를 안다
- 사고가 난 뒤에 필요한 값을 미리 정한다
- 값이 없을 때 무엇이 찍히는지 알아 둔다
- 기계가 읽을 형식으로 바꾼다
- 오류만 따로 모은다
- 싱크 두 개를 함께 쓴다
- 요청 아이디는 누가 만드나
- 로그 설계 메모를 남긴다