Developing a strategy for collecting application-level logs necessitates stepping back and looking at the big picture. Engineers developing the applications may only see logging at its ground level: the code that writes the event to the log—for example a function that captures Warning: An interesting event has occurred! But where does that message go from there? What path does it travel to get to its destination?
In a sufficiently large architecture where you have many services and applications, possibly spanning multiple data centers and maybe even touching both on-prem and cloud-hosted environments, you may want to designate log collection points at different tiers. These collection points would ingest data from all the applications in a network, for example, or from all within a data center, before forwarding it to a higher tier such as a log aggregation server that is responsible for reporting on all data globally. That way, only the mid-tier collection points would need to have knowledge of where the log aggregation server lives, while the applications would need to know only about the mid-tier collection points, simplifying administration if the network ever changes.
In this blog post, I will describe HAProxy’s log forwarding support for the Syslog protocol, which is a standardized logging protocol baked into many devices, software, and programming languages. HAProxy can act as a log forwarder, standing in as a collection point that receives logs and relays them to a higher tier. Its ability to act as a remote Syslog server and client, along with its support for both UDP and TCP, make it a convenient choice for teams that host a variety of applications and environments.
Log forwarding over UDP
In version 2.3, HAProxy introduced a feature for receiving Syslog messages and forwarding them to another server. HAProxy can listen on either a TCP or UDP port, or both, and then send the message out via TCP or UDP. The UDP configuration is the simplest, so let’s start with that.
In the HAProxy configuration snippet below, a section named
log-forward listens for incoming messages and forwards them to a server at 172.25.0.12.
bind line tells HAProxy to listen for incoming messages over TCP, and the
dgram-bind line tells it to listen for incoming messages over UDP. By specifying 0.0.0.0 as the address, it listens on all available IP addresses assigned to the load balancer. We’re listening and sending using port 514, which is the standard Syslog port for both UDP and TCP. The facility code, local0, is used only if the received log event doesn’t already set a facility.
HAProxy supports two formats of the Syslog protocol, the older RFC3164 and the newer RFC5424, and it will relay whichever format it receives. However, you can choose which one to relay by setting
format on the
In this example, messages are sent out using the UDP protocol. The benefit of UDP is that it’s a fire-and-forget protocol, meaning that HAProxy doesn’t need to wait for a response from the target server, which avoids any slowdowns in performance. The disadvantage is that there is no guarantee that all log messages will arrive at their destination, such as if the destination server were to go offline. HAProxy isn’t able to health-check the server to know if it’s down. In many cases, losing non-critical logs here and there isn’t too important, but if you require 100% message delivery, consider sending outgoing messages over TCP instead.
Log forwarding over TCP
TCP guarantees that messages will reach their destination, but it expects HAProxy to wait for an acknowledgement from the server. To avoid slowdowns, HAProxy performs this waiting in the background, storing queued up Syslog messages in a buffer until they’re sent and acknowledged.
In the configuration snippet below, we utilize a
ring section to define a circular buffer in memory for storing log messages until they’re sent. The
log line in the
log-forward section then refers to this
ring section rather than an IP address as in the UDP example.
log-forward sections enable relaying Syslog messages over TCP without creating a bottleneck. You can play with the
size parameters to change the maximum size of a Syslog message and the overall size of the buffer. Timeouts ensure that HAProxy won’t wait forever on an unresponsive server.
In this blog post, you learned how HAProxy can act as a log collection point that ingests logs from multiple applications and then forwards them to a centralized log aggregation server. HAProxy’s ability to listen for both UDP and TCP Syslog messages helps it to integrate with a variety of software. By creating a tier of log collection points, you can simplify administration of your logging infrastructure.