HAProxy HTTP Log Format Regex Extractor & Grok Expressions
Extract, parse, and analyze HAProxy HTTP access logs with battle-tested Grok expressions and PCRE regular expressions. Dissect microsecond connection timers, session termination flags, and backend load balancing telemetry.
HAProxy HTTP logs record microsecond-level latency metrics, connection states, and reverse-proxy routing decisions. Use standard Grok pattern %{HAPROXYHTTP} or compile explicit PCRE regex to capture client IP, frontend, backend, server, timers (%TR/%Tw/%Tc/%Tr/%Ta), HTTP status, and byte payloads. Structured parsing enables real-time bottleneck detection, 5xx error tracking, and edge telemetry aggregation in Vector, Logstash, and Fluent Bit.
1. Anatomy of the Default HAProxy HTTP Log Format
When option httplog is declared inside an HAProxy frontend or defaults block, the proxy emits rich telemetry structured according to the internal 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"
Here is a concrete real-world production log event emitted by HAProxy through local rsyslog:
2. Production Grok Pattern & Pure PCRE Regular Expression
While Logstash includes a built-in %{HAPROXYHTTP} pattern, production environments frequently require explicit sub-field extractions, handling negative latency flags (-1), and typed integer conversions.
Explicit Grok Pattern (with Type Coercion)
^(?:%{SYSLOGTIMESTAMP:syslog_timestamp}\s+%{HOSTNAME:syslog_host}\s+haproxy\[%{POSINT:syslog_pid:int}\]:\s+)?%{IPORHOST:client_ip}:%{POSINT:client_port:int}\s+\[%{NOTSPACE:accept_date}\]\s+%{NOTSPACE:frontend_name}\s+%{NOTSPACE:backend_name}/%{NOTSPACE:server_name}\s+%{INT:time_wait_request:int}/%{INT:time_wait_queue:int}/%{INT:time_connect_tcp:int}/%{INT:time_response_server:int}/%{INT:time_total_active:int}\s+%{INT:status_code:int}\s+%{INT:bytes_read:int}\s+%{NOTSPACE:client_cookie}\s+%{NOTSPACE:server_cookie}\s+%{NOTSPACE:termination_state}\s+%{INT:actconn:int}/%{INT:feconn:int}/%{INT:beconn:int}/%{INT:srvconn:int}/%{INT:retries:int}\s+%{INT:srv_queue:int}/%{INT:backend_queue:int}\s+"(?:%{WORD:http_verb}\s+%{NOTSPACE:http_request}(?:\s+HTTP/%{NUMBER:http_version})?|%{DATA:raw_request})"$ High-Performance PCRE Regex (Named Capture Groups)
Optimized for Fluent Bit, Vector VRL, ClickHouse, and Python re modules:
^(?:(?[A-Z][a-z]{2}\s+\d+\s+\d{2}:\d{2}:\d{2})\s+(? \S+)\s+haproxy\[(? \d+)\]:\s+)?(? [\w\.\:]+):(? \d+)\s+\[(? [^\]]+)\]\s+(? \S+)\s+(? \S+)\/(? \S+)\s+(? -?\d+)\/(? -?\d+)\/(? -?\d+)\/(? -?\d+)\/(? -?\d+)\s+(? \d+)\s+(? \d+)\s+(? \S+)\s+(? \S+)\s+(? [A-Za-z\-]{2,4})\s+(? \d+)\/(? \d+)\/(? \d+)\/(? \d+)\/(? \d+)\s+(? \d+)\/(? \d+)\s+"(?:(? [A-Z]+)\s+(? [^\s"]+)(?:\s+HTTP\/(? [\d\.]+))?|(? [^"]+))"$
3. HAProxy Log Parsing Cheat Sheet Table
Every field emitted by HAProxy corresponds to critical diagnostic telemetry. The table below outlines each token, meaning, example value, and recommended destination schema type:
| Token | Variable Name | Description | Sample Value | Type |
|---|---|---|---|---|
| %ci | client_ip | Client IPv4 or IPv6 origin address | 198.51.100.44 | ip / string |
| %cp | client_port | Client TCP ephemeral source port | 52841 | integer |
| %t / [%tr] | accept_date | Timestamp when HAProxy accepted connection | 09/Sep/2026:15:30:14.281 | date / string |
| %ft | frontend_name | Frontend identifier that accepted request | fe_https~ | string |
| %b | backend_name | Backend pool routed to handle request | be_api_cluster | string |
| %s | server_name | Backend server member handling connection | srv_api_03 | string |
| %TR | time_wait_request | Time waiting for complete client HTTP request (ms) | 4 | integer (ms) |
| %Tw | time_wait_queue | Time waiting in backend queue for a slot (ms) | 0 | integer (ms) |
| %Tc | time_connect_tcp | Time to establish TCP 3-way handshake to server (ms) | 1 | integer (ms) |
| %Tr | time_response_server | Time for server to send full response headers (ms) | 22 | integer (ms) |
| %Ta | time_total_active | Total active request duration end-to-end (ms) | 27 | integer (ms) |
| %ST | status_code | HTTP response status code returned to client | 200 | integer |
| %B | bytes_read | Payload bytes sent to client excluding HTTP headers | 4582 | integer (bytes) |
| %tsc | termination_state | Session termination condition flags | ---- / cD / sH | string |
| %ac/%fc/%bc/%sc/%rc | conn_counters | Concurrent connections & server retry count | 142/85/32/8/0 | integers |
| %sq/%bq | queue_counters | Active queue depth on server and backend pool | 0/0 | integers |
| %{+Q}r | http_request | Quoted HTTP request line with query params | "POST /api/v3/orders HTTP/1.1" | string |
4. Performance Triage: Isolating Bottlenecks with the 5 Latency Timers
The timer string %TR/%Tw/%Tc/%Tr/%Ta is HAProxy's most powerful observability feature. Rather than treating response time as a black box, parsing these 5 values isolates exactly which layer caused latency:
High %TR (Request Header Wait)
Indicates slow client connections, mobile packet loss, or a Slowloris DoS attack. If %TR is several seconds while %Tr is low, the delay is outside your infrastructure.
High %Tw (Queue Delay)
Indicates backend pool exhaustion. All server maxconn thresholds are saturated. Requests are backing up in HAProxy queues waiting for available worker processes.
High %Tc (TCP Handshake)
Indicates network congestion or kernel SYN backlog exhaustion between HAProxy and backend application servers. High %Tc points to host infrastructure or AWS VPC peering issues.
High %Tr (Backend Processing)
Indicates slow application code, unindexed database queries, or external API deadlocks. The backend server accepted the TCP connection but stalled before emitting response headers.
High %Ta with Low %Tr (Client Egress Stalling)
When %Ta - (%TR + %Tw + %Tc + %Tr) is large, HAProxy completed backend processing quickly, but the client took excessive time reading the payload over a slow broadband or mobile link.
5. Ingestion Pipeline Configurations
Vector Remap Language (VRL) Transform
Native Rust parsing with regex pattern extraction, type casting, and timestamp parsing:
# Vector Remap Language (VRL) - HAProxy HTTP Parser parsed, err = parse_regex(.message, r'^(?:(?P[A-Z][a-z]{2}\s+\d+\s+\d{2}:\d{2}:\d{2})\s+(?P \S+)\s+haproxy\[(?P \d+)\]:\s+)?(?P [\w\.\:]+):(?P \d+)\s+\[(?P [^\]]+)\]\s+(?P \S+)\s+(?P \S+)\/(?P \S+)\s+(?P -?\d+)\/(?P -?\d+)\/(?P -?\d+)\/(?P -?\d+)\/(?P -?\d+)\s+(?P \d+)\s+(?P \d+)\s+(?P \S+)\s+(?P \S+)\s+(?P [A-Za-z\-]{2,4})\s+(?P \d+)\/(?P \d+)\/(?P \d+)\/(?P \d+)\/(?P \d+)\s+(?P \d+)\/(?P \d+)\s+"(?:(?P [A-Z]+)\s+(?P [^\s"]+)(?:\s+HTTP\/(?P [\d\.]+))?|(?P [^"]+))"$') if err != null { log("HAProxy parse error: " + err, level: "warn") } else { . = merge(., parsed) .client_port = to_int!(.client_port) .status = to_int!(.status) .bytes = to_int!(.bytes) .tr_wait_ms = to_int!(.tr_wait) .tw_queue_ms = to_int!(.tw_queue) .tc_conn_ms = to_int!(.tc_conn) .tr_resp_ms = to_int!(.tr_resp) .ta_active_ms = to_int!(.ta_active) .timestamp = parse_timestamp!(.timestamp, "%d/%b/%Y:%T%.3f") del(.message) }
Fluent Bit Regex Parser (parsers.conf)
Oniguruma regex parser configuration for edge logging:
[PARSER]
Name haproxy_httplog
Format regex
Regex ^(?:(?[A-Z][a-z]{2}\s+\d+\s+\d{2}:\d{2}:\d{2})\s+(?\S+)\s+haproxy\[(?\d+)\]:\s+)?(?[\w\.\:]+):(?\d+)\s+\[(? 6. Session Termination State Flags (%tsc) Cheat Sheet
The 4-character termination flag field reveals why and where a session closed. Normal completed sessions display ----. Abnormal terminations identify exact failure modes:
| Flag Code | Termination Cause | Meaning & Operational Resolution |
|---|---|---|
| ---- | Clean Termination | Request and response completed normally without premature closure. |
| cD | Client Abort (Data) | Client closed TCP socket while server was transmitting response data (e.g., browser tab closed). |
| cH | Client Abort (Headers) | Client disconnected before receiving full response headers from backend. |
| sH | Server Timeout / Reset (Headers) | Backend server died or reached timeout server before sending complete headers. |
| sQ | Queue Expired | Request timed out in HAProxy queue before any server slot opened (timeout queue). |
| PR | Proxy Denied | HAProxy blocked request via ACL rules (e.g. rate limit, path restriction, or WAF block). |