rsyslog: why disk-assisted queues keep a file open
From time to time, someone asks why rsyslog disk-assisted queues keep one file open until shutdown. So it probably is time to elaborate a bit about it.
Let’s start with explaining what can be seen: if a disk-assisted queue is configured, rsyslog will normally use the in-memory queue. It will open a disk queue only if there is good reason to do so (because it severely hurts performance). The prime reason to go to disk is when the in memory queue’s configured size has been exhausted. Once this happens, rsyslog begins to create spool files, numbered consequtively. This should normally happen in cases where e.g. a remote target is temporarily not reachable or a database engine is responding extremely slow. Once the situation has been cleared, rsyslog clears out the spool files. However, one spool file always is kept until you shut rsyslog down. Note well that when the disk queue is idle, all messages are processed even though the the physical spool file still contains some already-processed data (impstats will show you the exact details).
This is expected behaviour, and there is good reason for it. This is what happens technically:
A DA queue is actually “two queues in one”: It is a regular in-memory queue, which has a (second) helper disk queue in case it neeeds it. As long as operations run smoothly, the disk queue is never used. When the system starts up, only the in-memory queue is started. Startup of the disk queue is deferred until it is actually needed (as in most cases it will never be needed).
When the in-memory queue runs out of space, it starts that Disk queue, which than allocates its queue file. In order to reclaim space, not a single file is written but a series of files, where old files are deleted when they are processed and new files are created on an as-needed basis. Initially, there is only one file, which is read and written. And if the queue is empty, this single file still exists, because it is the representation of a disk queue (like the in-memory mapping tables for memory queues always exist, which just cannot be seen by the user).
So what happens in the above case is that the disk queue is created, put into action (the part where it writes and deletes files) and is then becoming idle and empty. At that stage, it will keep its single queue file, which holds the queue’s necessary mappings.
One may now ask “why not shut down the disk queue if no longer needed”? The short answer is that we anticpiate that it will be re-used and thus we do not make the effort to shut it down and restart when the need again arises. Let me elaborate: experience tells that when a system needs the disk queue once, it is highly likely to need it again in the future. The reason for disk queues to kick into action are often cyclic, like schedule restarts of remote systems or database engines (as part of a backup process, for example). So we assume if we used it once, we will most probably need it again and so keep it ready. This also helps reduce potential message loss during the switchover process to disk – in extreme cases this can happen if there is high traffic load and slim in-memory queues (remember that starting up a disk queue needs comparativley long).
The longer answer is that in the past rsyslog tried to shut down disk queues to “save” ressources. Experience told us that this “saving” often resulted in resource wasting. Also, the need to synchronize disk queue shutdown with the main queue was highly complex (just think about cases where we shut it down at the same time the in-memory queue actually begins to need it again!). This caused quite some overhead even when the disk queue was not used (again, this is the case most of the time – if properly sized). An indication of this effect probably is that we could remove roughly 20% of rsyslog’s queue code when we removed the “disk queue shutdown” feature!
Bottom line: keeping the disk queue active once it has been activated is highly desirable and as such seeing a queue file around until shutdown is absolutely correct. Many users will even never see this spool file, because there are no exceptional circumstances that force the queue to go to disk. So they may be surprised if it happens every now and then.
Side-Note: if disk queue files are created without a traget going offline, one should consider increasing the in-memory queue size, as disk queues are obviouly much less efficient than memory queues.
/etc/rsyslog.conf
are applied. Based on these rules, the rule processor evaluates which actions are to be performed. Each action has its own action queue. Messages are passed through this queue to the respective action processor which creates the final output. Note that at this point, several actions can run simultaneously on one message. For this purpose, a message is duplicated and passed to multiple action processors.-
they serve as buffers that decouple producers and consumers in the structure of rsyslog
-
they allow for parallelization of actions performed on messages
WARNING
SSH
logging, which in turn can prevent SSH
access. Therefore it is advised to use dedicated action queues for outputs which are forwarded over a network or to a database./etc/rsyslog.conf
:$objectQueueType queue_type
MainMsg
) or for an action queue (replace object with Action
). Replace queue_type with one of direct
, linkedlist
or fixedarray
(which are in-memory queues), or disk
.Direct Queues
$objectQueueType Direct
MainMsg
or with Action
to use this option to the main message queue or for an action queue respectively. With direct queue, messages are passed directly and immediately from the producer to the consumer.Disk Queues
/etc/rsyslog.conf
:$objectQueueType Disk
MainMsg
or with Action
to use this option to the main message queue or for an action queue respectively. Disk queues are written in parts, with a default size 10 Mb. This default size can be modified with the following configuration directive:$objectQueueMaxFileSize size
$objectQueueFilename name
In-memory Queues
$ActionQueueSaveOnShutdown
setting to save the data before shutdown. There are two types of in-memory queues:-
FixedArray queue — the default mode for the main message queue, with a limit of 10,000 elements. This type of queue uses a fixed, pre-allocated array that holds pointers to queue elements. Due to these pointers, even if the queue is empty a certain amount of memory is consumed. However, FixedArray offers the best run time performance and is optimal when you expect a relatively low number of queued messages and high performance.
-
LinkedList queue — here, all structures are dynamically allocated in a linked list, thus the memory is allocated only when needed. LinkedList queues handle occasional message bursts very well.
$objectQueueType LinkedList
$objectQueueType FixedArray
MainMsg
or with Action
to use this option to the main message queue or for an action queue respectively.Disk-Assisted In-memory Queues
$objectQueueFileName
directive to define a file name for disk assistance. This queue then becomesdisk-assisted, which means it couples an in-memory queue with a disk queue to work in tandem.$objectQueueHighWatermark number
$objectQueueLowWatermark number
MainMsg
or with Action
to use this option to the main message queue or for an action queue respectively. Replace number with a number of enqueued messages. When an in-memory queue reaches the number defined by the high watermark, it starts writing messages to disk and continues until the in-memory queue size drops to the number defined with the low watermark. Correctly set watermarks minimize unnecessary disk writes, but also leave memory space for message bursts since writing to disk files is rather lengthy. Therefore, the high watermark must be lower than the whole queue capacity set with $objectQueueSize. The difference between the high watermark and the overall queue size is a spare memory buffer reserved for message bursts. On the other hand, setting the high watermark too low will turn on disk assistance unnecessarily often.Example 20.12. Reliable Forwarding of Log Messages to a Server
UDP
protocol.Procedure 20.1. Forwarding To a Single Server
-
Use the following configuration in
/etc/rsyslog.conf
or create a file with the following content in the/etc/rsyslog.d/
directory:$ActionQueueType LinkedList $ActionQueueFileName example_fwd $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on *.* @@example.com:6514
Where:-
$ActionQueueType
enables a LinkedList in-memory queue, -
$ActionFileName
defines a disk storage, in this case the backup files are created in the/var/lib/rsyslog/
directory with the example_fwd prefix, -
the
$ActionResumeRetryCount -1
setting prevents rsyslog from dropping messages when retrying to connect if server is not responding, -
enabled
$ActionQueueSaveOnShutdown
saves in-memory data if rsyslog shuts down, -
the last line forwards all received messages to the logging server, port specification is optional.
With the above configuration, rsyslog keeps messages in memory if the remote server is not reachable. A file on disk is created only if rsyslog runs out of the configured memory queue space or needs to shut down, which benefits the system performance. -
Procedure 20.2. Forwarding To Multiple Servers
-
Each destination server requires a separate forwarding rule, action queue specification, and backup file on disk. For example, use the following configuration in
/etc/rsyslog.conf
or create a file with the following content in the/etc/rsyslog.d/
directory:$ActionQueueType LinkedList $ActionQueueFileName example_fwd1 $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on *.* @@example1.com $ActionQueueType LinkedList $ActionQueueFileName example_fwd2 $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on *.* @@example2.com
syslogd
daemon and is managed by SELinux. Therefore all files to which rsyslog is required to write to, must have the appropriate SELinux file context.Procedure 20.3. Creating a New Working Directory
-
If required to use a different directory to store working files, create a directory as follows:
~]#
mkdir
/rsyslog
-
Install utilities to manage SELinux policy:
~]#
yum install policycoreutils-python
-
Set the SELinux directory context type to be the same as the
/var/lib/rsyslog/
directory:~]#
semanage fcontext -a -t syslogd_var_lib_t /rsyslog
-
Apply the SELinux context:
~]#
restorecon -R -v /rsyslog
restorecon reset /rsyslog context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:syslogd_var_lib_t:s0 -
If required, check the SELinux context as follows:
~]#
ls -Zd /rsyslog
drwxr-xr-x. root root system_u:object_r:syslogd_var_lib_t:s0 /rsyslog -
Create subdirectories as required. For example:
~]#
mkdir
/rsyslog/work/
The subdirectories will be created with the same SELinux context as the parent directory.
-
Add the following line in
/etc/rsyslog.conf
immediately before it is required to take effect:$WorkDirectory /rsyslog/work
This setting will remain in effect until the next
WorkDirectory
directive is encountered while parsing the configuration files.
Limiting Queue Size
$objectQueueHighWatermark number
MainMsg
or with Action
to use this option to the main message queue or for an action queue respectively. Replace number with a number of enqueued messages. You can set the queue size only as the number of messages, not as their actual memory size. The default queue size is 10,000 messages for the main message queue and ruleset queues, and 1000 for action queues.$objectQueueMaxDiscSpace number
MainMsg
or with Action
. When the size limit specified by number is hit, messages are discarded until sufficient amount of space is freed by dequeued messages.Discarding Messages
$objectQueueDiscardMark number
MainMsg
or with Action
to use this option to the main message queue or for an action queue respectively. Here, number stands for a number of messages that have to be in the queue to start the discarding process. To define which messages to discard, use:$objectQueueDiscardSeverity priority
debug
(7), info
(6), notice
(5), warning
(4), err
(3), crit
(2), alert
(1), and emerg
(0). With this setting, both newly incoming and already queued messages with lower than defined priority are erased from the queue immediately after the discard mark is reached.Using Timeframes
$objectQueueDequeueTimeBegin hour
$objectQueueDequeueTimeEnd hour
Configuring Worker Threads
$objectQueueWorkerThreadMinimumMessages number
$objectQueueWorkerThreads number
$objectQueueWorkerTimeoutThreadShutdown time
-1
, no thread will be closed.Batch Dequeuing
$objectQueueDequeueBatchSize number
Terminating Queues
$objectQueueTimeoutShutdown time
$objectQueueTimeoutActionCompletion time
$objectQueueTimeoutSaveOnShutdown time
action()
object that can be used both separately or inside a ruleset in /etc/rsyslog.conf
. The format of an action queue is as follows:action(type="action_type" queue.size="queue_size" queue.type="queue_type" queue.filename="file_name")
disk
or select from one of the in-memory queues: direct
, linkedlist
or fixedarray
. For file_name specify only a file name, not a path. Note that if creating a new directory to hold log files, the SELinux context must be set. See Section 20.4.2, “Creating a New Directory for rsyslog Log Files” for an example.Example 20.13. Defining an Action Queue
action(type="omfile" queue.size="10000" queue.type="linkedlist" queue.filename="logfile")
*.* action(type="omfile" file="/var/lib/rsyslog/log_file )
*.* action(type="omfile" queue.filename="log_file" queue.type="linkedlist" queue.size="10000" )
The default work directory, or the last work directory to be set, will be used. If required to use a different work directory, add a line as follows before the action queue:
global(workDirectory="/directory")
Example 20.14. Forwarding To a Single Server Using the New Syntax
omfwd
plug-in is used to provide forwarding over UDP
or TCP
. The default is UDP
. As the plug-in is built in it does not have to be loaded./etc/rsyslog.conf
or create a file with the following content in the /etc/rsyslog.d/
directory:
*.* action(type="omfwd" queue.type="linkedlist" queue.filename="example_fwd" action.resumeRetryCount="-1" queue.saveOnShutdown="on" target="example.com" port="6514" protocol="tcp" )
-
queue.type="linkedlist"
enables a LinkedList in-memory queue, -
queue.filename
defines a disk storage. The backup files are created with the example_fwd prefix, in the working directory specified by the preceding globalworkDirectory
directive, -
the
action.resumeRetryCount -1
setting prevents rsyslog from dropping messages when retrying to connect if server is not responding, -
enabled
queue.saveOnShutdown="on"
saves in-memory data if rsyslog shuts down, -
the last line forwards all received messages to the logging server, port specification is optional.