From 63179540fb514c54cd91b921e24b7061da31757f Mon Sep 17 00:00:00 2001 From: Julien Clarysse Date: Thu, 11 Dec 2025 10:28:44 +0100 Subject: [PATCH] rsyslog: replace conf truncate_multiline by octet_counted_framing The recently added config `truncate_multiline`(PR #180 and #181) might raise wrong user expectation as it relies on a workaround that is not supported by all syslog servers. I propose to keep this dev but rename the config to `octet_counted_framing` which is what it actually does, and inverse the value. This should avoid confusion and prevent any future misuse. --- README.rst | 4 ++-- journalpump/rsyslog.py | 15 ++++++++------- journalpump/senders/rsyslog.py | 2 +- systest/test_rsyslog.py | 12 ++++++------ 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/README.rst b/README.rst index a8ab9c1..842d22e 100644 --- a/README.rst +++ b/README.rst @@ -567,10 +567,10 @@ timestamp:::date-rfc3339, HOSTNAME, app-name, procid, msgid, msg and structured- For example the rfc3164 log format would be defined as `<%pri%>%timestamp% %HOSTNAME% %app-name%[%procid%]: %msg%` -``truncate_multiline`` (default ``true``) +``octet_counted_framing`` (default ``false``) By default, log messages are sent using non-transparent framing and are terminated by newline. -Set it to ``false`` if the server supports octet-counted framing and messages are multi-line. +Set it to ``true`` if the server supports octet-counted framing and messages are multi-line. (see `RFC 6587 for Syslog over TCP message transfer `_) ``structured_data`` (default ``null``) diff --git a/journalpump/rsyslog.py b/journalpump/rsyslog.py index c0396d2..0bc6a20 100644 --- a/journalpump/rsyslog.py +++ b/journalpump/rsyslog.py @@ -86,7 +86,7 @@ def __init__( keyfile=None, certfile=None, log_format=None, - truncate_multiline=None, + octet_counted_framing=None, ): self.socket = None self.server = server @@ -94,7 +94,7 @@ def __init__( self.max_msg = max_msg or 2048 self.socket_proto = socket.SOCK_STREAM self.ssl_context = None - self.truncate_multiline = True if truncate_multiline is None else truncate_multiline + self.octet_counted_framing = False if octet_counted_framing is None else octet_counted_framing if rfc == "RFC5424": self.formatter = _rfc_5424_formatter elif rfc == "RFC3164": @@ -161,12 +161,13 @@ def send(self, message): # length and a space ( ). # - Non-transparent framing: Each message is terminated by a # newline (\n). - # So far, non-transparent framing was used by journalpump, - # and multi-line log messages were truncated to 1st line. + # So far, only non-transparent framing was used by journalpump + # and multi-line log messages were terminated at first newline. # We keep this behavior by default, but now expose a new config - # allowing to switch to octet-counted framing, so that - # multi-line log messages only get truncated by max size. - if not self.truncate_multiline: + # allowing to switch to octet-counted framing. Provided that this + # method is supported by the syslog server, multi-line messages + # will only get truncated according to the max_message_size. + if self.octet_counted_framing: message = f"{len(message)} ".encode("utf-8") + message self.socket.sendall(message[: self.max_msg - 1]) diff --git a/journalpump/senders/rsyslog.py b/journalpump/senders/rsyslog.py index ec276ec..cd51da5 100644 --- a/journalpump/senders/rsyslog.py +++ b/journalpump/senders/rsyslog.py @@ -45,7 +45,7 @@ def _init_rsyslog_client(self): keyfile=self.config.get("client_key"), certfile=self.config.get("client_cert"), log_format=self.config.get("logline"), - truncate_multiline=self.config.get("truncate_multiline"), + octet_counted_framing=self.config.get("octet_counted_framing"), ) self.log.info( "Initialized Rsyslog Client %s, server: %s, port: %d", diff --git a/systest/test_rsyslog.py b/systest/test_rsyslog.py index 0b00da6..63293d3 100644 --- a/systest/test_rsyslog.py +++ b/systest/test_rsyslog.py @@ -174,7 +174,7 @@ def _run_pump_test( @pytest.mark.parametrize( - "messages_to_send,truncate_multiline_config,expected_message_count,expected_multiline_support", + "messages_to_send,octet_counted_framing_config,expected_message_count,expected_multiline_support", [ ( [ @@ -189,7 +189,7 @@ def _run_pump_test( "PRIORITY": journal.LOG_CRIT, }, ], - {}, # config not specified, truncate_multiline is True by default + {}, # config not specified, octet_counted_framing is False by default 4, False, ), @@ -200,7 +200,7 @@ def _run_pump_test( "PRIORITY": journal.LOG_INFO, }, ], - {"truncate_multiline": True}, + {"octet_counted_framing": False}, 1, False, ), @@ -211,7 +211,7 @@ def _run_pump_test( "PRIORITY": journal.LOG_INFO, }, ], - {"truncate_multiline": False}, + {"octet_counted_framing": True}, 1, True, ), @@ -220,7 +220,7 @@ def _run_pump_test( def test_rsyslogd_tcp_sender( tmpdir, messages_to_send, - truncate_multiline_config, + octet_counted_framing_config, expected_message_count, expected_multiline_support, ): @@ -239,7 +239,7 @@ def test_rsyslogd_tcp_sender( "rsyslog_port": 5140, "format": "custom", "logline": "<%pri%>%timestamp% %HOSTNAME% %app-name%[%procid%]: %msg% {%%} %not-valid-tag%", - **dict(truncate_multiline_config), + **dict(octet_counted_framing_config), }, }, },