For details on how flow-control works, see Managing incoming and outgoing messages with flow-control. The summary of the main points is as follows:
-
The syslog-ng application normally reads a maximum of log-fetch-limit() number of messages from a source.
-
From TCP and unix-stream sources, syslog-ng reads a maximum of log-fetch-limit() from every connection of the source. The number of connections to the source is set using the max-connections() parameter.
-
Every destination has an output buffer. The size of this buffer is set automatically for log paths that use flow-control, and can be set using the log-fifo-size() option for other log paths.
-
Flow-control uses a control window to determine if there is free space in the output buffer for new messages. Every source has its own control window, the log-iw-size() option sets the size of the static control window. Optionally, you can enable a dynamic control window for the source using the dynamic-window-size() option.
-
When a source accepts multiple connections, 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.
The dynamic control window is automatically distributed among the active connections of the source.
-
If the control window is full, syslog-ng stops reading messages from the source until some messages are successfully sent to the destination.
-
If the output buffer becomes full, and neither disk-buffering nor flow-control is used, messages may be lost.
|
Caution:
If you modify the max-connections() or the log-fetch-limit() parameter, do not forget to adjust the log-iw-size() and dynamic-window-size() parameters accordingly. |
Example: Sizing parameters for flow-control
Suppose that syslog-ng has a source that must accept up to 300 parallel connections. Such situation can arise when a network source receives connections from many clients, or if many applications log to the same socket.
Set the max-connections() parameter of the source to 300. However, the log-fetch-limit() (default value: 10) parameter applies to every connection of the source individually, while the log-iw-size() (default value: 1000) parameter applies to the source. In a worst-case scenario, the destination does not accept any messages, while all 300 connections send at least log-fetch-limit() number of messages to the source during every poll loop. Therefore, the control window must accommodate at least max-connections()*log-fetch-limit() messages to be able to read every incoming message of a poll loop. In the current example this means that log-iw-size() should be greater than 300*10=3000. If the control window is smaller than this value, the control window might fill up with messages from the first connections — causing syslog-ng to read only one message of the last connections in every poll loop.
The output buffer of the destination must accommodate at least log-iw-size() messages, but use a greater value: in the current example 3000*10=30000 messages. That way all incoming messages of ten poll loops fit in the output buffer. If the output buffer is full, syslog-ng does not read any messages from the source until some messages are successfully sent to the destination.
source s_localhost {
network(
ip(127.0.0.1)
port(1999)
max-connections(300)
);
};
destination d_tcp {
network("10.1.2.3"
port(1999)
localport(999)
log-fifo-size(30000)
);
};
log {
source(s_localhost);
destination(d_tcp);
flags(flow-control);
};
If other sources send messages to this destination, then the output buffer must be further increased. For example, if a network host with maximum 100 connections also logs into the destination, then increase the log-fifo-size() by 10000.
source s_localhost {
network(
ip(127.0.0.1)
port(1999)
max-connections(300)
);
};
source s_tcp {
network(
ip(192.168.1.5)
port(1999)
max-connections(100)
);
};
destination d_tcp {
network("10.1.2.3"
port(1999)
localport(999)
log-fifo-size(40000)
);
};
log {
source(s_localhost);
destination(d_tcp);
flags(flow-control);
};
The syslog-ng Open Source Edition application can store messages on the local hard disk if the destination (for example, the central log server) or the network connection to the destination becomes unavailable. The syslog-ng OSE application automatically sends the stored messages to the destination when the connection is reestablished. The disk buffer is used as a queue: when the connection to the destination is reestablished, syslog-ng OSE sends the messages to the destination in the order they were received.
Every such destination uses a separate disk buffer (similarly to the output buffers controlled by log-fifo-size()). The hard disk space is not pre-allocated, so ensure that there is always enough free space to store the disk buffers even when the disk buffers are full.
If syslog-ng OSE is restarted (using the /etc/init.d/syslog-ng restart command, or another appropriate command on your platform), it automatically saves any unsent messages from the disk buffer and in-memory queues. After the restart, syslog-ng OSE sends the saved messages to the destination. In other words, the disk buffer is persistent. The disk buffer is also resistant to syslog-ng OSE crashes.
The syslog-ng OSE application supports two types of disk buffering: reliable and normal. For details, see Enabling reliable disk-based buffering and Enabling normal disk-based buffering, respectively.
Message handling and normal disk-based buffering
When you use disk-based buffering, and the reliable() option is set to no, syslog-ng OSE handles outgoing messages the following way:
Figure 17: Handling outgoing messages in syslog-ng OSE
-
Output queue: In-memory queue. If there is space left in it, syslog-ng OSE puts the message into this queue first . Messages stored here are processed faster, because syslog-ng OSE can skip writing to, and reading from the disk, as well as serializing or deserializing the message, saving I/O and processor time as a result. The contents of the in-memory output queue are persisted to the disk-buffer file during syslog-ng OSE reload, restart or stop, but they cannot be persisted if in the event of power failures, or if syslog-ng OSE crashes. By default, the output queue can hold 1000 messages (you can adjust this number using the quot-size() option).
-
Disk-buffer file: Disk queue. If there is no space left in the output queue, the message is stored on the disk-buffer file. Messages stored here are persisted on the disk, even in case of power failures or if syslog-ng OSE crashes. Using the disk-buffer file takes considerable amount of disk I/O and processor time. The size of this queue can be set with the disk-buf-size() option.
-
Overflow queue: In-memory queue. This queue is used to trigger flow-control if it is set. The contents of the in-memory overflow queue are persisted to the disk-buffer file in case of syslog-ng OSE reload, restart or stop, but they are not persisted in case of power failures or if syslog-ng OSE crashes. Setting the size of the overflow queue can be done with the mem-buf-length() option.
|
Caution:
Hazard of data loss!
In case of normal disk-buffers, the messages stored in the output queue and the overflow queue can be lost in case of power failures or if syslog-ng OSE crashes. |
NOTE: Using disk buffer can significantly decrease performance.
Message handling and reliable disk-based buffering
When you use disk-based buffering, and the reliable() option is set to yes, syslog-ng OSE handles outgoing messages the following way.
The mem-buf-size() option determines when flow-control is triggered. After the size of the disk-buffer file reaches (disk-buf-size() minus mem-buf-size()), messages are written into both the disk-buffer file and the overflow queue, indicating that flow-control needs to slow down the message source. These messages are not taken out from the control window (governed by log-iw-size()), causing the control window to fill up.
If the control window is full, the flow-control completely stops reading incoming messages from the source. (As a result, mem-buf-size() must be at least as large as log-iw-size() times the average message size.)
Figure 18: Handling outgoing messages in syslog-ng OSE with the reliable disk-buffer option
-
Output queue: In-memory and disk queue. If there is space left in it, syslog-ng OSE puts the message into this queue first. In case of reliable disk-buffer, in addition to storing the message in memory, it is stored directly in the disk-buffer file as well for safety reasons (see the next point). Messages stored here are processed faster, because syslog-ng OSE can skip reading from the disk, and deserializing the message, saving I/O and processor time. By default, the output queue can hold 1000 messages (you can adjust it using the quot-size() option).
-
Disk-buffer file: Disk queue. If there is no space left in the output queue, the message is stored on the disk-buffer file. Messages stored here are persisted on the disk, and survive syslog-ng OSE crash or power failure. Using the disk-buffer file takes considerable amount of disk I/O and processor time. The size of this queue can be set with the disk-buf-size() option.
-
Overflow queue: In-memory and disk queue. This queue is used to trigger flow-control if it is set. Similarly to the output queue, in case of reliable disk-buffer in addition to storing the message in memory, it is stored directly in the disk-buffer file as well for safety reasons. Setting the size of the overflow queue can be done with the mem-buf-size() option.
To enable reliable disk-based buffering, use the disk-buffer(reliable(yes)) parameter in the destination. Use reliable disk-based buffering if you do not want to lose logs in case of reload/restart, unreachable destination or syslog-ng OSE crash. This solution provides a slower, but reliable disk-buffer option. It is created and initialized at startup and gradually grows as new messages arrive. The filename of the reliable disk buffer file is the following: <syslog-ng path>/var/syslog-ng-00000.rqf.
Example: Example for using reliable disk-based buffering
destination d_BSD {
network("127.0.0.1"
port(3333)
disk-buffer(
mem-buf-size(10000)
disk-buf-size(2000000)
reliable(yes)
)
);
};
For details on the differences between normal and reliable disk-based buffering, see also About disk queue files.
If the reliable() option is not set, by default a normal disk-buffer is created. To explicitly enable the normal disk-buffer option, use the disk-buffer(reliable(no)) parameter in the destination. Use the normal disk-buffer option if you want a solution that is faster than the reliable disk-buffer option. In this case, the process will be less reliable and it is possible to lose logs in case of syslog-ng OSE crash. The filename of the normal disk-buffer file is the following: <syslog-ng path>/var/syslog-ng-00000.qf.
Example: Example for using normal disk-based buffering
When using the disk-buffer plugin:
destination d_BSD {
network("127.0.0.1"
port(3333)
disk-buffer(
mem-buf-length(10000)
disk-buf-size(2000000)
reliable(no)
)
);
};
For details on the differences between normal and reliable disk-based buffering, see also About disk queue files.