HAProxy HTTP 로그: 타이머와 종료 상태
HAProxy 로그 한 줄은 웬만한 접근 로그보다 많은 것을 말합니다. 요청이 큐에서 얼마나 기다렸는지, TCP 연결에 얼마나 걸렸는지, 서버가 얼마나 생각했는지, 그리고 네 글자로 누가 어느 단계에서 연결을 끝냈는지까지입니다. 이 페이지는 장애 중에 그것을 읽기 위한 참고표입니다.
haproxy.log 를 이 페이지에 놓으면 보드가 종료 상태를 사람 말로 풀고, 요청마다 큐 · 연결 · 서버 · 전송 막대를 그리고, 로그만으로 frontend → backend → server 구성도를 만듭니다. 업로드는 없습니다.
HTTP 로그 형식
frontend 에 option httplog 를 쓰면 HTTP 형식이 켜집니다. 매뉴얼은 이것을 다음 log-format 문자열과 정확히 같다고 정의합니다.
# strict equivalent of "option httplog"
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC \
%CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"syslog 를 거쳐 파일에 남은 한 줄입니다.
Oct 18 10:02:02 lb1 haproxy[2201]: 198.51.100.7:40110 [18/Oct/2026:10:01:57.020] fe_http be_api/api-3 0/0/0/120/5032 200 65536 - - SD-- 315/301/44/15/0 0/0 "GET /api/export HTTP/1.1"| # | awk 칸 | 칸 | 예시 값 | 뜻 |
|---|---|---|---|---|
| – | $1–$4 | syslog 머리 | Oct 18 10:02:02 lb1 | HAProxy 가 아니라 syslog 가 붙입니다. 이 폭에 따라 아래 awk 위치가 모두 정해집니다. |
| 1 | $5 | process_name[pid]: | haproxy[2201]: | 프로세스 이름과 pid 입니다. |
| 2 | $6 | client_ip:client_port | 198.51.100.7:40110 | TCP 연결의 클라이언트입니다. accept-proxy 와 PROXY 프로토콜을 쓰면 전달받은 주소입니다. |
| 3 | $7 | [request_date] | [18/Oct/2026:10:01:57.020] | 요청 첫 바이트를 받은 시각(%tr)입니다. 줄을 쓴 시각이 아닙니다. |
| 4 | $8 | frontend_name | fe_http | 연결을 받은 frontend 입니다. |
| 5 | $9 | backend/server | be_api/api-3 | 고른 backend 와 마지막으로 시도한 서버입니다. 서버에 닿지 못했으면 <NOSRV>, 통계 페이지면 <STATS> 입니다. |
| 6 | $10 | TR/Tw/Tc/Tr/Ta | 0/0/0/120/5032 | 밀리초 단위 타이머입니다. 다음 절에서 설명합니다. |
| 7 | $11 | status_code | 200 | 클라이언트에 돌려준 상태입니다. 대개 서버의 것이지만, 서버에 닿지 못했거나 응답을 막았으면 HAProxy 가 정합니다. |
| 8 | $12 | bytes_read | 65536 | 클라이언트로 보낸 바이트이며 헤더를 포함합니다. 64비트 계수기입니다. |
| 9 | $13 | captured_request_cookie | - | "capture cookie" 로 잡은 값이며, 설정이 없으면 대시입니다. |
| 10 | $14 | captured_response_cookie | - | 응답 쪽 같은 값입니다. |
| 11 | $15 | termination_state | SD-- | 누가 어느 단계에서 끝냈는지, 지속 쿠키에 무슨 일이 있었는지입니다. |
| 12 | $16 | actconn/feconn/beconn/srv_conn/retries | 315/301/44/15/0 | 로그를 남길 때 프로세스 · frontend · backend · 서버의 동시 연결 수, 그리고 재시도 수입니다. |
| 13 | $17 | srv_queue/backend_queue | 0/0 | 이 요청 앞에 서버 큐 · backend 큐에서 먼저 처리된 요청 수입니다. |
| 14–15 | – | {captured headers} | (없음) | "capture request/response header" 로 잡은 헤더입니다. 설정했을 때만 중괄호가 나오고, 안에 공백이 들어갈 수 있습니다. |
| 16 | 마지막 | "http_request" | "GET /api/export HTTP/1.1" | 요청 줄이며 늘 마지막, 늘 따옴표 안입니다. syslog 버퍼보다 길면 잘릴 수 있습니다. |
예시 읽기: 서버는 120 ms 만에 헤더를 보냈고(Tr), 본문이 흐르는 도중 서버 쪽 연결이 오류로 끊겼습니다(SD). 클라이언트는 요청 도착 5032 ms 뒤에 200 과 함께 더 컸어야 할 응답 중 64 KiB 만 받았습니다. 상태 코드는 성공이라 말하고, 종료 상태는 다운로드가 깨졌다고 말합니다.
awk 위치가 밀릴 때
위 위치는 전통 syslog 머리(Mmm dd hh:mm:ss host)를 가정합니다. RFC 5424 나 ISO-8601 머리는 앞에 오는 낱말 수가 다르고, 호스트 이름이 하나 더 붙어 전달된 로그도 마찬가지입니다. 캡처한 헤더는 큐 칸 뒤의 칸만 밉니다. 헷갈리면 타이머 칸(빗금으로 나뉜 숫자 다섯 개)을 찾아 거기서부터 세십시오. 아래의 타이머 칸을 찾는 명령이 바로 그렇게 합니다. 보드는 머리 모양과 상관없이 클라이언트 주소와 요청 시각을 찾아 거기서부터 읽습니다.
다섯 타이머: TR / Tw / Tc / Tr / Ta
값은 모두 밀리초입니다. 요청 하나가 프록시를 지나는 길을 따라갑니다.
요청 첫 바이트 응답 마지막 바이트
| |
|-- TR --|-- Tw --|-- Tc --|-------- Tr --------|---------- Td ----------|
요청 큐 TCP 서버가 응답 헤더를 응답 본문이
헤더 대기 연결 보낼 때까지 일함 클라이언트로 나감
|<------------------------------- Ta ------------------------------------>|
TR 앞: Th(TCP 수락 + TLS · PROXY 핸드셰이크), Ti(유휴, keep-alive)
Tq = Th + Ti + TR Tt = Th + Ti + Ta Td = Ta - (TR + Tw + Tc + Tr)| 타이머 | 재는 것 | -1 의 뜻 | 크면 대개 |
|---|---|---|---|
| TR | 첫 바이트부터 헤더 끝 빈 줄까지, 요청 헤더를 다 받는 데 걸린 시간입니다. | 헤더 끝을 끝내 보지 못했습니다. 클라이언트가 일찍 닫았거나 시간 초과입니다. | 클라이언트와 HAProxy 사이 네트워크 문제, 또는 손으로 친 요청입니다. |
| Tw | 연결 자리를 기다리며 backend · 서버 큐에서 보낸 시간입니다. | 큐에 닿기 전에 끝난 요청입니다. 잘못됐거나 거부됐습니다. | 서버가 maxconn 에 차서 요청이 차례를 기다립니다. |
| Tc | 서버와 TCP 연결을 맺는 데 걸린 시간(SYN 부터 SYN/ACK 까지)입니다. | 서버와 연결이 끝내 맺어지지 않았습니다. | HAProxy 와 서버 사이 네트워크 문제입니다. LAN 이면 1 ms 안팎이어야 합니다. |
| Tr | 서버 응답 시간 — 연결이 맺어진 뒤 서버가 응답 헤더를 다 보낼 때까지입니다. | 응답 헤더를 끝내 보지 못했습니다. 대개 "timeout server" 가 먼저 닥쳤습니다. | 이 요청에서 서버가 느립니다. POST 라면 클라이언트가 본문을 보내는 시간도 들어갑니다. |
| Ta | 요청 첫 바이트부터 응답 마지막 바이트까지 전체 활성 시간입니다. | -1 이 되지 않습니다. | 느린 전송, 느린 클라이언트, 또는 시간 제한에 걸린 연결입니다. 앞에 "+" 가 있으면 option logasap 으로 일찍 남긴 값입니다. |
원인을 가리키는 타이머 모양
| 모양 | 일어난 일 | 볼 곳 |
|---|---|---|
-1/xx/xx/xx/Ta | 클라이언트가 요청을 제때 다 보내지 못했거나 그만뒀습니다. | 종료 상태, 그다음 "timeout http-request" 와 "timeout client". |
TR/-1/xx/xx/Ta | 요청을 처리할 수 없었습니다. 서버가 모두 내려갔거나, 요청이 잘못됐거나, ACL 로 거부됐습니다. | 종료 상태. |
TR/Tw/-1/xx/Ta | 서버와 연결하지 못했습니다. 거절당했거나 Ta-(TR+Tw) ms 뒤 시간 초과입니다. | 종료 상태, 그다음 "timeout connect". |
TR/Tw/Tc/-1/Ta | 서버가 연결은 받았지만 응답을 제때 다 주지 않았거나 Ta-(TR+Tw+Tc) ms 뒤 연결을 닫았습니다. | 종료 상태, 그다음 "timeout server". |
| 3000 · 6000 · 9000 근처 값 | TCP 재전송입니다. 재전송 지연이 3 · 6 · 12… 초라서 3초 배수에 가까운 타이머는 거의 언제나 패킷 손실입니다. | Th/Ti 가 3000 근처면 클라이언트 쪽, Tc 가 3000 근처면 HAProxy 와 서버 사이. |
| Ta 가 설정한 시간 제한에 가까움 | 그 시간 제한으로 연결이 끊겼을 가능성이 큽니다. | 어느 시간 제한과 맞는지, 그리고 종료 상태. |
Th · Ti · Td · Tt · Tq · Tu
Th: TCP 수락과 TLS · PROXY 프로토콜 핸드셰이크입니다. 연결의 첫 요청에만 찍히고 뒤 요청은 0 입니다.Ti: 요청 전 유휴 시간입니다. 미리 맺어 둔 연결이나 keep-alive 연결이 기다린 시간이며, 아무것도 받지 못했으면 -1 입니다.Td: 헤더 뒤 응답 본문 전송 시간입니다. 기본 형식에는 없으므로 Ta − (TR + Tw + Tc + Tr) 로 구하고, -1 인 타이머는 빼고 계산합니다.Tt: 수락부터 닫힐 때까지 연결 전체 시간입니다. HTTP 에서는 Tt = Th + Ti + Ta 입니다.Tq: Th + Ti + TR 입니다. 예전 HAProxy 는 같은 자리에Tq/Tw/Tc/Tr/Tt를 남겼습니다. Tq 와 Tt 는 핸드셰이크와 유휴 시간을 품으므로 keep-alive 연결에서 훨씬 커 보이며, 매뉴얼은 Tq 대신 TR 을 권합니다.Tu: 사용자가 느끼는 시간 추정치입니다. 연결 전체 시간에서 유휴 시간 Ti 를 뺀 값입니다.
종료 상태: 네 글자
11번 칸은 TCP 로그에서 두 글자, HTTP 로그에서 네 글자입니다. 앞 두 글자는 연결이 어떻게 끝났는지, 뒤 두 글자는 지속 쿠키 이야기이며 쿠키를 쓰지 않으면 -- 입니다. 그래서 「SD--」를 검색했다면 중요한 것은 SD 이고, cD-- 는 쿠키와 상관없는 cD 입니다.
첫 글자: 무엇이 끝냈나
| 글자 | 뜻 |
|---|---|
C | 클라이언트가 TCP 세션을 예기치 않게 끊었습니다. |
S | 서버가 TCP 세션을 예기치 않게 끊었거나 명시적으로 거절했습니다. |
P | 프록시가 일찍 끊었습니다. 연결 한도, 거부 규칙, 응답의 보안 검사 때문입니다. |
L | HAProxy 가 직접 처리했습니다(리다이렉트, return, 통계, 캐시 등). |
R | 프록시 자원이 바닥났습니다(메모리, 소켓, 출발 포트). 심각한 이상으로 다뤄야 합니다. |
I | 자체 점검에서 내부 오류를 찾았습니다. 일어나면 안 되며, 매뉴얼은 버그로 보고하라고 합니다. |
D | 서버가 내려간 것으로 감지됐고, 내려갈 때 연결을 끊도록 설정돼 있어 끊었습니다. |
U | 활성 서버가 다시 올라와, backup 서버의 연결을 끊도록 한 설정에 따라 끊었습니다. |
K | 관리자가 직접 끊었습니다. |
c | 클라이언트 쪽 시간 제한이 지났습니다(클라이언트가 보내거나 받기를 기다리던 중). |
s | 서버 쪽 시간 제한이 지났습니다(서버가 보내거나 받기를 기다리던 중). |
- | 정상 종료 — 양쪽이 버퍼에 남은 것 없이 닫았습니다. |
둘째 글자: 어느 단계였나
| 글자 | 단계 |
|---|---|
R | 클라이언트의 완전하고 올바른 요청을 기다리던 중(HTTP 만). 서버로는 아무것도 가지 않았습니다. |
Q | 연결 자리를 얻으려고 큐에서 기다리던 중(maxconn 을 둔 서버). 재분배가 없었다면 서버에 연결을 시도하지도 않았습니다. |
C | 서버와 연결이 맺어지기를 기다리던 중. |
H | 서버의 완전하고 올바른 응답 헤더를 기다리던 중(HTTP 만). |
D | 데이터 단계. |
L | 서버는 끝났고 클라이언트에 마지막 데이터를 보내던 중. 드뭅니다. |
T | 요청이 tarpit 에 걸려 있었습니다. 붙잡아 둔 시간은 Tw 에 찍힙니다. |
- | 전송을 마치고 정상 종료. |
셋째 · 넷째 글자: 지속 쿠키
| 글자 | 셋째: 클라이언트가 낸 쿠키 | 넷째: 응답에서 쿠키에 한 일 |
|---|---|---|
N | 쿠키를 내지 않았습니다. | 서버도 쿠키를 주지 않았고 넣지도 않았습니다. |
I | 아는 서버와 맞지 않는 잘못된 쿠키입니다. | 서버가 쿠키를 주지 않아 HAProxy 가 넣었습니다. |
D | 내려간 서버를 가리키는 쿠키입니다. | 서버가 준 쿠키를 HAProxy 가 지웠습니다. |
V | 올바른 쿠키라 그 서버로 보냈습니다. | – |
E | 올바르지만 "maxidle" 로 만료돼 무시했습니다. | – |
O | 올바르지만 "maxlife" 보다 오래돼 무시했습니다. | – |
U | 쿠키가 있었지만 쓰지 않았습니다(예: use-server 규칙이 골랐음). | 쿠키의 마지막 방문 날짜를 갱신했습니다(maxidle 을 둔 insert 모드). |
P | – | 서버가 준 쿠키를 그대로 넘겼습니다. |
R | – | 서버가 준 쿠키를 HAProxy 가 고쳐 썼습니다. |
- | 해당 없음(설정에 쿠키 없음). | 해당 없음. |
종료 상태 참고표: 흔한 조합
매뉴얼이 꼽은 조합, 쉬운 말 풀이, 다음에 볼 곳입니다. 대문자는 중단 · 오류, 소문자는 시간 초과입니다.
| 상태 | 일어난 일 | 다음에 볼 곳 |
|---|---|---|
-- | 정상 종료입니다. | 프록시 쪽은 문제없습니다. -- 인데 5xx 면 서버가 직접 낸 오류이니 애플리케이션 로그를 보십시오. |
CC | HAProxy 가 서버에 연결하는 동안 클라이언트가 포기했습니다. | Tc 와 서버 상태. 막 죽었거나 점검되지 않은 서버에 연결할 때 생깁니다. |
CD | 데이터 전송 중 클라이언트가 끊었습니다. | 대개 브라우저 · 모바일이 떠난 경우입니다. 한 경로에 몰리면 큰 다운로드나 중간 장비가 연결을 끊는 경우입니다. |
cD | 데이터 단계에서 "timeout client" 동안 클라이언트가 아무것도 보내거나 확인하지 않았습니다. | 클라이언트 쪽 네트워크 끊김이나 깔끔하지 않게 떠난 클라이언트. Ta 를 timeout client 와 견줘 보십시오. |
CH | 서버가 응답을 시작하기를 기다리는 동안 클라이언트가 끊었습니다. | 이 줄들의 Tr. 서버가 느렸거나 사용자가 중지를 눌렀습니다. |
cH | POST 중 클라이언트 데이터를 기다리다 "timeout client" 가 닥쳤습니다. | PPPoE 경로의 지나치게 큰 TCP MSS, 또는 timeout client 가 timeout server 보다 짧은데 서버가 느린 경우. |
CQ | 서버 자리를 기다리며 큐에 있는 동안 클라이언트가 끊었습니다. | Tw 와 큐 칸. 서버가 포화됐거나 한 서버가 느립니다. |
CR | 클라이언트가 요청을 다 보내기 전에 끊었습니다. 상태는 대개 400. | 손으로 친 요청, 브라우저 미리 연결, 연결을 끊는 IDS. "option http-ignore-probes" 로 0바이트 연결을 숨길 수 있습니다. |
cR | 요청이 다 오기 전에 "timeout http-request" 가 닥쳤습니다. 상태는 대개 408. | 브라우저 미리 연결, MSS 문제, 느린 클라이언트. "option http-ignore-probes" 의 득실도 같습니다. |
CT | tarpit 에 걸린 동안 클라이언트가 끊었습니다. | tarpit 규칙이 정상 요청을 잡지 않는지 확인하십시오. |
LC | 직접 처리 — 서버 줄의 "redir" 설정에 따른 리다이렉트입니다. | 예상된 동작입니다. |
LR | 직접 처리 — 리다이렉트, http-request return, 또는 애플릿(통계, 캐시, Prometheus exporter, Lua). | 예상된 동작입니다. |
LH | 응답을 직접 처리 — 리다이렉트나 http-response return 입니다. | 예상된 동작입니다. |
SC | 서버나 그 앞 장비가 TCP 연결을 거절했습니다(RST 또는 ICMP). 상태는 대개 502 나 503. | 서버 프로세스가 듣고 있나? 방화벽 규칙은? 12번 칸의 재시도 수도 보십시오. |
sC | 서버 연결이 끝나기 전에 "timeout connect" 가 닥쳤습니다. 상태는 대개 503 이나 504. | 서버까지의 네트워크 경로, 서버의 accept 대기열, timeout connect 값. |
SD | 데이터 전송 중 서버와의 연결이 오류로 죽었습니다. 서버의 RST 나 중간 장비의 ICMP 입니다. | 그 시각의 서버 비정상 종료나 네트워크 장비. 클라이언트가 받은 응답은 잘려 있습니다. |
sD | 데이터 단계에서 "timeout server" 동안 서버가 아무것도 보내거나 확인하지 않았습니다. | 서버 앞 L4 장비(방화벽, 로드밸런서)의 더 짧은 유휴 시간 제한, HAProxy 에서 먼저 만료된 keep-alive 세션. |
SH | 서버가 응답 헤더를 다 보내기 전에 끊었거나 처리 중에 죽었습니다. | 서버 로그. 드문 일이라 남은 요청이 애플리케이션 버그를 재현하는 경우가 많습니다. |
sH | 서버가 응답 헤더를 돌려주기 전에 "timeout server" 가 닥쳤습니다. 가장 흔한 이상입니다. | 느린 애플리케이션이나 포화된 데이터베이스. Tr 은 -1, Ta 는 timeout server 에 가깝습니다. 시간 제한을 늘리면 가려질 뿐입니다. |
sQ | 큐에서 너무 오래 기다려 만료됐습니다. | "timeout queue" · "timeout connect", 서버 maxconn. 짧은 시간에 몰리면 서버의 I/O · 데이터베이스 정체인 경우가 많습니다. |
PC | 프로세스의 소켓 한도에 닿아 프록시가 서버 연결을 거절했습니다. | 전역 maxconn, 손으로 강제한 ulimit-n. |
PD | 서버가 헤더를 보낸 뒤 형식이 잘못된 chunked 메시지를 프록시가 막았습니다. | 서버의 잘못된 chunked 인코딩(청크 크기는 2 GB − 1 까지 받습니다). |
PH | 프록시가 서버 응답을 막았습니다. 잘못됐거나, 불완전하거나, 위험하거나, 필터에 걸렸습니다. 클라이언트는 502 를 받습니다. | 금지 문자가 든 헤더 이름. 응답 헤더 고쳐 쓰기에 실패하면 대신 500 입니다(tune.maxrewrite). |
PR | 프록시가 클라이언트 요청을 막았습니다. 잘못된 문법이면 400, 거부 규칙이면 403. | 어느 deny 규칙이 걸렸나. 요청 헤더 고쳐 쓰기에 실패하면 500 입니다. |
PT | 프록시가 요청을 막고 tarpit 한 뒤 500 을 돌려줬습니다. 서버로는 아무것도 가지 않았습니다. | Tw 가 붙잡아 둔 시간입니다. |
RC | 서버 연결 전에 로컬 자원(메모리, 소켓, 출발 포트)이 바닥났습니다. | 시스템 조정. 오류 출력에 무엇이 모자랐는지 나옵니다. |
쿠키 조합
| 뒤 두 글자 | 뜻 |
|---|---|
-- | 지속 쿠키를 쓰지 않습니다. |
NN | 클라이언트 쿠키 없음, 넣지도 않음(예: insert 모드에 postonly 를 둔 GET). |
NI | 클라이언트 쿠키 없음, 새로 넣음 — insert 모드의 첫 요청입니다. 이것을 세면 새 사용자 수가 됩니다. |
VN | 올바른 쿠키, 새로 넣지 않음. 다시 온 요청 대부분입니다. |
VU | 올바른 쿠키지만 마지막 방문 날짜가 낡아 갱신한 쿠키를 보냈습니다. |
II | 모르는 서버의 쿠키라 올바른 것을 넣었습니다. 설정에서 서버를 뺀 뒤 흔합니다. |
EI | maxidle 보다 오래된 쿠키라 무시하고 새로 넣었습니다. |
OI | maxlife 보다 오래된 쿠키라 무시하고 새로 넣었습니다. |
DI | 쿠키의 서버가 내려가 있어 새 서버를 고르고 알렸습니다. |
VI | 쿠키의 서버가 죽은 표시는 아니었지만 닿지 않아 재분배하고 새 서버를 알렸습니다. |
「자꾸 다시 로그인해야 한다」는 민원이 있으면 그 시각의 II · DI · VI · EI · OI 를 보십시오. 하나하나가 원래 서버를 떠난 요청입니다.
연결 수 · 재시도 · 큐
| 칸 | 뜻 | 볼 점 |
|---|---|---|
| actconn | 프로세스 전체의 동시 연결 수입니다. | 연결 오류가 날 때 512 나 1024 근처면 파일 기술자가 바닥났을 가능성이 큽니다. |
| feconn | frontend 의 동시 연결 수입니다. | 크게 뛰면 backend 정체, 때로는 공격, 또는 frontend maxconn 도달입니다. |
| beconn | 큐에 있는 것까지 포함한 backend 의 동시 연결 수입니다. | 부하를 받으려면 서버가 몇 대 더 필요한지 가늠하는 값입니다. |
| srv_conn | 서버에 아직 살아 있는 동시 연결 수입니다. 서버 maxconn 을 넘지 않습니다. | 자주 maxconn 이면 maxconn 이 낮거나 서버가 모자랍니다. 한 서버만 높으면 그 서버가 느립니다. |
| retries | 이 요청의 연결 재시도 수입니다. 보통 0 입니다. | 잦으면 네트워크 문제나 서버의 대기열이 찬 것입니다. 앞에 "+" 가 있으면 재분배가 일어났으므로 그 수는 로그에 찍힌 서버의 몫이 아닙니다. |
| srv_queue | 서버 큐에서 이 요청보다 먼저 처리된 요청 수입니다. | Tw 를 이 값으로 나누면 서버 응답 시간을 대략 가늠할 수 있습니다. |
| backend_queue | backend 큐에서 이 요청보다 먼저 처리된 요청 수입니다. | 서버 하나의 maxconn 으로 나누면 대략 모자란 서버 대수입니다. |
HAProxy 로그에서 보드가 보여 주는 것
- 종료 상태 — 상태별 건수와 쉬운 말 풀이, 비정상인 것부터.
- 요청 해부 — TR · Tw · Tc · Tr · 전송 시간을 쌓은 막대. 시간이 큐에 갔는지, 연결에 갔는지, 서버에 갔는지 보입니다.
- 로그로 그린 구성도 — 4 · 5번 칸으로 frontend → backend → server 를 그립니다. 굵기는 트래픽, 빨강은 오류가 나는 곳입니다.
- 재시도와 큐 대기 — backend · 서버별.
- 먼저 볼 것 — 예: 「HAProxy SD 61회 — backend be_api, 서버 api-3」.
- 그 밖의 기본 카드 — 상태 코드, 상위 경로, 상위 클라이언트, 지연, 시간축.
HAProxy 로그용 한 줄 명령
전통 syslog 머리를 단 option httplog 표본으로 실행해 확인했습니다. 머리가 다르면 모든 칸 번호에 같은 차이를 더하거나 빼고, 아니면 타이머 칸을 찾는 명령을 쓰십시오.
모든 종료 상태, 많은 순
awk '{print $15}' haproxy.log | sort | uniq -c | sort -rn앞 두 글자만(쿠키 글자 무시)
awk '{print substr($15, 1, 2)}' haproxy.log | sort | uniq -c | sort -rn위치를 믿지 않고 같은 일 — 타이머 칸을 찾아 다섯 칸 뒤를 읽습니다
awk '{for (i = 1; i <= NF; i++) if ($i ~ /^-?[0-9]+\/-?[0-9]+\/-?[0-9]+\/-?[0-9]+\/\+?[0-9]+$/) {print $(i+5); next}}' haproxy.log | sort | uniq -c | sort -rnbackend/server 별 비정상 종료
awk 'substr($15, 1, 1) != "-" {print substr($15, 1, 2), $9}' haproxy.log | sort | uniq -c | sort -rnbackend 별 상태 코드
awk '{split($9, b, "/"); print b[1], $11}' haproxy.log | sort | uniq -c | sort -rn서버가 헤더를 보내는 데 1초 넘게 걸린 요청(Tr)과 종료 상태
awk '{split($10, t, "/"); if (t[4] > 1000) print t[4], $9, $15}' haproxy.log | sort -rn큐에서 기다린 요청(Tw > 0)과 큐 위치
awk '{split($10, t, "/"); if (t[2] > 0) print t[2], $9, $17}' haproxy.log | sort -rn서버와 연결이 끝내 맺어지지 않은 요청(Tc = -1)
awk '{split($10, t, "/"); if (t[3] == -1 && t[2] != -1) print $9, $11, $15}' haproxy.log | sort | uniq -c재시도가 있는 요청. "+" 는 재분배
awk '{split($16, c, "/"); if (c[5] != "0") print c[5], $9, $15}' haproxy.log서버에 닿지 못한 요청 수
grep -c '/<NOSRV> ' haproxy.log전체 활성 시간 Ta 의 p99
awk '{split($10, t, "/"); sub(/^\+/, "", t[5]); print t[5]}' haproxy.log | sort -n | awk '{a[NR]=$1} END {i=int(NR*0.99); if (i<NR*0.99) i++; print a[i] " ms"}'본 것 중 가장 큰 프로세스 전체 연결 수
awk '{split($16, c, "/"); if (c[1] > m) m = c[1]} END {print "peak actconn", m}' haproxy.log본문 전송 시간이 가장 긴 요청(Td = Ta − TR − Tw − Tc − Tr)
awk '{split($10, t, "/"); if (t[1] >= 0 && t[2] >= 0 && t[3] >= 0 && t[4] >= 0) print t[5]-(t[1]+t[2]+t[3]+t[4]), $9}' haproxy.log | sort -rn | head -3
자주 묻는 질문
HAProxy 로그의 SD-- 는 무슨 뜻인가요?
데이터 전송 중 서버와의 연결이 오류로 죽었다는 뜻입니다. HAProxy 가 서버의 RST 나 중간 장비의 ICMP 를 받았습니다. 상태는 200 일 수 있지만 클라이언트는 잘린 응답을 받았습니다. 그 시각의 서버와 네트워크 경로를 보십시오.
cD-- 는 무슨 뜻인가요?
데이터 단계에서 클라이언트 쪽 시간 제한이 지났다는 뜻입니다. 클라이언트가 "timeout client" 동안 데이터를 보내지도 확인하지도 않았습니다. 대개 클라이언트 네트워크 끊김이나 닫지 않고 떠난 클라이언트입니다.
sH-- 는 무슨 뜻인가요?
서버가 응답 헤더를 보내기 전에 "timeout server" 가 지났다는 뜻입니다. 가장 흔한 이상이며 느린 애플리케이션이나 데이터베이스를 가리킵니다. 이런 줄은 Tr 이 -1, Ta 가 timeout server 값에 가깝습니다.
CR-- 와 cR-- 는 무슨 뜻인가요?
둘 다 끝내 다 오지 않은 요청입니다. CR 은 클라이언트가 먼저 끊은 것이며 상태는 대개 400, cR 은 "timeout http-request" 가 먼저 닥친 것이며 상태는 대개 408 입니다. 브라우저의 미리 연결이 많이 만들며, "option http-ignore-probes" 를 쓰면 0바이트 연결을 남기지 않습니다.
TR · Tw · Tc · Tr · Ta 는 각각 무엇인가요?
TR 은 요청 헤더를 받는 시간, Tw 는 큐 대기, Tc 는 서버 연결, Tr 은 서버가 응답 헤더를 보낼 때까지, Ta 는 요청 첫 바이트부터 응답 마지막 바이트까지의 전체 시간입니다. 모두 밀리초입니다.
타이머가 -1 인 이유는?
그 단계가 끝나지 않았다는 뜻입니다. Tc 가 -1 이면 서버 연결이 맺어지지 않았고, Tr 이 -1 이면 응답 헤더가 오지 않았고, TR 이 -1 이면 요청 헤더가 끝나지 않았습니다. Ta 는 -1 이 되지 않습니다.
재시도 수 앞의 + 는 무엇인가요?
첫 서버에서 최대 재시도를 다 쓴 뒤 다른 서버로 재분배됐다는 뜻입니다. 그 재시도는 로그에 찍힌 서버가 아니라 첫 서버의 몫입니다.
<NOSRV> 는 무엇인가요?
서버를 고르거나 서버에 닿기 전에 끝난 요청입니다. 거부, 리다이렉트, 직접 처리, 또는 클라이언트가 일찍 포기한 경우이며, 어느 쪽인지는 종료 상태가 말해 줍니다.
로그에 Tq/Tw/Tc/Tr/Tt 가 찍힙니다. 같은 건가요?
예전 HAProxy 의 배치입니다. Tq 는 핸드셰이크와 유휴 시간을, Tt 는 연결 전체 시간을 품으므로 keep-alive 연결에서 TR · Ta 보다 큽니다. 보드는 옛 배치도 읽지만 새 이름으로 보여 주므로, 그런 파일에서는 보드의 TR 을 Tq 로, Ta 를 Tt 로 읽으십시오.