Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Python脚本读取systemd日志_Python_Systemd_Journal - Fatal编程技术网

从Python脚本读取systemd日志

从Python脚本读取systemd日志,python,systemd,journal,Python,Systemd,Journal,我试图使用systemd库在Python中模拟这个shell命令 实际上,我试图在Python中模拟这个命令 journalctl --since=-5m --no-pager 我见过其他人在Python中通过调用日志可执行文件来实现这一点,但这是一种非常糟糕的方式 我根据上面链接的文档编写了这个简单的脚本 import select from systemd import journal j = journal.Reader() j.log_level(journal.LOG_INFO)

我试图使用systemd库在Python中模拟这个shell命令

实际上,我试图在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\u journal\u previous(在python systemd模块中,即
    journal.Reader().get\u previous()

    此外,您的示例代码将消耗80-100%的CPU负载,因为即使在获取条目后,读卡器的状态仍保持“可读”,这将导致过多的
    poll()

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

    总之,您的示例代码是:

    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'])
    

    前面的答案是有效的,关于在seek_tail()之后调用get_next()的提示确实很重要

    一种更简单的方法是(但显然,在更大的应用程序中,使用轮询的早期版本更灵活)

    如果您想详细观察正在发生的事情,以下支持调试输出的版本可能会有所帮助(使用一些参数调用它将启用该功能)


    对我来说,它总是导致一开始就失效。我不知道这到底意味着什么。如果某个用作迭代器的东西无效,我可能会以某种方式重新创建/重新打开/刷新它。但至少在我的基本测试过程中,上面的代码可以正常工作。不确定是否会有任何比赛条件。事实上,我很难解释该代码是如何不受种族限制的。

    这太棒了,因为它看起来很有效。我确实怀疑seek_tail后跟get_事件可能会导致它循环回到开始。我愚蠢地从未想过尝试上一个然后下一个。现在,要处理loglevel,命令journalctl-f中的信息似乎比使用loglevel时更多。infoevent loglevel.DEBUG显示的信息比命令“journalctl-f”少。python脚本似乎没有捕获到启动和停止服务之类的内容。但我没有以root用户身份运行脚本。嗯!!!感谢您的帮助,它现在工作得很好。我发现似乎“j.get_next()”(在j.get_previous()之后)是不必要的。有一种方法
    可靠的\u fd()
    。是否需要在投票前调用?我不知道在什么情况下这可能是假的。当我叫它时,它又变成了真的。可能它在非持久性日志上不起作用?请不要使用INVALIDATE删除事件。它只是一个标志,告诉客户端清除/刷新其显示,而不是附加新消息。@leoluk您能解释一下a.)客户端b.)清除刷新其显示是什么意思吗?以前显示的所有事件都无效?在什么情况下会发生这种情况?已经有一段时间没有使用它了,但是在我上面的回答中,INVALIDATE总是作为第一个事件出现。因此,在这种情况下,将不会有真正的清除/刷新。除非程序仍然显示来自不同机器或以前引导的内容,但混合来自不同来源的输入只是愚蠢的实现。一个新的源不需要告诉我,忘记以前的源。是的,据我所知,清除所有事件:“如果SD_JOURNAL_无效,日志文件被添加或删除(可能是由于旋转)。在后一个事件中,live view UI可能会刷新其整个显示”,请参阅我无意中发现的一件事。在
    event=j.wait(-1)
    中,
    event
    是一个。我首先认为它包含一个事件,也就是日志行。将
    事件
    视为
    状态变化
    ,可能不那么容易混淆。
    import systemd.journal
    
    def main():
      j = systemd.journal.Reader()
      j.seek_tail()
      j.get_previous()
      while True:
        event = j.wait(-1)
        if event == systemd.journal.APPEND:
          for entry in j:
             print entry['MESSAGE']
    
    if __name__ == '__main__':
      main()
    
    import sys
    import systemd.journal
    
    def main(debug):
      j = systemd.journal.Reader()
      j.seek_tail()
      j.get_previous()
      while True:
        event = j.wait(-1)
        if event == systemd.journal.APPEND:
          for entry in j:
             print entry['MESSAGE']
        elif debug and event == systemd.journal.NOP:
          print "DEBUG: NOP"
        elif debug and event == systemd.journal.INVALIDATE:
          print "DEBUG: INVALIDATE"
        elif debug:
          raise ValueError, event   
    
    if __name__ == '__main__':
      main(len(sys.argv) > 1)