Trey Stout
Trey Stout

Reputation: 6911

How do I set the ident string when using logging.SysLogHandler in Python 2.6?

I have logging configured using logging.fileConfig(). I have a the root logger going to a handler that uses SysLogHandler('/dev/log', handlers.SysLogHandler.LOG_USER)

This all works perfectly well, and I see my log entries in /var/log/user.log

The question is how can I set the syslog ident string to something other than python? It appears the syslog module in the standard lib allows setting this when opening a log, but the logging handler doesn't offer this feature.

Would the solution be to subclass SysLogHandler and use the syslog library inside it's emit method? This is a UNIX only program, so using syslog directly doesn't pose a portability problem.

Upvotes: 10

Views: 11738

Answers (4)

Braňo Žarnovičan
Braňo Žarnovičan

Reputation: 191

Syslog implementations accepting RFC3164 messages should recognize first part of the message ("foo:" in the example) as TAG.

The MSG part has two fields known as the TAG field and the CONTENT field. The value in the TAG field will be the name of the program or process that generated the message.

Python code..

import logging
from logging.handlers import SysLogHandler

h = SysLogHandler(address='/dev/log')
h.setFormatter(logging.Formatter('foo: %(message)s'))
logging.getLogger().addHandler(h)

logging.error('bar')

..will send this into syslog socket

connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 10) = 0
sendto(3, "<11>foo: bar\0", 13, 0, NULL, 0) = 13
close(3)

Which in turn, produces this in systemd's journal.

Dec 13 14:48:20 laptop foo[1928]: bar

Journal message details:

{
  ..
  "PRIORITY" : "3",
  "SYSLOG_FACILITY" : "1",
  "SYSLOG_IDENTIFIER" : "foo",
  "MESSAGE" : "bar",
  "_PID" : "1928",
}

It works with Py2.6, 2.7, 3.4, 3.5 and Systemd's syslog server. It may work with other syslog implementations as well (if they accept RFC3164) messages. This solution will probably break when python's SysLogHandler will default to newer RFC5424.

Upvotes: 9

Mike Clark
Mike Clark

Reputation: 10136

For Python 2.7, you could do something like this:

class MySysLogHandler(logging.handlers.SysLogHandler):
    def __init__(self):
        super(MySysLogHandler, self).__init__(address='/dev/log')
    def emit(self, record):
        priority = self.encodePriority(self.facility, self.mapPriority(record.levelname))
        record.ident = "My[" + str(priority) + "]:"
        super(MySysLogHandler, self).emit(record)

handler = MySysLogHandler()
handler.formatter = logging.Formatter(fmt="%(ident)s %(levelname)s: %(message)s")
logging.root.addHandler(handler)
logging.info("hello world")

This will produce in the syslog:

Sep 3 16:28:53 hostname My[14]: INFO: hello world

Upvotes: 2

FirefighterBlu3
FirefighterBlu3

Reputation: 419

This is a bit old but new information should be recorded here so people don't feel the need to write their own syslog handler.

Since Python 3.3, the SysLogHandler has a class attribute of .ident precisely for this purpose; the default for it is ''.

Example:

import logging
from logging.handlers import SysLogHandler

h = SysLogHandler(address=('some.destination.com',514), facility=SysLogHandler.LOG_LOCAL6)
h.setFormatter(
    logging.Formatter('%(name)s %(levelname)s %(message)s')
)
h.ident = 'conmon'

syslog = logging.getLogger('syslog')
syslog.setLevel(logging.DEBUG)
syslog.addHandler(h)

syslog.debug('foo syslog message')

Upvotes: 10

Vinay Sajip
Vinay Sajip

Reputation: 99415

AFAIK, the ident string is an artifact of the syslog API, see this page. It's just using the C argv[0] which would of course be "python".

I'm surprised that you're getting this using SysLogHandler with a domain socket, as the message sent to syslog daemons across domain or TCP sockets is just a string with the priority in <angle brackets> followed by the formatted message and a NUL byte. There's no ident string specified by SysLogHandler, as it doesn't use the syslog API (which has some thread-safety issues in some versions, IIRC).

Upvotes: 4

Related Questions