【问题标题】:Call a function everytime logging module in python is called每次调用 python 中的日志记录模块时调用一个函数
【发布时间】:2021-03-16 12:06:57
【问题描述】:

我想每次都调用一个函数,我使用 python 中的logging 模块进行任何类型的日志记录。

如下所示,我不想在每个日志记录实例中调用copyfiles,而是想看看是否有办法以某种方式将复制文件注入文件处理程序甚至是包装器。

from sys import argv
import shutil
import logging
logger = logging.getLogger('')

sh = logging.StreamHandler(sys.stdout)
logfile = 'logs/log-run-{}.log'.format(date.today().strftime('%d-%m-%Y'))
fh = logging.FileHandler(logfile)

formatter = logging.Formatter('[%(asctime)s] %(levelname)s \
                            [%(filename)s.%(funcName)s:%(lineno)d] \
                            %(message)s', datefmt='%a, %d %b %Y %H:%M:%S')
logger.setLevel(logging.INFO)

sh.setFormatter(formatter)
fh.setFormatter(formatter)

logger.addHandler(sh)
logger.addHandler(fh)

LOGPATH = args[1]
def copyfiles():
    """
    Copy files to azure blob storage
    """
    fh.flush()
    shutil.copy(logfile, LOGPATH)

logging.info('test')
copyfiles()
logging.info('foobar')
copyfiles()

我尝试在每次调用日志记录时深入调用副本文件,但最终无处可寻。

如果你想知道我为什么要从日志中复制文件,this is why

【问题讨论】:

  • 所以你想在每次添加新行时复制整个文件?
  • 是的,你是对的。
  • 我提出了一个解决方案,如果可行,请告诉我。只是好奇,这不会导致大量额外的文件 I/O 并成为瓶颈吗?
  • 这可能会成为瓶颈,但这是唯一的出路,因为直到工作结束才会给出 stdout 和 stderr。所以,我什至不知道我在等什么
  • 我真的认为这是一个非常糟糕的主意。为什么不使用另一个处理程序,例如 HTTPHandler、SocketHandler、DatagramHandler 等等?

标签: python logging wrapper


【解决方案1】:

目前这是我能想到的:

  • 通过将 FileHandler 的 flush() 继承到实用程序中来覆盖它 如下代码所示的 FlushCopyFileHandler 类。
  • 不要使用 FileHandler,而是使用 FlushCopyFileHandler 类 你所要做的就是调用这个被覆盖的flush()。

"""

from logging import FileHandler
from shutil

class FlushCopyFileHandler(FileHandler):
    
    # These arguments are passed along to the parent class FileHandler.
    def __init__(self, *args, **kwargs):
        super(FlushCopyFileHandler, self).__init__(filename, *args, **kwargs)
        self.copy_destination = "some default destination path"   # can also be set from args.
        
    # When this flush() is called it will call the flush() of FileHandler class.
    # After that it will call the shutil.copy() method.
    def flush(self):
        super().flush()
        shutil.copy(self.filename, self.copy_destination)
        
    # Use this to change destination path later on.
    def set_copy_path(self, destination):
        self.copy_destination = destination 

"""

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    相关资源
    最近更新 更多