HAProxy access logs don’t just appear in /var/log/haproxy.log by default; you have to actively tell HAProxy to send them somewhere, and rsyslog is the common destination.

Here’s how to get HAProxy access logs flowing to rsyslog:

First, you need to configure HAProxy to log to a specific syslog facility and severity. Open your HAProxy configuration file, usually located at /etc/haproxy/haproxy.cfg.

Find the global section and add or modify the log directive. This directive tells HAProxy which syslog server to send logs to and at what level. For local rsyslog, you’ll typically use a local facility like local0 through local7.

global
    log 127.0.0.1:514 local0
    # ... other global settings

This line tells HAProxy to send logs to rsyslog running on the local machine (127.0.0.1) on port 514 (the standard syslog port), using the local0 facility.

Next, within your HAProxy configuration, you need to specify what to log for each frontend and backend. This is done using the option log-format directive, typically within the defaults section or specific frontend/backend sections.

A common and useful log format includes timestamp, client IP, method, URI, status code, bytes sent, and backend response time.

defaults
    mode http
    log global
    option httplog
    option dontlognull
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    # This is the crucial part for access logs
    log-format '%{+Q}APROXY_LOG_FORMAT' # Using a predefined format for simplicity

# Or, define a custom format:
# log-format '%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %s %CC %CS %tsc %rc %sq %hsl %Hw'

frontend http_frontend
    bind *:80
    default_backend web_servers
    # If not set in defaults, you can set it here:
    # log-format '%{+Q}APROXY_LOG_FORMAT'

backend web_servers
    balance roundrobin
    server server1 192.168.1.10:80 check
    server server2 192.168.1.11:80 check

The %{+Q}APROXY_LOG_FORMAT is a convenient built-in format string that captures essential details. If you want a custom format, you can define it explicitly using various format specifiers. The example shows a more detailed custom format.

Now, you need to configure rsyslog to receive these logs and process them. Create a new rsyslog configuration file, for example, /etc/rsyslog.d/60-haproxy.conf.

In this file, you’ll tell rsyslog to listen for UDP traffic on port 514 and to associate logs from the local0 facility with a specific output file.

# /etc/rsyslog.d/60-haproxy.conf

# Provide TCP and UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")

# Define a template for HAProxy logs
template(name="HAProxyLog" type="string"
         string="/var/log/haproxy-access.log")

# Filter logs from HAProxy (local0 facility) and direct them to the template
if ($syslogfacility-text == "local0") then ?HAProxyLog

This configuration tells rsyslog to load the imudp module, listen on port 514 for UDP packets, and if a message comes in with the local0 facility, it should write it to /var/log/haproxy-access.log using the HAProxyLog template.

After saving both configuration files, you need to restart HAProxy and rsyslog for the changes to take effect.

Restart HAProxy:

sudo systemctl restart haproxy

Restart rsyslog:

sudo systemctl restart rsyslog

Now, when HAProxy processes requests, you should see log entries appearing in /var/log/haproxy-access.log.

tail -f /var/log/haproxy-access.log

You’ll see lines similar to this (depending on your log-format):

1678886400.123456 192.168.1.100:54321 [01/Jan/2023:10:00:00.123] http_frontend/server1 200 12345 0.012 0.010 0.011 200 12345

This log line contains the timestamp, client IP and port, frontend name, backend server, HTTP status code, bytes received, and various timings.

If you’re using a more advanced setup where HAProxy and rsyslog are on different servers, you would change log 127.0.0.1:514 local0 in haproxy.cfg to log <rsyslog_server_ip>:514 local0. On the rsyslog server, you’d ensure rsyslog is configured to listen on the network interface (e.g., input(type="imudp" port="514" listenPort="514") or input(type="imudp" port="514" address="0.0.0.0")) and that firewalls allow traffic on UDP port 514.

The most common pitfall is forgetting to enable the network input module in rsyslog if you’re not using local syslog sockets. For network reception, you must have module(load="imudp") and input(type="imudp" port="514") (or imtcp for TCP) in your rsyslog.conf or a file in /etc/rsyslog.d/.

The next thing you’ll likely want to do is parse these logs with a log analysis tool like ELK stack or Splunk, or configure rsyslog to buffer logs and send them to a remote collector.

Want structured learning?

Take the full Haproxy course →