Python logging日志模块 & Pytorch代码日志记录

       日志让我们可以监测程序运行的状态。当然,很多时候用print也可以完成,但是学过会发现,用专门的日志模块会更加省力。

       

      默认情况下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就print的功能,输出日志信息。前面初始化了日志输出的格式,后面代码中只需要写内容(对应message),时间等信息都会自动带上,这就是loggingprint方便的地方。

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模块上篇 - 知乎

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值