diff --git a/ansible/roles/common/defaults/main.yml b/ansible/roles/common/defaults/main.yml
index 31f4aaa3f1..9d217d8629 100644
--- a/ansible/roles/common/defaults/main.yml
+++ b/ansible/roles/common/defaults/main.yml
@@ -79,6 +79,7 @@ syslog_facilities:
output_tag: true
output_time: true
- name: "haproxy"
+ match: "infra.haproxy.**"
enabled: "{{ enable_haproxy | bool and inventory_hostname in groups['haproxy'] }}"
facility: "{{ syslog_haproxy_facility }}"
logdir: "haproxy"
diff --git a/ansible/roles/common/releasenotes/notes/parse-haproxy-logs-5f550fbdee432aaa.yaml b/ansible/roles/common/releasenotes/notes/parse-haproxy-logs-5f550fbdee432aaa.yaml
new file mode 100644
index 0000000000..2d5c77afd0
--- /dev/null
+++ b/ansible/roles/common/releasenotes/notes/parse-haproxy-logs-5f550fbdee432aaa.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ HAProxy logs are now parsed to extract detailed information about HTTP
+ and TCP connections. The original log message is retained.
diff --git a/ansible/roles/common/templates/conf/filter/01-rewrite-0.12.conf.j2 b/ansible/roles/common/templates/conf/filter/01-rewrite-0.12.conf.j2
index 473b7a692c..a58b9b1af3 100644
--- a/ansible/roles/common/templates/conf/filter/01-rewrite-0.12.conf.j2
+++ b/ansible/roles/common/templates/conf/filter/01-rewrite-0.12.conf.j2
@@ -43,3 +43,10 @@
rewriterule1 Payload ^\d{6} infra.mariadb.mysqld_safe
rewriterule2 Payload ^\d{4}-\d{2}-\d{2} infra.mariadb.mysqld
+
+# Retag log messages from HAProxy according to log format
+
+ @type rewrite_tag_filter
+ rewriterule1 Payload ^.*haproxy.*\]: [^ ]+:[^ ]+ [^ ]+ [^ ]+ [^ ]+\/[^ ]+ [^\/]+\/[^\/]+\/[^ ]+ [^ ]+ [^ ]+ \S{2}[^\/]+.*$ infra.haproxy.tcp
+ rewriterule2 Payload ^.*haproxy.*\]: [^ ]+:[^ ]+ [^ ]+ [^ ]+ [^ ]+\/[^ ]+ [^\/]+\/[^\/]+\/[^ ]+ [^ ]+ [^ ]+ \S \S \S{4}[^\/]+.*$ infra.haproxy.http
+
diff --git a/ansible/roles/common/templates/conf/filter/01-rewrite-0.14.conf.j2 b/ansible/roles/common/templates/conf/filter/01-rewrite-0.14.conf.j2
index 4337b877f2..cd882fd477 100644
--- a/ansible/roles/common/templates/conf/filter/01-rewrite-0.14.conf.j2
+++ b/ansible/roles/common/templates/conf/filter/01-rewrite-0.14.conf.j2
@@ -192,3 +192,18 @@
tag infra.mariadb.mysqld
+
+# Retag log messages from HAProxy according to log format
+
+ @type rewrite_tag_filter
+
+ key Payload
+ pattern /^.*haproxy.*\]: [^ ]+:[^ ]+ [^ ]+ [^ ]+ [^ ]+\/[^ ]+ [^\/]+\/[^\/]+\/[^ ]+ [^ ]+ [^ ]+ \S{2}[^\/]+.*$/
+ tag infra.haproxy.tcp
+
+
+ key Payload
+ pattern /^.*haproxy.*\]: [^ ]+:[^ ]+ [^ ]+ [^ ]+ [^ ]+\/[^ ]+ [^\/]+\/[^\/]+\/[^ ]+ [^ ]+ [^ ]+ \S \S \S{4}[^\/]+.*$/
+ tag infra.haproxy.http
+
+
diff --git a/ansible/roles/common/templates/conf/filter/02-parser.conf.j2 b/ansible/roles/common/templates/conf/filter/02-parser.conf.j2
index 5936a3cf54..be852a7cd5 100644
--- a/ansible/roles/common/templates/conf/filter/02-parser.conf.j2
+++ b/ansible/roles/common/templates/conf/filter/02-parser.conf.j2
@@ -25,3 +25,23 @@
timestamp ${time}
+
+# Parse HAProxy TCP logs
+
+ @type parser
+ format /^.*haproxy.*\]: (?[^ ]+):(?[^ ]+) \[(?[^ ]+)\] (?[^ ]+) (?[^ ]+)\/(?[^ ]+) ((?[^\/]+)\/(?[^\/]+)\/(?[^ ]+)) (?[^ ]+) \S{2} (?[^\/]+)\/(?[^\/]+)\/(?[^\/]+)\/(?[^\/]+)\/(?[^ ]+) (?[^\/]+)\/(?[^ ]+)$/
+ time_format %d/%b/%Y:%k:%M:%S.%N
+ time_key accept_date
+ key_name Payload
+ reserve_data true
+
+
+# Parse HAProxy HTTP logs
+
+ @type parser
+ format /^.*haproxy.*\]: (?[^ ]+):(?[^ ]+) \[(?[^ ]+)\] (?[^ ]+) (?[^ ]+)\/(?[^ ]+) (((?[^\/]+)\/(?[^\/]+)\/(?[^\/]+)\/(?[^\/]+)\/(?[^ ]+) (?[^ ]+))) (?[^ ]+) (\S \S \S{4}|\S{2}) (?[^\/]+)\/(?[^\/]+)\/(?[^\/]+)\/(?[^\/]+)\/(?[^ ]+) (?[^\/]+)\/(?[^ ]+) "(?[^ ]+) (?[^ ]+) (?[^ ]+)"$/
+ time_format %d/%b/%Y:%k:%M:%S.%N
+ time_key accept_date
+ key_name Payload
+ reserve_data true
+
diff --git a/ansible/roles/common/templates/conf/output/00-local.conf.j2 b/ansible/roles/common/templates/conf/output/00-local.conf.j2
index 2f628f8111..f2ccae3f9d 100644
--- a/ansible/roles/common/templates/conf/output/00-local.conf.j2
+++ b/ansible/roles/common/templates/conf/output/00-local.conf.j2
@@ -1,5 +1,5 @@
{% for item in syslog_facilities | selectattr('enabled') %}
-
+
@type copy
@type file