Python 2.7与TCP错误地聚合了系统日志消息,与UDP一起正常工作

时间:2019-06-12 16:30:33

标签: python logging tcp udp syslog

使用Linux Mint 19.1随附的Python 2.7.15rc1,我正在syslog将一些数据添加到rsyslog 8.32.0-1ubuntu4。通过TCP这样做会错误地将多个日志消息链接到/ var / log / syslog中的一行中,而UDP正确地不会进行这种聚合。

为了可靠性,我想使用TCP而不是UDP,但是我需要未分类的输出。

如果我从以下位置更改程序中的一行:

socktype = socket.SOCK_DGRAM

...至:

socktype = socket.SOCK_STREAM

...然后事情开始变得怪异。一行是从已知有效的代码复制问题所需的唯一代码更改。

这是我获取日志记录处理程序的方式:

handler = logging.handlers.SysLogHandler(address=address, socktype=socktype)

在良好情况下(使用UDP)的日志消息如下所示(对于EG):

Jun 11 15:59:25 2019-06-11 15: 59:25,870|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading xgb_factory
Jun 11 15:59:25 2019-06-11 15: 59:25,871|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading lgb_factory
Jun 11 15:59:25 2019-06-11 15: 59:25,871|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading rf_factory
Jun 11 15:59:39 2019-06-11 15: 59:39,161|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading xgb_factory
Jun 11 15:59:39 2019-06-11 15: 59:39,161|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading lgb_factory
Jun 11 15:59:39 2019-06-11 15: 59:39,162|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading rf_factory

在恶劣情况下(使用TCP)的日志消息看起来像(对于EG):

Jun 11 11:55:04 2019-06-11 11: 53:43,139|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading xgb_factory#000<14>2019-06-11 11:53:43,140|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading lgb_factory#000<14>2019-06-11 11:53:43,141|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading rf_factory#000<14>2019-06-11 11:53:57,842|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading xgb_factory#000<14>2019-06-11 11:53:57,843|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading lgb_factory#000<14>2019-06-11 11:53:57,843|_|INFO|_|dstromberg-inspiron-5570|_|domain.classifier.factories.classifier_academy|_|classifier_academy.py|_|load|_|132|_|loading rf_factory

在TCP情况下,时间戳始终具有该虚假空间(“ 2019-06-11 11:53:43,139”中的小时后的ASCII 32),并且已将多个消息组合为单个消息。这些消息似乎带有类似“#000 <14>”的内容。 #000部分是一致的,但数字部分(在这种情况下为14)会随着入射而变化。但是,它始终是一个很小的整数。

这是SyslogHandler中的错误吗?这是一个已知问题吗?除了切换到UDP,还有谁知道修复程序吗?

我正在做的唯一的甚至是不寻常的事情(除了TCP上的syslog之外)都是添加一个过滤器来添加一个(docker)主机名。看起来就像:

class ContainerFilter(logging.Filter):
    """This is a filter that just adds the container name (hostname)."""

    def __init__(self, name='', container_id=None):
        """Initialize."""
        super(ContainerFilter, self).__init__(name)
        self.container_id = container_id

    def filter(self, record):
        """Set record's metric and container_id attributes, if available."""
        record.container = self.container_id
        return True

filter_ = ContainerFilter(container_id=_DOCKER_CONTAINER_ID)
handler.addFilter(filter_)

我认为那件事真是个纳格尔的事。

关于TCP与UDP-我喜欢TCP的可靠性,而且我喜欢它在不工作时会出现异常,而不仅仅是丢弃消息。

另外:我知道不久将不支持Python 2.x,但是此特定代码将在2.x上使用更长的时间。

0 个答案:

没有答案