微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从Python脚本中读取systemd日志

我试图使用systemd库在Python中模拟这个shell命令
http://www.freedesktop.org/software/systemd/python-systemd/journal.html

我实际上是试图在Python中模拟这个命令.

journalctl --since=-5m --no-pager

我已经看到其他人通过调用日志可执行文件在Python中执行此操作,但这是一种非常糟糕的方法.

我根据上面链接的文档编写了这个简单的脚本

import select
from systemd import journal

j = journal.Reader()
j.log_level(journal.LOG_INFO)
# j.add_match(_SYstemD_UNIT="systemd-udevd.service")

j.seek_tail()
j.get_next()

while j.get_next():
    for entry in j:
        if entry['MESSAGE'] != "":
            print(str(entry['__REALTIME_TIMESTAMP'] )+ ' ' + entry['MESSAGE'])

这里有一些问题

>日志似乎从大约5天前开始,这意味着seek_tail似乎不起作用.
>我在这里得到了很多垃圾是否有一个特定的过滤器我应该用来匹配我从问题开头给出的journalctl命令得到的数据?

理想情况下,我希望仅根据一组过滤器/匹配来跟踪此日志,以模拟命令’journalctl -f’,但我只需要首先解决此问题.我想最终得到这样的东西,但它也不起作用.

import select
from systemd import journal

j = journal.Reader()
j.log_level(journal.LOG_INFO)

# j.add_match(_SYstemD_UNIT="systemd-udevd.service")
j.seek_tail()

p = select.poll()
p.register(j, j.get_events())
while p.poll():

    while j.get_next():
        for entry in j:
            if entry['MESSAGE'] != "":
                print(str(entry['__REALTIME_TIMESTAMP'] )+ ' ' + entry['MESSAGE'])

解决方法:

我也在研究类似的python模块.

根据以下链接,我们必须调用sd_journal_prevIoUs(在python systemd模块中,即journal.Reader().get_prevIoUs()).

http://www.freedesktop.org/software/systemd/man/sd_journal_seek_tail.html

https://bugs.freedesktop.org/show_bug.cgi?id=64614

此外,您的示例代码将占用80-100%的cpu负载,因为即使在获得条目后,读取器的状态仍然是“可读”的,这导致了太多的poll().

根据以下链接,似乎我们必须在每次poll()之后调用sd_journal_process(在python systemd模块中,即journal.Reader().process()),以便重置文件描述符的可读状态.

http://www.freedesktop.org/software/systemd/man/sd_journal_get_events.html

总之,您的示例代码是,

import select
from systemd import journal

j = journal.Reader()
j.log_level(journal.LOG_INFO)

# j.add_match(_SYstemD_UNIT="systemd-udevd.service")
j.seek_tail()
j.get_prevIoUs()
# j.get_next() # it seems this is not necessary.

p = select.poll()
p.register(j, j.get_events())

while p.poll():
    if j.process() != journal.APPEND:
        continue

    # Your example code has too many get_next() (i.e, "while j.get_next()" and "for event in j") which cause skipping entry.
    # Since each iteration of a journal.Reader() object is equal to "get_next()", just do simple iteration.
    for entry in j:
        if entry['MESSAGE'] != "":
            print(str(entry['__REALTIME_TIMESTAMP'] )+ ' ' + entry['MESSAGE'])

编辑:
在j.get_prevIoUs()之后删除了“j.get_next()”.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐