日志让我们可以监测程序运行的状态。当然,很多时候用
默认情况下python的logging模块将日志打印到了标准输出(屏幕)中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET)
import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s') for i in range(10): logging.info(f'iteration {i}: ***')
这里的
logging.info就
是logging
比logging.getLogger(name)
logging.getLogger(name)获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象。
logging信息输出到文件中
import logging logging.basicConfig( filename="log.txt", level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s') for i in range(10): logging.info(f'iteration {i}: ***')
这样就会只输出到文件中,而且内容是在后面追加
logging信息输出到屏幕+文件中
import logging import sys logging.basicConfig( filename="log.txt", level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s') logging.getLogger().addHandler(logging.StreamHandler(sys.stdout)) for i in range(10): logging.info(f'iteration {i}: ***')
但是这种写法遇到过不起作用的情况,像导入MONAI库的时候
下面这种写法更有用
import logging my_logger = logging.getLogger('my_logger') my_logger.setLevel(logging.INFO) # 创建一个将日志写入文件的处理器,并将其附加到 my_logger 记录器上 file_handler = logging.FileHandler('my_log_file.txt') file_handler.setLevel(logging.INFO) file_handler.setFormatter( logging.Formatter('%(asctime)s %(levelname)s %(message)s') ) my_logger.addHandler(file_handler) # 输出一些日志消息 my_logger.debug('Debug message') my_logger.info('Info message') my_logger.warning('Warning message') my_logger.error('Error message') my_logger.critical('Critical message')
运行的时候python -u lian.py
logging输出配置文件内容
config = parse_args() logger.info(json.dumps(config, indent=2))
logging模块不工作
在 PyTorch 中,如果在导入某些包之后
logging
模块停止工作,这通常是因为其他包修改了logging
模块的配置或者覆盖了logging
模块的配置。像我遇到过导入MONAI的包之后logging就不起作用了
解决方法是 给logging.basicConfig的force参数设为True,就可以了。但是必须要python3.8才行
logging.basicConfig( filename="log.txt", level=logging.INFO, format='[%(asctime)s.%(msecs)03d] %(message)s', datefmt='%H:%M:%S', force=True, )
huggingface的transformers库中也有logging模块,注意
一个常见的问题是 PyTorch 自带的 CUDA 库(
torch.cuda
)可能会覆盖logging
模块的配置。这是因为 CUDA 使用了自己的logging
配置。在这种情况下,可以使用以下代码来恢复
logging
模块的配置:import logging import torch # 获取 CUDA 的 logger cuda_logger = logging.getLogger('torch.cuda') # 禁用 CUDA 的 logger cuda_logger.disabled = True # 恢复 logging 模块的配置 logging.basicConfig(level=logging.DEBUG)
在这个示例中,我们首先获取了 CUDA 的 logger,并将其禁用。然后,我们通过
basicConfig()
函数恢复了logging
模块的配置。如果你的代码中有其他的包也影响了
logging
模块的配置,可以使用类似的方法来恢复配置。为什么很多程序都是logging.getLogger(__name__)
logging.getLogger(__name__)
是一种常用的获取 logger 对象的方式,它的作用是创建一个以模块名为名称的 logger 对象。这样,每个模块都会有自己独立的 logger 对象,用于记录该模块中发生的事件和错误信息。这种方式可以避免在不同模块中使用同一个 logger 对象时发生名称冲突的问题。当一个项目比较大的时候,不同的文件中都要用到logging,可以考虑将其封装为一个类来使用
#! /usr/bin/env python #coding=gbk import logging,os class Logger: def __init__(self, path,clevel = logging.DEBUG,Flevel = logging.DEBUG): self.logger = logging.getLogger(path) self.logger.setLevel(logging.DEBUG) fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S') #设置CMD日志 sh = logging.StreamHandler() sh.setFormatter(fmt) sh.setLevel(clevel) #设置文件日志 fh = logging.FileHandler(path) fh.setFormatter(fmt) fh.setLevel(Flevel) self.logger.addHandler(sh) self.logger.addHandler(fh) def debug(self,message): self.logger.debug(message) def info(self,message): self.logger.info(message) def war(self,message): self.logger.warn(message) def error(self,message): self.logger.error(message) def cri(self,message): self.logger.critical(message) if __name__ =='__main__': logyyx = Logger('yyx.log',logging.ERROR,logging.DEBUG) logyyx.debug('一个debug信息') logyyx.info('一个info信息') logyyx.war('一个warning信息') logyyx.error('一个error信息') logyyx.cri('一个致命critical信息')
Python logging日志模块 & Pytorch代码日志记录
于 2021-08-22 21:36:14 首次发布