From 5dd8afda3ec83d245a4708638a40ca267d0dfed0 Mon Sep 17 00:00:00 2001 From: Tamaki Nishino Date: Fri, 20 Oct 2017 21:50:08 +0900 Subject: journal: allow JournalHandler constructor to be called with args in a positional param This change enables to add extra fields to JournalHandler in a configuration file loaded by `logging.config.fileConfig`, which only allows positional parameters: class=systemd.journal.JournalHandler args={'level': INFO, 'SYSLOG_IDENTIFIER': 'my-cool-app'} [zj: originally the patch added a new positional parameter to __init__(), but that is not backwards compatible. So I added a new classmethod to allow the positional parameters to be passed.] --- systemd/journal.py | 14 ++++++++++++++ systemd/test/test_journal.py | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/systemd/journal.py b/systemd/journal.py index 4168dec..64502ce 100644 --- a/systemd/journal.py +++ b/systemd/journal.py @@ -565,6 +565,20 @@ class JournalHandler(_logging.Handler): self.send = sender_function self._extra = kwargs + @classmethod + def with_args(cls, config=None): + """Create a JournalHandler with a configuration dictionary + + This creates a JournalHandler instance, but accepts the parameters through + a dictionary that can be specified as a positional argument. This is useful + in contexts like logging.config.fileConfig, where the syntax does not allow + for positional arguments. + + >>> JournalHandler.with_args({'SYSLOG_IDENTIFIER':'my-cool-app'}) + <...JournalHandler ...> + """ + return cls(**(config or {})) + def emit(self, record): """Write `record` as a journal event. diff --git a/systemd/test/test_journal.py b/systemd/test/test_journal.py index 49e4279..2f3cd3b 100644 --- a/systemd/test/test_journal.py +++ b/systemd/test/test_journal.py @@ -82,10 +82,14 @@ def test_journalhandler_init_exception(): kw = {' X ':3} with pytest.raises(ValueError): journal.JournalHandler(**kw) + with pytest.raises(ValueError): + journal.JournalHandler.with_args(kw) def test_journalhandler_init(): kw = {'X':3, 'X3':4} journal.JournalHandler(logging.INFO, **kw) + kw['level'] = logging.INFO + journal.JournalHandler.with_args(kw) def test_journalhandler_info(): record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) @@ -98,6 +102,16 @@ def test_journalhandler_info(): assert 'X=3' in sender.buf[0] assert 'X3=4' in sender.buf[0] + sender = MockSender() + handler = journal.JournalHandler.with_args({'level':logging.INFO, 'X':3, 'X3':4, 'sender_function':sender.send}) + handler.emit(record) + assert len(sender.buf) == 1 + assert 'X=3' in sender.buf[0] + assert 'X3=4' in sender.buf[0] + + # just check that args==None doesn't cause an error + journal.JournalHandler.with_args() + def test_journalhandler_no_message_id(): record = logging.LogRecord('test-logger', logging.INFO, 'testpath', 1, 'test', None, None) sender = MockSender() -- cgit v1.2.1