【问题标题】:Python logger: won't overwrite the original log?Python logger:不会覆盖原始日志?
【发布时间】:2017-12-25 09:26:56
【问题描述】:

所以,当我将以下 x 次复制粘贴到 python 提示符时, 它将日志 x 次添加到指定文件的末尾。

如何更改代码,以便每次复制粘贴到提示符时, 我只是覆盖了现有文件(代码似乎不接受 mode = 'w'选项或者我好像没看懂它的意思)

def MinimalLogginf():
    import logging
    import os
    paths = {'work': ''}
    logger = logging.getLogger('oneDayFileLoader')
    LogHandler = logging.FileHandler(os.path.join(paths["work"] , "oneDayFileLoader.log"), mode='w')
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
    LogHandler.setFormatter(formatter)
    logger.addHandler(LogHandler) 
    logger.setLevel(logging.DEBUG)
    #Let's say this is an error:
    if(1 == 1):
        logger.error('overwrite')

所以我运行一次: 最小Loggingf()

现在,我希望新的日志文件覆盖上一次运行时创建的日志文件:

MinmalLoggingf()

【问题讨论】:

    标签: python logging


    【解决方案1】:

    您的日志消息被重复,因为您不止一次调用addHandler。对addHandler 的每次调用都会添加一个附加 日志处理程序。

    如果您想确保文件是从头开始创建的,请添加额外的代码行以将其删除:

    os.remove(os.path.join(paths["work"], "oneDayFileLoader.log"))
    

    【讨论】:

      【解决方案2】:

      模式被指定为 logging.basicConfig 的一部分,并使用文件模式传递。

      logging.basicConfig(
          level = logging.DEBUG,
          format = '%(asctime)s %(levelname)s %(message)s',
          filename = 'oneDayFileLoader.log,
          filemode = 'w'
      )
      

      https://docs.python.org/3/library/logging.html#simple-examples

      【讨论】:

      • 等一下,这会替换问题中的哪部分代码?
      【解决方案3】:

      如果我理解正确,您一次运行某个 Python 进程数天,并且希望每天轮换日志。我建议你走一条不同的路线,使用自动轮换日志文件的处理程序,例如http://www.blog.pythonlibrary.org/2014/02/11/python-how-to-create-rotating-logs/

      但是,如果您想以您熟悉的相同方法使用进程控制日志(Python 控制台,粘贴代码.. 极不美观且容易出错,但有时 quick-n-dirty 就足够了手头的任务),嗯...

      您的问题是每次粘贴代码时都会创建一个新的 FileHandler,并将其添加到 Logger 对象。您最终会得到一个附加了 X FileHandlers 的记录器,它们都写入同一个文件。试试这个:

      import logging
      paths = {'work': ''}
      logger = logging.getLogger('oneDayFileLoader')
      if logger.handlers:
         logger.handlers[0].close()
         logger.handlers = []
      logHandler = logging.FileHandler(os.path.join(paths["work"] , "oneDayFileLoader.log"), mode='w')
      formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
      logHandler.setFormatter(formatter)
      logger.addHandler(logHandler) 
      logger.setLevel(logging.DEBUG)
      logger.error('overwrite')
      

      根据您的要求,我还添加了一个使用 TimedRotatingFileHandler 的示例。注意我没有在本地测试过,所以如果你有问题 ping 回来。

      import logging
      from logging.handlers import TimedRotatingFileHandler
      
      logPath = os.path.join('', "fileLoaderLog")
      logger = logging.getLogger('oneDayFileLoader')
      logHandler = TimedRotatingFileHandler(logPath,
                                         when="midnight",
                                         interval=1)
      formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
      logHandler.setFormatter(formatter)
      logger.addHandler(logHandler) 
      logger.setLevel(logging.DEBUG)
      logger.error('overwrite')
      

      【讨论】:

      • 旋转日志方案看起来更好,但是你怎么用呢?
      • 由于我不知道你的代码库是如何实际执行的,或者关于你的用例的任何事情,这有点猜测......但是,让我编辑并添加一个可能有效的示例.
      • 我真的很想学习这些东西。我将在问题中添加一个更充实的示例(也供未来的读者使用)
      • 在那里,添加了一个可能有效的示例。确保在依赖它之前对其进行测试。如果有任何语法错误,请告诉我。不是你只需要执行一次这个代码,而且它应该在每晚午夜创建一个新的日志文件。
      • 就像我在上面的代码中做的那样。我做了一个“信仰的飞跃”(甚至不检查它,真的,因为它只是 qnd 代码)并假设第一个当前处理程序属于那种类型,然后我关闭它:logger.handlers[0].close()。只有您知道它是正确的处理程序,因为您会将它保存在不同的上下文中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2012-01-12
      • 2018-03-06
      • 2011-08-29
      • 1970-01-01
      相关资源
      最近更新 更多