zoukankan      html  css  js  c++  java
  • python进阶----logging模块

    在工作中经常要打印一些日志,下面介绍一下python中的logging模块

    首先,先了解一下日志的级别,主要分为以下5种:

    debug      最低级别,一般开发用来打印一些调试信息

    info          正常输出信息,一般用来打印一下正常的操作

    warning   一般用来打印报警信息

    error       一般打印一些错误信息

    critical    一般打印一些致命的错误信息

    logging模块中主要有四个类

    logger    记录器,应用程序可以通过logger提供的api记录日志,相当于创建一个办公室,让员工在里面工作

    handler  处理器 ,处理日志信息,可以将日志保存或者显示在不同的目标区域

    filter       过滤器

    formatter  日志格式化

    日志的输出格式

    %(levelno)s: 打印日志级别的数值
    %(levelname)s: 打印日志级别名称
    %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
    %(filename)s: 打印当前执行程序名
    %(funcName)s: 打印日志的当前函数
    %(lineno)d: 打印日志的当前行号
    %(asctime)s: 打印日志的时间
    %(thread)d: 打印线程ID
    %(threadName)s: 打印线程名称
    %(process)d: 打印进程ID
    %(message)s: 打印日志信息
    工作中给的常用格式:
    format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
    这个格式可以输出日志的打印时间,是哪个文件第几行输出的,输出的日志级别是什么,以及输入的日志内容。
    

    写日志功能的简单实现

    import logging
    logging.basicConfig(level=logging.ERROR,#大写表示常量
                        format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',#日志输出格式
                        filename='a.log',#日志输出到哪个文件
                        filemode='a'#以追加的形式写入文件
    
    )
    logging.debug('我是debug')
    logging.info('我是info')
    logging.warning('我是warning')
    logging.error('我是error')
    logging.critical('我是critical')
    

      注意了:日志级别排列:debug<info<warning<error<critical,选择了日志级别后,打印该级别以及比这个级别高的日志的内容

     上述基本实现了log的写入功能,但是用个问题:日志只是写入了文件,但是在终端中显示不出来,怎样可以两者兼顾呢?

    使用logging模块下的handlers

    1.创建一个logger对象,相当于创建一个办公室

    Logger = logging.getLogger() 
    

      2.设置日志的级别

    Logger.setLevel(logging.DEBUG) 
    

      3.定义日志输出格式

    fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')

      4.实例化两个对象,StreamHandler 负责在屏幕上显示日志  / TimedRotatingFileHandler 负责向文件中写日志

    t = logging.StreamHandler()  #实例化StreamHandler,相当于找一个人给你干活 往屏幕上输出
    st.setFormatter(fmt) #设置屏幕上显示的格式
    th = handlers.TimedRotatingFileHandler(
    	'my.log',when='d',encoding='utf-8',backupCount=5
    	#第一个参数是文件名,第二个 when是隔多久生成一个日志,backupCount就是保存几个日志文件
    ) #实例化TimedRotatingFileHandler  相当于找一个人给你干活 往文件里面写东西
    th.setFormatter(fmt)#设置文件里面写入的格式
    

      5.将两个对象加入logger中

    Logger.addHandler(st) #把这两个对象加入到logger里面,也就是把干活的人塞到办公室里面
    Logger.addHandler(th)
    

      6.打印log

    Logger.debug('my_log debug 信息')
    Logger.info('my_log info 信息')
    Logger.warning('my_log warning 信息')
    Logger.error('my_log error 信息')
    

      完整代码如下:

    import logging
    from logging import handlers
    
    Logger = logging.getLogger()  #创建一个办公室
    Logger.setLevel(logging.DEBUG)  #设置日志级别
    fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')#定义格式
    st = logging.StreamHandler()  #实例化StreamHandler,相当于找一个人给你干活 往屏幕上输出
    st.setFormatter(fmt) #设置屏幕上显示的格式
    th = handlers.TimedRotatingFileHandler(
    	'my.log',when='d',encoding='utf-8',backupCount=5
    	#第一个参数是文件名,第二个 when是隔多久生成一个日志,backupCount就是保存几个日志文件
    ) #实例化TimedRotatingFileHandler  相当于找一个人给你干活 往文件里面写东西
    th.setFormatter(fmt)#设置文件里面写入的格式
    Logger.addHandler(st) #把这两个对象加入到logger里面,也就是把干活的人塞到办公室里面
    Logger.addHandler(th)
    Logger.debug('my_log debug 信息')
    Logger.info('my_log info 信息')
    Logger.warning('my_log warning 信息')
    Logger.error('my_log error 信息')
    

      最后封装成一个类,可以以后可以直接使用

    import logging
    from logging import handlers
    class Logger(object):
    	level_relations = {
    		'debug': logging.DEBUG,
    		'info': logging.INFO,
    		'warning': logging.WARNING,
    		'error': logging.ERROR,
    		'crit': logging.CRITICAL
    	}  # 日志级别关系映射
    	def __init__(self,filename,level='info',
    				 when='D',
    				 back_count=3,
    				 fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
    		self.logger = logging.getLogger(filename)
    		# 分割日志的单位 S 秒、M 分、 H 小时、 D 天、 W 每星期(interval==0时代表星期一)、midnight 每天凌晨
    		format_str = logging.Formatter(fmt) #设置日志格式
    		self.logger.setLevel(self.level_relations.get(level)) #设置日志级别
    		sh = logging.StreamHandler()
    		sh.setFormatter(format_str)
    		th = handlers.TimedRotatingFileHandler(filename=filename,when=when,
    							backupCount=back_count,encoding='utf-8')
    		th.setFormatter(format_str)
    		self.logger.addHandler(sh)
    		self.logger.addHandler(th)
    if __name__ == '__main__':
    	log = Logger('haha.log')
    	log.logger.debug('i的是100')
    	log.logger.info('hello wold')
    	log.logger.warning('waring message')
    	log.logger.error('error le ')
    

      

    
    
  • 相关阅读:
    Apollo与ROS
    QT windeployqt
    自定义QGraphicsItem
    ROS与C++
    aptitude与apt-get
    解决tcp粘包问题
    网络中两台主机通信
    I/O多路复用之select、poll、epoll
    Nginx命令行控制
    C++11
  • 原文地址:https://www.cnblogs.com/alasijia/p/8544107.html
Copyright © 2011-2022 走看看