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()
?