Python模块“记录”双输出

时间:2018-09-02 19:02:18

标签: python python-3.x logging

我想使用logging模块,但是由于输出两次,所以遇到了麻烦。我读过很多帖子,有同样的问题,log.propagate = False或`log.handlers.pop()'已为他们解决了。这对我不起作用。

我有一个名为 logger.py 的文件,如下所示:

import logging

def __init__():
    log = logging.getLogger("output")
    filelog = logging.FileHandler("output.log")
    formatlog = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
    filelog.setFormatter(formatlog)
    log.addHandler(filelog)
    log.setLevel(logging.INFO)

    return log

这样我就可以从多个文件中写入:

import logger
log = logger.__init__()

但这给了我很多问题。因此,我已经看到了几种解决方案,但是我不知道如何在不定义所有记录程序的情况下将其合并到多个脚本中。

3 个答案:

答案 0 :(得分:0)

多个脚本导致多个进程。因此很不幸地创建了logger.__init__()函数返回的多个对象。

通常,您有一个脚本可以创建记录器和不同的流程, 但是据我了解,您希望有多个脚本记录到同一目标。

如果您希望有多个进程记录到同一目的地,我建议将进程间通信用作“命名管道”,否则建议使用UDP / TCP端口进行记录。

Python中还提供了队列模块,用于发送一个(原子的)日志记录条目,以便将其记录为一个部分(相比之下,多个进程将其附加到文件中-可能从111111 \ n和22222 \ n到11212121221 \文件中的n \ n)

否则请考虑命名管道...

日志记录服务器的代码段 注意:我只是假设将所有内容记录为错误...

import socket
import logging

class mylogger():
    def __init__(self, port=5005):
    log = logging.getLogger("output")
    filelog = logging.FileHandler("output.log")
    formatlog = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
    filelog.setFormatter(formatlog)
    log.addHandler(filelog)
    log.setLevel(logging.INFO)
    self.log = log
    UDP_IP = "127.0.0.1"  # localhost
    self.port = port
    self.UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    self.UDPClientSocket.bind((UDP_IP, self.port))
def pollReceive(self):
    data, addr = self.UDPClientSocket.recvfrom(1024)  # buffer size is 1024 bytes
    print("received message:", data)
    self.log.error( data )
pass

log = mylogger()

while True:
    log.pollReceive()

答案 1 :(得分:0)

我找到了一个非常简单的解决方案。我需要做的就是添加一个if语句,检查处理程序是否已经存在。所以我的logger.py文件现在看起来像这样:

import logging

def __init__():
    log = logging.getLogger("output")

    if not log.handlers:
        filelog = logging.FileHandler("output.log")
        formatlog = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
        filelog.setFormatter(formatlog)
        log.addHandler(filelog)
        log.setLevel(logging.INFO)

    return log

答案 2 :(得分:0)

您必须非常小心,方法是使用以下命令向记录器添加新处理程序

log.addHandler(...)

如果您向记录器添加多个处理程序,则将获得多个输出。请注意,这仅适用于在同一线程中运行的记录器。如果您正在运行从 Thread 派生的类,则它是同一线程。但是,如果您正在运行从 Process 派生的类,则它是另一个线程。为了确保根据该线程只有一个记录程序处理程序,应使用以下代码(这是SocketHandler的示例):

logger_root = logging.getLogger()
if not logger_root.hasHandlers():
    socket_handler = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
    logger_root.addHandler(socket_handler)