FreeBSD System Logging in Production: syslogd, newsyslog, and Rotation
Route FreeBSD system and application messages with facility-aware syslogd rules, safe newsyslog rotation, retention budgets, and verifiable recovery.
FreeBSD’s base logging path is deliberately small: programs submit messages through the system logging interface, syslogd(8) applies rules from syslog.conf(5), and selected messages are written to files, the console, users, or configured destinations. newsyslog(8) rotates and archives files so they do not grow without bound. These pieces solve different problems: routing decides where a message goes, rotation limits the active file, and retention determines how long evidence remains available.
A reliable design makes each boundary explicit. Decide which application owns each facility, what priority threshold should be recorded, how much disk the archive set may consume, and how a writer learns that a file has been rotated. A daemon still writing to an old open file is not fixed by a successful newsyslog exit. Verify the real log path and the writer’s reopen behavior as one tested lifecycle.
Map the message path before editing rules
syslogd handles messages from the kernel, base daemons, and applications using the syslog API. A syslog message carries a facility that identifies its source class and a priority that indicates severity. FreeBSD facilities include auth, cron, daemon, kern, mail, user, and local0 through local7. The priority order from most to least urgent is emerg, alert, crit, err, warning, notice, info, and debug.
By default, a selector such as daemon.notice matches the selected facility at that priority and more urgent priorities. It does not mean “notice only.” To select exactly one level, use the documented comparison form such as daemon.=notice. This distinction matters when a rule is intended to reduce volume: an accidentally broad selector can duplicate large amounts of data into another file.
Inspect the active configuration, sockets, service flags, and the current mount before deciding where logs belong:
sed -n '1,240p' /etc/syslog.conf
sysrc syslogd_enable syslogd_flags
sockstat -u -l | grep syslogd
df -h /var/log
Do not assume the local machine uses the stock configuration unchanged. FreeBSD supports include directives and service flags; a package or administrator may add rules in included directories. syslogd also has secure-mode options that govern whether it accepts remote messages. This article focuses on local system and application logs, not on designing a remote logging transport.
Give an application a stable facility
When an application uses syslog(3), assign it a facility that is not already overloaded. The local0 through local7 facilities are conventional choices for site-defined applications. Configure the application itself to use the chosen facility where possible. Avoid matching only a program-name string when the facility is a more stable contract; program tags can change across wrappers, service managers, and platform ports.
For a service that emits local0 messages, a narrow rule can route them to a dedicated file:
# /etc/syslog.conf
local0.* /var/log/inventory.log
The spaces or tabs separate the selector and action. local0.* accepts all priorities for that facility. If the operational contract needs only notice and more severe events, use local0.notice; if it needs debug-level data for a bounded diagnostic period, define that consciously and size the file accordingly. A line such as local0.=notice is different: it matches only notice priority.
Create the destination with deliberate ownership and mode, then reload the logger using the service path documented for the system:
if [ ! -e /var/log/inventory.log ]; then
install -o root -g wheel -m 0640 /dev/null /var/log/inventory.log
fi
chown root:wheel /var/log/inventory.log
chmod 0640 /var/log/inventory.log
service syslogd restart
logger -p local0.notice -t inventory-import "FreeBSD syslog routing test"
grep -F "FreeBSD syslog routing test" /var/log/inventory.log
The logger(1) command proves that a message with that priority and tag reached a file; it does not prove that the application uses the same facility or that every important event is emitted. Test one success, one expected error path, and any structured metadata the application promises. Do not add a second broad catch-all rule without checking whether the same message is already recorded in /var/log/messages.
Design rotation as a writer protocol
newsyslog is normally invoked periodically by cron. In the default FreeBSD configuration it is run hourly, so a size threshold is checked on that cadence rather than continuously. It can rotate based on file size, elapsed interval, or a configured time. If a file grows faster than the check interval can tolerate, an hourly policy may leave it oversized until the next run; choose a threshold and schedule based on peak write rate and disk headroom.
Each newsyslog.conf(5) entry names a file, optional archive owner and group, mode, archive count, size threshold, time condition, flags, and optional process identifier or command. An entry for the syslogd-owned file above can look like this:
# logfile owner:group mode count size when flags
/var/log/inventory.log root:wheel 0640 14 10M * J
This example retains up to fourteen archived files, requests rotation when the active log reaches 10 MiB, and marks archives compressible using the historical J behavior (bzip2 when the default legacy compression mode is in effect). The * in the time field means rotation depends on size. Confirm the site’s <compress> setting before assuming the archive algorithm. Do not copy the size, count, or permissions without estimating the real workload and the sensitivity of its messages.
When no process-ID field is provided and the N flag is absent, newsyslog sends SIGHUP to syslogd after rotating the file. This is the expected reopen protocol for a file written by syslogd. A custom application that opens its own file needs its own documented reopen signal or command; use the PID or command field and correct signal for that application. Conversely, N explicitly says no process needs a signal. Adding N to a file still held open by a daemon can make the pathname look fresh while the old process continues writing to the rotated inode.
The C flag has a limited meaning: newsyslog can create a missing configured file when invoked with its -C behavior. It should not be treated as a promise that every periodic run creates every missing file. Provision the active file with the intended owner and mode, or deliberately test the -C path. Keep one rotation entry per path; the manual warns that duplicate lines can rotate a file multiple times.
Size retention from observed volume
Choose retention as a storage budget, not an arbitrary count. If the service produces 2 MiB per hour, a 10 MiB size threshold may rotate roughly every five hours under steady traffic, while fourteen archives cover only about three days before accounting for compression and burst variation. If a legal, incident-response, or operations policy requires a duration, calculate a worst-case archive budget from peak log rate, archive count, filesystem reserve, and rotation delay.
Remember that newsyslog count is the number of archives, not the active file. Compression reduces space only after rotation and varies with message content. A large error storm can fill the filesystem before the next scheduled check. Monitor /var free space, active-file size, archive count and age, newsyslog exit status, and the age of the newest expected application message. Alert before the filesystem reaches a level that could affect unrelated services.
Permissions apply to both the active file and its rotated archives. Choose a mode that lets the intended operator read logs without exposing data to every local account. If the application runs under an unprivileged UID and writes directly to a file, make ownership consistent with its service account and its rotation procedure. Syslogd-owned output is different: the application submits a message to the logger and does not need direct write access to the destination file.
Test the configuration without forcing production rotation
Start with a dry run. newsyslog -n reports what it would do without trimming logs; -v adds detail. Use this before deploying a threshold or schedule change:
newsyslog -n -v
newsyslog -n -v -f /etc/newsyslog.conf
Then validate the actual path in a maintenance window or on staging: create a known test message, inspect the active file, trigger a test rotation for that file, confirm a correctly named archive appears, confirm the writer resumes on the new active file, and verify that permissions and compression match the policy. A forced rotation is a real change, not a parser check. Do not use it on a production log merely to see whether the command works.
After rotation, confirm that syslogd is running and that a new test message reaches the active pathname rather than an archive that is still held open. For an application-owned log, inspect the process’s open files with fstat or its own diagnostic interface and prove that its reopen signal worked. Check the result after an actual restart as well as after routine rotation.
Keep log roles separate and recoverable
System logs, application logs, and security audit trails are not interchangeable. Syslog priorities are not a complete event taxonomy, and a successful local file write does not establish immutable evidence or an off-host copy. Preserve the configuration alongside operational runbooks, record expected volumes, and test recovery from archived logs. If an audit facility has its own daemon and rotation mechanism, follow that mechanism instead of applying a general newsyslog recipe to its live trail.
A production logging check should verify four outcomes: the expected message is emitted, its facility and priority route it to the intended destination, the active file and archive set stay within the capacity budget, and the writer continues after rotation. If any one of those is untested, a configuration that parses may still lose the event you expected to find later.
Related:
- FreeBSD’s rc.d Init System: Scripts, Dependencies, and Service Ordering
- How to Configure Audit(4) for Security Event Logging on FreeBSD
Sources: