【问题标题】:Python: capturing each thread details in individual log filePython:在单个日志文件中捕获每个线程的详细信息
【发布时间】:2020-06-03 07:21:13
【问题描述】:

我正在为几个 URL 执行网络健全性,目前,我们将这些 URL 的整个日志详细信息记录在一个日志文件中(使用日志记录模块),但是 需要捕获每个 URL 的日志详细信息url 在单独的日志文件中

目前,我在一个列表中有 7 个 url,并在一个列表中创建了 7 个 logging.txt 文件。然后,在一个循环中,我对每个 logging.txt 文件使用了 basicConfig() 方法,并在线程中传递了相应的 url 和 logger 对象(请检查下面的代码)。

运行脚本后,我只能找到一个 logging0.txt 文件,其中包含所有捕获的 urls 日志详细信息。显然,在线程中将记录器对象作为 arg 传递不会执行我认为的那样。

log_files_here = ['logging0.txt','logging1.txt','logging2.txt','logging3.txt','logging4.txt','logging5.txt','logging6.txt']
urls = ['url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7']

for i in range(0, len(urls)):
    url = urls[i] 
    logfilepath = log_files_here[i]
    logging.basicConfig(filename=logfilepath, format='%(asctime)s %(message)s',level=logging.INFO)
    logger=logging.getLogger(__name__)

    print(f'Current logging file here {logfilepath} and loggere here is {logger}')
    logobject = getLogger(i)
    # Initiating thread here
    node_thread = threading.Thread(target=url_sanity, args=(url,logger))
    node_thread.start()  # starting the thread
    node_thread.join()

我进一步研究并只创建了一个记录器对象并使用了RotatingFilehandler(),测试了下面的代码并在线程中传递了记录器对象。

这会生成 7 个具有相同 INFO 的备份文件,但不是 7 个文件中的每个 url 日志详细信息。通过传递 backUpCount 参数来理解只需要备份。

logger = logging.getLogger('my_logger')
logger.setLevel(logging.INFO)
handler = RotatingFileHandler('my_log.log', maxBytes=2000, backupCount=7)
logger.addHandler(handler)

所以,这也不能解决需求。现在,我生成了一个日志文件,其中包含所有 url 日志详细信息,而我想要的只是生成每个日志文件来捕获每个 url(线程)信息。 请注意,我无法提供任何回溯错误,因为我在单个日志文件中获取这些 url 的日志详细信息。

能否请您帮助我如何在单独的日志文件中捕获每个 url 的日志详细信息?提前致谢。

【问题讨论】:

    标签: python multithreading logging


    【解决方案1】:

    这里的问题是您只配置了一个记录器实例,因为basicConfig() 只配置了根记录器,即使您将该配置循环 X 次,您也只配置了同一个实例。

    当您执行logger=logging.getLogger(__name__) 时,您将获得一个从根记录器继承的实例,并且它只配置了一个fileHandler

    解决多文件日志记录问题的一种方法是创建尽可能多的命名记录器,并为每个文件分配一个fileHandler

    这是通过使用日志核心的命名系统来实现的。例如,您可以使用 url 的名称来获取要使用的记录器。

    请检查这个根据您的代码构建的示例:

    import logging
    import threading
    
    log_files_here = ['logging0.txt','logging1.txt','logging2.txt','logging3.txt','logging4.txt','logging5.txt','logging6.txt']
    urls = ['url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7']
    
    
    def configure_logging():
        """ Configuring all the logging instances with files-urls mapping"""
        for i in range(0, len(urls)):
            url = urls[i]
            logfilepath = log_files_here[i]
            # This will create and get a named urlX instance of the logger
            log = logging.getLogger(url)
            # NOTE: You can use a RotatingFileHandler here if fits better
            filehandler = logging.FileHandler(logfilepath, mode='a')
            log.addHandler(filehandler)
            # Feel free to parametrize this if you want different loglevel settings on your files.
            log.setLevel(logging.INFO)
    
    
    def logger_worker(url):
        log = logging.getLogger(url)
        log.info(f"{url} logging! .")
    
    
    def main():
        """ Testing current log settings"""
        configure_logging()
    
        for i in range(0, len(urls)):
            url = urls[i]
            node_thread = threading.Thread(target=logger_worker, args=(url,))
            node_thread.start()  # starting the thread
            node_thread.join()
    
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 我添加了 logger= logging.getLogger(url) 而不是 logging.getLogger(name) 并将 logger 对象作为 arg 与线程中的 url 一起传递。还是不行。
    • 我已更新示例以包含线程部分。您需要确保在记录之前获得正确的日志实例。您可以在 main 循环中获取日志并将其作为参数传递,或者(我的选择)根据参数获取线程内的日志
    猜你喜欢
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 2020-02-18
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    • 2016-01-02
    相关资源
    最近更新 更多