[systemd-devel] [PATCH v2] systemd-python: attach fields to JournalHandler, add SYSLOG_IDENTIFIER

Steven Hiscocks steven-systemd at hiscocks.me.uk
Wed Apr 24 12:51:47 PDT 2013


On 24/04/13 03:10, Zbigniew Jędrzejewski-Szmek wrote:
> Arbitrary fields can be attached at the level of the handler,
> and they'll be sent with all messages from this handler.
>
> This facility is used to attach SYSLOG_IDENTIFIER to all messages,
> since otherwise journald attaches SYSLOG_IDENTIFIER=python or
> something similar, which is completely useless.
> ---
> This is part (a) in my email. I think it can go in as is,
> independently of other potential improvements.
>
> Zbyszek
>
Like it. I'm particularly keen to see (c) implemented as well, so I went 
and had a stab at it. I can now see your point Marti about the python 
logging module not being the easiest to work with without getting ugly 
very quickly :)

I thought I'd share my hacking about for interest. Works by:
     import logging, sys
     from systemd import journal
     logging.setLoggerClass(journal.JournalLogger)

     log = logging.getLogger("mylogger")
     log.addHandler(journal.JournalHandler(TEST_FIELD="Default"))
     log.addHandler(logging.StreamHandler(sys.stdout))

     log.warn("Message1")
     log.warn("Message2", systemd_fields={"TEST_FIELD2": "Value"})
     log.warn("Message3", systemd_fields={"TEST_FIELD": "Not Default"})

diff --git a/src/python-systemd/journal.py b/src/python-systemd/journal.py
index 7d42525..6a3ad36 100644
--- a/src/python-systemd/journal.py
+++ b/src/python-systemd/journal.py
@@ -437,6 +437,17 @@ def stream(identifier, priority=LOG_DEBUG, 
level_prefix=False):
          fd = stream_fd(identifier, priority, level_prefix)
          return _os.fdopen(fd, 'w', 1)

+class JournalLogger(_logging.Logger):
+
+    def _log(self, *args, **kwargs):
+        self._systemd_fields = kwargs.pop("systemd_fields", dict())
+        super(JournalLogger, self)._log(*args, **kwargs)
+
+    def makeRecord(self, *args, **kwargs):
+        rv = super(JournalLogger, self).makeRecord(*args, **kwargs)
+        rv.__dict__["systemd-fields"] = self._systemd_fields
+        return rv
+
  class JournalHandler(_logging.Handler):
          """Journal handler class for the Python logging framework.

@@ -508,6 +519,8 @@ class JournalHandler(_logging.Handler):
                          msg = self.format(record)
                          pri = self.mapPriority(record.levelno)
                          mid = getattr(record, 'MESSAGE_ID', None)
+                        extra = self._extra.copy()
+                        extra.update(getattr(record, 'systemd-fields', 
dict()))
                          send(msg,
                               MESSAGE_ID=mid,
                               PRIORITY=format(pri),
@@ -516,7 +529,7 @@ class JournalHandler(_logging.Handler):
                               CODE_FILE=record.pathname,
                               CODE_LINE=record.lineno,
                               CODE_FUNC=record.funcName,
-                             **self._extra)
+                             **extra)
                  except Exception:
                          self.handleError(record)


-- 
Steven Hiscocks


More information about the systemd-devel mailing list