简体   繁体   English

Python日志记录创建额外的日志文件

[英]Python logging creating extra log files

I am trying to use logging to create log files for a program. 我正在尝试使用logging来为程序创建日志文件。 I'm doing something like this: 我正在做这样的事情:

if not os.path.exists(r'.\logs'):
        os.mkdir(r'.\logs')

logging.basicConfig(filename = rf'.\logs\log_{time.ctime().replace(":", "-").replace(" ", "_")}.log',
                    format = '%(asctime)s %(name)s %(levelname)s %(message)s',
                    level = logging.DEBUG)

def foo():
        # do stuff ...
        logging.debug('Done some stuff')

        # do extra stuff ...
        logging.debug('Did extra stuff')

        # some parallel map that does NOT use logging in the mapping function
        logging.debug('Done mapping')


if __name__ == '__main__':
        foo()

All goes well ant the log is created with the correct information in it: 一切顺利,并且创建的日志中包含正确的信息:

logs
    log_Wed_Feb_14_09-23-32_2018.log

Only that at the end, for some reason, it also creates 2 additional log files and leaves them empty: 最后,出于某种原因,它还会创建2个其他日志文件,并将它们留空:

logs
    log_Wed_Feb_14_09-23-32_2018.log
    log_Wed_Feb_14_09-23-35_2018.log
    log_Wed_Feb_14_09-23-39_2018.log

The timestamps are only a few seconds apart, but all of the logging still only goes in the first log file as it should. 时间戳仅相隔几秒钟,但是所有日志记录仍然仅应按原样进入第一个日志文件。

Why is it doing this? 为什么这样做呢? Also is there a way to stop it from giving me extra empty files aside from just deleting any empty logs at the end of the program? 除了在程序末尾删除任何空日志之外,还有没有办法阻止它给我额外的空文件?

Solved. 解决了。 Kind of. 的种类。

The behaviour using basic config kept happening so I tried to make a custom logger class: 使用基本配置的行为一直在发生,因此我尝试制作一个自定义记录器类:

class Logger:
        """Class used to encapsulate logging logic."""
        __slots__ = ['dir',
                     'level',
                     'formatter',
                     'handler',
                     'logger']

        def __init__(self,
                     name: str = '',
                     logdir: str = r'.\logs',
                     lvl: int = logging.INFO,
                     fmt: str = '%(asctime)s %(name)s %(levelname)s %(message)s',
                     hdl: str = rf'.\logs\log_{time.ctime().replace(":", "-").replace(" ", "_")}.log'):

                print('construct')

                if not os.path.exists(logdir):
                        os.mkdir(logdir)

                self.dir = logdir

                self.level = lvl

                self.formatter = logging.Formatter(fmt = fmt)

                self.handler = logging.FileHandler(filename = hdl)
                self.handler.setFormatter(self.formatter)

                self.logger = logging.getLogger(name)
                self.logger.setLevel(self.level)
                self.logger.addHandler(self.handler)

        def log(self, msg: str):
                """Logs the given message to the set level of the logger."""
                self.logger.log(self.level, msg)

        def cleanup(self):
                """Iterates trough the root level of the log folder, removing all log files that have a size of 0."""
                for log_file in (rf'{self.dir}\{log}' for log in next(os.walk(self.dir))[2]
                                 if log.endswith('.log') and os.path.getsize(rf'{self.dir}\{log}') is 0):
                                os.remove(log_file)

        def shutdown(self):
                """Prepares and executes the shutdown and cleanul actions."""
                logging.shutdown()
                self.handler.close()
                self.cleanup()

And tried to pass it as a parameter to functions like this: 并尝试将其作为参数传递给以下函数:

def foo(logger = Logger('foo_logger')):

But this approach made it construct a whole new logger each time I called the log method which let again to multiple files. 但是,这种方法使我每次调用log方法时都会构造一个全新的记录器,该方法再次允许访问多个文件。 By using one instance of Logger and defaulting the arguments to None I solved the problem of multiple files for this case. 通过使用Logger一个实例并将参数默认设置为None我解决了这种情况下多个文件的问题。

However the initial Basic Config situation remains a mistery. 但是,最初的Basic Config情况仍然很混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM