Have Python log to syslog
This article documents how I set up Python and the syslog daemon so that Python programs can log to syslogd.
Introduction
UNIX-like systems generally have a syslogd
daemon running so that the
kernel and other programs can log important events.
By default, the Python logging
module writes output to the console.
This is not handy when you have a program that is not started from the
console.
So you might want to log to a file instead.
This is what I originally did for my statusline-i3
script.
Over time this generates a lot of log files that I had to clean up manually.
So I decided to switch to the built-in syslogd service. This writes logfiles in one place, and rotates them if desired.
Configuring the syslogd service
The syslogd
service is pretty sophisticated. It can be configured to route
messages from different facilities and different levels to different files and
even to different hosts.
Python uses the LOG_USER
facility by default. On FreeBSD this is the default facility.
On FreeBSD, LOG_USER
is generally not configured to be saved to a file.
Since a lot of programs use it for low-priority messages, there is a lot of
traffic to this facility.
So I decided to use the LOG_LOCAL3
facility, and route that to a special file.
Note
The following is geared toward the BSD family of operating systems.
On Linux e.g. /etc/syslog-ng.conf
or /etc/rsyslog.conf
might be
used instead of /etc/syslog.conf
. Some older UNIX systems only accept
tab characters between the selector and action fields. The proper way to
restart the syslog daemon also differs between systems.
To that end, I added the following to my /etc/syslog.conf
file:
local3.* /var/log/user.log
Since /var/log/messages
gets all messages of level notice
or higher by
default, I changed that to exclude messages to local3
:
*.notice;local3.none;mail.none;authpriv.none /var/log/messages
Next I created the logfile with permissions for all to read it, and restarted the syslog daemon.
# touch /var/log/user.log
# chmod 644 /var/log/user.log
# service syslogd restart
For now, I have not configured logfile rotation.
Configure Python for logging to syslogd
Note that I’m re-configuring the root logger here, so that all log messages go to syslogd.
import os
import logging
from logging.handlers import SysLogHandler
syslog = SysLogHandler(address='/var/run/log', facility=SysLogHandler.LOG_LOCAL3)
pid = os.getpid()
syslog.ident = f'progname[{pid}]: '
logging.basicConfig(
level='INFO',
format='%(levelname)s: %(message)s',
handlers=(syslog,)
)
The essential bits are;
- to create a
SysLogHandler
configured for the right address and facility, - setting the
ident
of theSysLogHandler
class to the name and PID of the program and - using said handler in the basic configuration of the logging module.
The level
and format
configuration parameters above are a personal preference.
Note
Both FreeBSD and macOS require that you use /var/run/log
as the
UNIX domain socket address.
For comments, please send me an e-mail.
Related articles
- Attempting a conky replacement in Python (part 2)
- Attempting a conky replacement in Python (part 1)
- Setting the Razer ornata chroma color from userspace
- Updating python3 to 3.6
- Switching IPython to Python 3