Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.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 阻止多线程访问日志脚本_Python_Logging_Process_Thread Safety_Handler - Fatal编程技术网

Python 阻止多线程访问日志脚本

Python 阻止多线程访问日志脚本,python,logging,process,thread-safety,handler,Python,Logging,Process,Thread Safety,Handler,我有一个名为myLog.py的模块,项目中的多个其他模块正在访问该模块。myLog.py模块有两个处理程序:file\u handler将日志输入到文件中,以及stream\u handler将日志输出到控制台。对于没有线程发生的模块,即myLog.py仅由一个进程访问,日志被正确插入,但对于正在执行线程的模块,即myLog.py由多个进程同时访问,我将获得插入同一行的多个日志我的日志文件.txt 在查看日志记录文档时,我发现日志记录模块是线程安全的,但我的实现说明了不同的情况。我应该如何初始化

我有一个名为
myLog.py
的模块,项目中的多个其他模块正在访问该模块。
myLog.py
模块有两个处理程序:
file\u handler
将日志输入到文件中,以及
stream\u handler
将日志输出到控制台。对于没有线程发生的模块,即
myLog.py
仅由一个进程访问,日志被正确插入,但对于正在执行线程的模块,即
myLog.py
由多个进程同时访问,我将获得插入同一行的多个日志我的
日志文件.txt

在查看日志记录文档时,我发现日志记录模块是线程安全的,但我的实现说明了不同的情况。我应该如何初始化
myLog.py
中的函数
setLogger()
,以便如果多个线程同时访问它,它会给出正确的输出

#myLog.py

#setup of logger
def setLogger(logfile_name = "log_file.txt"):
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(message)s')
    file_handler = logging.FileHandler(logfile_name)
    file_handler.setFormatter(formatter)
    stream_handler = logging.StreamHandler()
    logger.addHandler(file_handler)
    logger.addHandler(stream_handler)
    return logger
因此,假设它被一个名为parser.py的模块访问,该模块实现了线程化,然后日志语句以一种非常随机的复制方式打印出来

#parser.py

import threading
import myLog

logger = myLog.setLogger()

class investigate(threading.Thread):
    def __init__(self, section, file, buffer, args):
        threading.Thread.__init__(self)
        self.section = section
        self.file = file
        self.buffer = buffer
        self.args = args
        self.sig = self.pub = None
        self.exc = None

    def run(self):
        aprint("Starting section %d file %d" % (self.section, self.file))
        self.exc = None
        try:
            self.sign()
            aprint("Done section %d file %d" % (self.section, self.file))
        except:
            self.exc = sys.exc_info()

    def sign(self):
        self.sig, self.pub = sign_hsm(self.buffer, self.args)
        if self.sig is None or self.pub is None:
            raise Exception("Empty signing result")

    def store(self, bot):
        sec = filter(lambda x: x.type == self.section, bot.sections)[0]
        if self.file == 0xFF:
            signature = sec.signature
        else:
            signature = sec.files[self.file].signature
        signature.sig = self.sig
        signature.pub = self.pub

    def join(self, *args, **kwargs):
        threading.Thread.join(self, *args, **kwargs)
        if self.exc:
            msg = "Thread '%s' threw an exception: %s" % (self.getName(), self.exc[1])
            new_exc = Exception(msg)
            raise new_exc.__class__, new_exc, self.exc[2]

def PrintVersion():
    logger.info("This is output.")

print_lock = threading.RLock()
def aprint(*args, **kwargs):
    if verbosityLevel > 0:
        with print_lock:
            return logger.info(*args, **kwargs)


def multipleTimes():
    logger.info("Multiple times.")

if __name__ == "__main__":
    PrintVersion()
    for investigate in investigations:
       investigate.start()
      .......
      .......
      .......
    logger.info("This gets repeated")
    multipleTimes()

因此,由于多个线程试图访问
setLogger()
我得到
logger.info()
输出,例如:

这是输出。
这是输出。
这是输出。
这是输出。
这是输出。
这会被重复。
这会被重复。
这会被重复。
多次。
多次。
多次。
多次。
多次。
多次。
我应该得到的是:

这是输出。
这会被重复。
多次。

你能提供一个?@martineau吗?但这更多的是一个概念性问题,而不是一个应该由该人员复制以供解决的问题。我确实有一个模块,它试图通过多个并行进程访问这个模块myLog.py,但是在这里复制它非常困难。不需要真正的代码,只需要一些能够说明问题的最小代码-因此它不仅仅是“概念”,人们将有一些东西来测试他们的解决方案。文档暗示它不应该发生,所以提供一些代码来说明它确实发生了。@martineau我希望新的编辑帮助看起来很有希望,但它无法运行-例如,什么是
aprint()