阻止日志脚本被多个线程访问

问题描述

我有一个名为myLog.py的模块,项目中的其他多个模块正在访问该模块。 myLog.py模块具有两个处理程序:file_handler(将日志输入到文件中)和stream_handler(将日志输出到控制台)。对于没有发生线程的模块,例如,myLog.py仅由单个进程访问,日志被正确地插入;但是对于正在实现线程的模块,即,myLog.py被多个进程同时访问。我在log_file.txt中插入了同一行的多个日志。

遍历日志记录文档时,我发现日志记录模块是thread_safe,但是我的实现却有所不同。我应该如何初始化setLogger()中的函数myLog.py,以便如果多个线程同时访问它,它会给出正确的输出

#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,**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()输出,例如:

This is output.
This is output.
This is output.
This is output.
This is output.
This gets repeated.
This gets repeated.
This gets repeated.
Multiple times.
Multiple times.
Multiple times.
Multiple times.
Multiple times.
Multiple times.

我应该得到什么:

This is output.
This gets repeated.
Multiple times.

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)