在python中实现来自多个线程的自定义输出日志记录
我在Python多线程方面的实践相当糟糕。现在,我正在研究如何从多个线程获取日志信息。我看到了很多不同的方法,但我想从简单的方法开始。因此,任务是创建几个线程,并从每个线程记录数据。为了识别日志的来源,我想在日志输出中添加一些自定义标记。我知道日志库有一个reach LogRecord属性thread、threadName等,它工作得很好。所以,我有一些例子,并做了一些修改。以下是完整的代码: 导入日志记录 导入线程 导入时间 logger=logging.getLogger syslog=logging.StreamHandler 格式化程序=日志记录。格式化程序“%projects:%threadx” “%levelname-8s” “%messages” syslog.setFormatterformatter logger.setLevellogging.DEBUG logger.addHandlersyslog 类ContextFilterlogging.Filter: 定义初始自我,项目: superContextFilter,self.\u init__ self.project=project def过滤器自身,记录: record.project=self.project 返回真值 def workerargs: 而不是args['stop']: logging.debug'Hi from{}.formatargs['project'] 时间是0.5 def主: projects=['project_1','project_2'] 信息={'stop':False} 线程=[] 对于项目中的项目: 信息['project']=项目 logger.addFilterContextFilterproject thread=threading.Threadtarget=worker,args=info, thread.start threads.appendthread 尽管如此: 尝试: logging.debug'Hello from main' 时间1.75 除键盘中断外: 信息['stop']=True 打破 对于螺纹中的t: t、 加入 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': 主要的 以下是输出结果:在python中实现来自多个线程的自定义输出日志记录,python,multithreading,logging,Python,Multithreading,Logging,我在Python多线程方面的实践相当糟糕。现在,我正在研究如何从多个线程获取日志信息。我看到了很多不同的方法,但我想从简单的方法开始。因此,任务是创建几个线程,并从每个线程记录数据。为了识别日志的来源,我想在日志输出中添加一些自定义标记。我知道日志库有一个reach LogRecord属性thread、threadName等,它工作得很好。所以,我有一些例子,并做了一些修改。以下是完整的代码: 导入日志记录 导入线程 导入时间 logger=logging.getLogger syslog=lo
project_2 : 7fa627e77700 DEBUG Hi from project_2
project_2 : 7fa6293d0700 DEBUG Hello from main
project_2 : 7fa627676700 DEBUG Hi from project_2
project_2 : 7fa627e77700 DEBUG Hi from project_2
project_2 : 7fa627676700 DEBUG Hi from project_2
project_2 : 7fa627e77700 DEBUG Hi from project_2
project_2 : 7fa627676700 DEBUG Hi from project_2
project_2 : 7fa627e77700 DEBUG Hi from project_2
project_2 : 7fa627676700 DEBUG Hi from project_2
project_2 : 7fa6293d0700 DEBUG Hello from main
project_2 : 7fa627e77700 DEBUG Hi from project_2
事实上,这不是我所期望的。你能告诉我我做错了什么吗?你到底期望什么?如果您想知道为什么Hi from不显示项目名称,请尝试:
logging.debug('Hi from {}'.format(args['project']))
编辑:为了回答您的评论,事实上您确实从两个线程获得了日志。
但是您的infoobject是共享的。传递args=info时,实际上传递的是对info对象的引用,而不是副本
因此,第一次执行for循环时,会得到info['project']=project_1,但第二次执行时,info['project']会被project_2覆盖
您的工作线程只是从相同的信息目录中读取值。部分问题来自对象变量的传递。当您传递args=info时,您传递的是稍后修改并传递给下一个对象的对象,而不是该对象的副本。将同一个对象传递给多个线程可能会变得危险,这可能导致 首先,我们可以删除ContextFilter。我们将它们添加到全局记录器中,而不是跟踪每个线程的任何内容
import logging
import threading
import time
logger = logging.getLogger()
syslog = logging.StreamHandler()
formatter = logging.Formatter('%(project)s : %(thread)x '
'%(levelname)-8s '
'%(message)s')
syslog.setFormatter(formatter)
logger.setLevel(logging.DEBUG)
logger.addHandler(syslog)
我发现在一般情况下构建threading.Thread类对于除最简单任务外的所有任务都更有用
此类维护自己的运行状态,并使用正确的额外数据构建自己的日志适配器
现在我们需要改变一些事情。我们需要使用我们自己的工人阶级
我们不需要对logger做任何事情,类将管理自己的LoggerAdapter
我们希望确保每次都创建一个新的info对象,这非常简单,我们可以直接在函数调用{'project':project}中传递它,而无需指定变量
我们需要确保在从主线程进行日志记录时传递项目变量。用另一个LoggerAdapter可能更好
一旦我们中断了循环,我们可以要求每个线程停止,然后等待每个线程的连接可能会被移动到Worker类的stop方法中
此代码生成如下结果:
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
main : 7f4b45c8d700 DEBUG Hello from main
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
main : 7f4b45c8d700 DEBUG Hello from main
project_1 : 7f4b44180700 DEBUG Hi from project_1
有许多方法可以整理代码并使其更具可读性,但这至少应该为您提供一些学习和开始实验的起点。当您了解有关线程的更多信息时,您还应该阅读有关机制的内容。我最近开始在线程之间进行通信,导致代码更易于调试。谢谢,我错过了括号,我的疏忽。问题是我希望看到来自不同线程的日志,而不仅仅是来自“project_2”和Main。请记住接受其中一个答案
def main():
projects = ['project_1', 'project_2']
threads = []
for project in projects:
thread = Worker({'project': project})
thread.start()
threads.append(thread)
while True:
try:
logging.debug('Hello from main', extra={'project':'main'})
time.sleep(1.75)
except KeyboardInterrupt:
break
for t in threads:
t.stop()
for t in threads:
t.join()
if __name__ == '__main__':
main()
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
main : 7f4b45c8d700 DEBUG Hello from main
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
project_1 : 7f4b44180700 DEBUG Hi from project_1
project_2 : 7f4b4397f700 DEBUG Hi from project_2
main : 7f4b45c8d700 DEBUG Hello from main
project_1 : 7f4b44180700 DEBUG Hi from project_1