module HAProxyLogParser
grammar Line rule line syslog_portion:([^\[]+ '[' integer ']: ') client_ip:ip_address ':' client_port:integer ' ' '[' accept_date '] ' suffix:(normal_suffix / error_suffix) "\n"? end rule normal_suffix frontend_name:proxy_name transport_mode:'~'? ' ' backend_name:proxy_name '/' server_name ' ' tq:integer '/' tw:integer '/' tc:integer '/' tr:integer '/' tt:integer ' ' status_code:integer ' ' bytes_read:integer ' ' captured_request_cookie:([^ ]+) ' ' captured_response_cookie:([^ ]+) ' ' termination_state ' ' actconn:integer '/' feconn:integer '/' beconn:integer '/' srv_conn:integer '/' retries:integer ' ' srv_queue:integer '/' backend_queue:integer ' ' captured_request_headers:('{' headers:captured_headers '} ')? captured_response_headers:('{' headers:captured_headers '} ')? '"' http_request:[^"]+ '"' end rule error_suffix frontend_name:proxy_name '/' bind_name ': ' message:[^\n]+ end rule integer ('-' / '+')? [0-9]+ end rule time ([0-9] 2..2 ':') 2..2 ([0-9] 2..2) end rule ip_address # Asserting port is a little hacky but required because of the way # HAProxy writes IPv6 addresses in the logs. It uses a valid RFC5952 # method of IP:PORT, but this complicates things by having valid IP:PORT # combos that are themselves valid IPv6 addresses. # e.g. 1::2:123 ip4_address / ip6_address_assert_port end rule ip4_address dec_octet '.' dec_octet '.' dec_octet '.' dec_octet end rule colon_port ':' integer ' ' end rule ip6_address_assert_port # Taken from https://tools.ietf.org/html/rfc3986#section-3.2.2 # Performs look-ahead assertion on the port, assuming format IP:PORT ( h16 ':' ) 6..6 ls32 &colon_port / '::' ( h16 ':' ) 5..5 ls32 &colon_port / ( h16 )? '::' ( h16 ':' ) 4..4 ls32 &colon_port / ( h16 ( ':' h16 ) ..1 )? '::' ( h16 ':' ) 3..3 ls32 &colon_port / ( h16 ( ':' h16 ) ..2 )? '::' ( h16 ':' ) 2..2 ls32 &colon_port / ( h16 ( ':' h16 ) ..3 )? '::' h16 ':' ls32 &colon_port / ( h16 ( ':' h16 ) ..4 )? '::' ls32 &colon_port / ( h16 ( ':' h16 ) ..5 )? '::' h16 &colon_port / ( h16 ( ':' h16 ) ..6 )? '::' &colon_port end rule ls32 # least-significant 32 bits of address ( h16 ':' h16 ) / ip4_address end rule h16 # 16 bits of address represented in hexadecimal hex_digit 1..4 end rule hex_digit [a-f0-9A-F] end rule dec_octet '25' [0-5] / '2' [0-4] dec_digit / '1' dec_digit 2..2 / dec_digit 1..2 end rule dec_digit [0-9] end rule accept_date [0-9] 2..2 '/' [A-Z] [a-z] 2..2 '/' [0-9]+ ':' time '.' ([0-9] 3..3) end rule proxy_name [-_A-Za-z0-9.:]+ end rule server_name proxy_name / '<NOSRV>' / '<STATS>' end rule termination_state [-A-Za-z] 4..4 end rule captured_headers [^}]* end rule bind_name [-_A-Za-z0-9.]+ end end
end