【问题标题】:Python: separate processes logging to same file?Python:单独的进程记录到同一个文件?
【发布时间】:2013-02-12 07:34:27
【问题描述】:

Python 的logging 库是否为两个(或更多)单独的python 进程提供序列化日志记录到同一个文件?从文档(我已阅读)中似乎不清楚。

如果是这样,那么在完全不同的机器上会怎样(共享日志文件将存在于两者都可以访问的 NFS 导出上)。

【问题讨论】:

    标签: python multithreading logging nfs


    【解决方案1】:

    不,不支持。来自pythonlogging cookbook

    虽然日志记录是线程安全的,并且从 支持单个进程中的多个线程,记录到单个进程 不支持来自多个进程的文件,因为没有 跨多个序列化对单个文件的访问的标准方法 Python 中的进程。

    之后,说明书建议使用单个套接字服务器进程来处理日志以及向其发送日志消息的其他进程。 在Sending and Receiving logging events across a network 部分中有一个这种方法的工作示例。

    【讨论】:

    • 就我个人而言,我很想完全按照他们的建议去做,并使用套接字服务器实现一个非常小的“日志服务器”,然后按照他们在食谱中的建议登录到该套接字。
    • 避免用简短的句子和链接回答,但尽量包含实际回答问题的内容。这使得在 SO 中搜索信息变得更加容易,并且还请记住,链接将来可能会中断。如果您想在答案中添加信息,您应该编辑它而不是评论。
    • 感谢您的回答。我怀疑是这种情况。我想如果我有许多 syslog 守护进程记录到单个文件,这会是一样的吗?遗憾的是,要求日志存在于 NFS 共享上(可从运行相同代码的许多不同机器访问)。由于我们的要求规定我们不能强加进程需要能够通信的约束(它们可能位于不同的网络上)并且我们不能修改 NFS 共享(因为它需要与任何当前的 NFS 导出一起工作。看起来我必须在 NFS 共享上为每个进程设置 1 个日志。
    • 遗憾的是,鉴于任何守护进程都将是一个独特的进程,相同的规则将适用。本质上,必须从一个点控制对该单个文件的访问。您可能会找到一种基于命名约定合并这些单独日志文件的好方法吗?看看这个:stackoverflow.com/questions/6653371/…
    • 运气好的话,可以使用 rsyslog 或 logstash 作为服务器部分 :)
    【解决方案2】:

    解决这个问题的一个糟糕的解决方案是创建一个日志记录进程,该进程在单个线程上侦听套接字,该进程只输出它接收到的任何内容

    重点是劫持socket队列作为仲裁机制。

    #! /usr/bin/env python
    
    import sys
    import socket
    import argparse
    
    p = argparse.ArgumentParser()
    p.add_argument("-p", "--port", help="which port to listen on", type=int)
    p.add_argument("-b", "--backlog", help="accept backlog size", type=int)
    p.add_argument("-s", "--buffersize", help="recv buffer size", type=int)
    args = p.parse_args()
    
    port = args.port if args.port else 1339
    backlog = args.backlog if args.backlog else 5
    size = args.buffersize if args.buffersize else 1024
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('', port))
    s.listen(backlog)
    print "Listening on port ", port, 'backlog size', backlog, 'buffer size', size, '\n'
    while 1:
        try:
            (client, address) = s.accept()
            data = client.recv(size)
            print data
        except:
            client.close()
    

    并对其进行测试:

    #! /usr/bin/env python
    
    import sys
    import socket
    import argparse
    
    p = argparse.ArgumentParser()
    p.add_argument("-p", "--port", help="send port", action='store', default=1339, type=int)
    p.add_argument("text", help="text to send")
    args = p.parse_args()
    
    if not args.quit and not args.text:
        p.print_help()
    else:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect(('', args.port))
            s.send(args.text)
        except:
            s.close()
    

    然后像这样使用它:

    stdbuf -o L ./logger.py -b 10 -s 4096 >>logger.log 2>&1 &
    

    并通过以下方式监控最近的活动:

    tail -f logger.log
    

    来自任何给定进程的每个日志条目都将自动发出。将其添加到标准日志记录系统中应该不会太难。使用套接字意味着多台机器也可以针对单个日志,托管在专用机器上。

    【讨论】:

      【解决方案3】:

      最简单的方法是使用自定义处理程序进行日志记录,它将所有带有队列的日志从子进程传递到主进程,并在那里记录它。以这种方式,例如在您拥有主 UI 线程和工作线程的客户端应用程序上工作日志记录。

      同样在 POSIX 系统上,您可以在附加模式下使用日志记录。最多 4kb 将是原子的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-31
        • 1970-01-01
        • 2020-06-19
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 2022-01-17
        • 1970-01-01
        相关资源
        最近更新 更多