8.2. Managing incoming and outgoing messages with flow-control

This section describes the internal message-processing model of syslog-ng, as well as the flow-control feature that can prevent message losses. To use flow-control, the flow-control flag must be enabled for the particular log path.

The syslog-ng application monitors (polls) the sources defined in its configuration file, periodically checking each source for messages. When a log message is found in one of the sources, syslog-ng polls every source and reads the available messages. These messages are processed and put into the output buffer of syslog-ng (also called fifo). From the output buffer, the operating system sends the messages to the appropriate destinations.

In large-traffic environments many messages can arrive during a single poll loop, therefore syslog-ng reads only a fixed number of messages from each source. The log-fetch-limit() option specifies the number of messages read during a poll loop from a single source.

Figure 8.3. Managing log messages in syslog-ng

Managing log messages in syslog-ng

Every destination has its own output buffer. The output buffer is needed because the destination might not be able to accept all messages immediately. The log-fifo-size() parameter sets the size of the output buffer. The output buffer must be larger than the log-fetch-limit() of the sources, to ensure that every message read during the poll loop fits into the output buffer. If the log path sends messages to a destination from multiple sources, the output buffer must be large enough to store the incoming messages of every source.

TCP and unix-stream sources can receive the logs from several incoming connections (for example many different clients or applications). For such sources, syslog-ng reads messages from every connection, thus the log-fetch-limit() parameter applies individually to every connection of the source.

Figure 8.4. Managing log messages of TCP sources in syslog-ng

Managing log messages of TCP sources in syslog-ng

The flow-control of syslog-ng introduces a control window to the source that tracks how many messages can syslog-ng accept from the source. Every message that syslog-ng reads from the source lowers the window size by one, every message that syslog-ng successfully sends from the output buffer increases the window size by one. If the window is full (that is, its size decreases to zero), syslog-ng stops reading messages from the source. The initial size of the control window is by default 100: the log-fifo-size() must be larger than this value in order for flow-control to have any effect. If a source accepts messages from multiple connections, all messages use the same control window.

Note

If the source can handle multiple connections (for example, network()), the size of the control window is divided by the value of the max-connections() parameter and this smaller control window is applied to each connection of the source.

When flow-control is used, every source has its own control window. As a worst-case situation, the output buffer of the destination must be set to accommodate all messages of every control window, that is, the log-fifo-size() of the destination must be greater than number_of_sources*log-iw-size(). This applies to every source that sends logs to the particular destination. Thus if two sources having several connections and heavy traffic send logs to the same destination, the control window of both sources must fit into the output buffer of the destination. Otherwise, syslog-ng does not activate the flow-control, and messages may be lost.

The syslog-ng application handles outgoing messages the following way:

Figure 8.5. Handling outgoing messages in syslog-ng OSE

Handling outgoing messages in syslog-ng OSE
  • Output queue: Messages from the output queue are sent to the target syslog-ng server. The syslog-ng application puts the outgoing messages directly into the output queue, unless the output queue is full. The output queue can hold 64 messages, this is a fixed value and cannot be modified.

  • Disk buffer: If the output queue is full and disk-buffering is enabled, syslog-ng puts the outgoing messages into the disk buffer of the destination.

  • Overflow queue: If the output queue is full and the disk buffer is disabled or full, syslog-ng puts the outgoing messages into the overflow queue of the destination. (The overflow queue is identical to the output buffer used by other destinations.) The log-fifo-size() parameter specifies the number of messages stored in the overflow queue. For details on sizing the log-fifo-size() parameter, see Section 8.2, Managing incoming and outgoing messages with flow-control.

There are two types of flow-control: Hard flow-control and soft flow-control.

  • Soft flow-control: In case of soft flow-control there is no message lost if the destination can accept messages, but it is possible to lose messages if it cannot accept messages (for example non-writeable file destination, or the disk becomes full), and all buffers are full. Soft flow-control cannot be configured, it is automatically available for file destinations.

    Example 8.5. Soft flow-control
    source s_file { file("/tmp/input_file.log"); };
    destination d_file { file("/tmp/output_file.log"); };
    destination d_tcp { network("127.0.0.1" port(2222) log-fifo-size(1000)); };
    log { source(s_file); destination(d_file); destination(d_tcp); };
    
    Warning

    Hazard of data loss! For destinations other than file, soft flow-control is not available. Thus, it is possible to lose log messages on those destinations. To avoid data loss on those destinations, use hard flow-control.

  • Hard flow-control: In case of hard flow-control there is no message lost. To use hard flow-control, enable the flow-control flag in the log path. Hard flow-control is available for all destinations.

    Example 8.6. Hard flow-control
    source s_file { file("/tmp/input_file.log"); };
    destination d_file { file("/tmp/output_file.log"); };
    destination d_tcp { network("127.0.0.1" port(2222) log-fifo-size(1000)); };
    log { source(s_file); destination(d_file); destination(d_tcp); flags(flow-control); };