For the longest time, if you wanted to use haproxy in front of syslog servers, you were limited to syslog over TCP, and you weren’t load balancing messages but connections because that’s all “mode tcp” would allow you.

This is going to change with haproxy 2.3: it will support message based load balancing and forwarding, with the ability to send and receive messages over TCP, UDP, or UNIX domain sockets. Each message being processed individually.

This blog post will detail the new configuration options available to implement syslog forwarding and load balancing, as well as provide sample configurations for different use cases.

Log forwarding

The usual way of proxying a service with haproxy is to use listen or frontend/backend blocks to define entry point and exit points for the service.

For syslog, there is a new kind of section called “log-forward”. This section contains the definition of listeners to receive incoming syslog messages, and a list of servers to forward messages to. There can be multiple “log-forward” sections in a configuration. An example “log-forward” definition would be:

    log-forward syslog-lb

To receive incoming syslog messages, one can define UNIX or TCP listeners with the “bind” keyword, and UDP listeners with the “dgram-bind” keyword. The “bind” keyword is the same used in “frontend”, “listen”, or “peers” sections, and all associated keywords can be used, which means things such as TLS with client authentication can be configured. There is no such option for “dgram-bind”.

    bind :514
    dgram-bind :514

The list of servers to forward messages to consists in a list of log lines. The same log lines that can be used in “global”, “listen” or “frontend” section. An example server would be one of the following:

    log 192.168.122.10:514 local0

The target for the log line can be either a UDP syslog server, a UNIX domain socket, or a TCP syslog server, the latter being addressed through a local ring.

A “log-forward” listener can be used as log target for a “frontend”, “listen” or “global” section. Similarly, a “log-forward” can contain a “log global” line, and forward logs to the server defined in the “global” section.

Playing with Severity

While a facility must be set on the log server lines when an address is also set, the facility is ignored, unless the message has no facility (eg: raw message), in which case the configured facility will be set for outgoing messages.

Severities on the other hand can be used to filter messages under a certain severity, and/or set a maximum severity for forwarded messages. When the severity exceeds the configured max, it is set to the configured maximum severity. To give an example:

    log 192.168.122.10:514 local0 info notice

With this, any message with a severity of debug will not be forwarded, and any message with a severity exceeding notice will have its severity set to notice.

Format translation

An optional format can be configured on log server lines, and messages will be translated to that format when needed, before being sent to the log target.

    log 192.168.122.10:514 format rfc5424 local0 info notice

This can be used to translate messages received from clients using different formats to a unique one.

Message based load balancing

When haproxy receives a message, it will send a copy of this message to all the servers defined in the “log-forward” section.

It is possible to do message based load balancing using the “sample” keyword on a log server line. The following would balance messages between 3 servers in a round robin fashion:

    log 192.168.122.11:514 sample 1:3 local0 info notice
    log 192.168.122.12:514 sample 2:3 local0 info notice
    log 192.168.122.13:514 sample 3:3 local0 info notice

Not available (yet?)

There is currently no support for traffic processing rules, or content switching rules in a “log-forward” section, meaning it’s not possible to route messages based on content, or rewrite the content of the messages.

There is no support for load balancing other than by abusing “sample”, and it is not possible to persist clients.

Sample configurations

Basic round robin

    log-forward syslog-lb-rr
      # UDP listener
      dgram-bind *:514
      # log targets
      log 192.168.122.185:514 sample 1:2  local2 info warning
      log 192.168.122.212:514 sample 2:2  local2 info warning

Weighted round robin

    log-forward syslog-lb-wrr
      # UDP listener
      dgram-bind *:514
      # log targets 25/75 split
      log 192.168.122.185:514 sample 1:4  local2 info warning
      log 192.168.122.212:514 sample 2-4:4  local2 info warning

Mixing protocols

    ring syslogtcpsrv
      format rfc3164
      size 32764
      maxlen 1200
      server log1 192.168.122.133:10514


    log-forward syslog-lb-dualproto
      # TCP listener
      bind *:514
      # UDP listener
      dgram-bind *:514
      # UDP log targets 25/75 split
      log 192.168.122.185:514 sample 1:4  local2 info warning
      log 192.168.122.212:514 sample 2-4:4  local2 info warning
      # TCP log target gets all messages
      log ring@syslogtcpsrv local2 info warning

TLS

    ring syslogtcpsrv
      format rfc3164
      size 32764
      maxlen 1200
      server log1 192.168.122.133:10514


    log-forward syslog-lb-tls-in
      # TCP listener
      bind *:1514 ssl crt /path/to/cert.pem verify required ca-file /path/to/ca.pem
      # UDP log targets 25/75 split
      log 192.168.122.185:514 sample 1:4  local2 info warning
      log 192.168.122.212:514 sample 2-4:4  local2 info warning
      # TCP log target gets all messages
      log ring@syslogtcpsrv local2 info warning