翼度科技»论坛 编程开发 python 查看内容

Python中logging模块用法

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
一、低配logging

日志总共分为以下五个级别,这个五个级别自下而上进行匹配 debug-->info-->warning-->error-->critical,默认最低级别为warning级别。
1.v1
  1. import logging
  2. logging.debug('调试信息')
  3. logging.info('正常信息')
  4. logging.warning('警告信息')
  5. logging.error('报错信息')
  6. logging.critical('严重错误信息')
复制代码
  1. WARNING:root:警告信息
  2. ERROR:root:报错信息
  3. CRITICAL:root:严重错误信息
复制代码
v1版本无法指定日志的级别;无法指定日志的格式;只能往屏幕打印,无法写入文件。因此可以改成下述的代码。
2.v2
  1. import logging
  2. # 日志的基本配置
  3. logging.basicConfig(filename='access.log',
  4.                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
  5.                     datefmt='%Y-%m-%d %H:%M:%S %p',
  6.                     level=10)
  7. logging.debug('调试信息')  # 10
  8. logging.info('正常信息')  # 20
  9. logging.warning('警告信息')  # 30
  10. logging.error('报错信息')  # 40
  11. logging.critical('严重错误信息')  # 50
复制代码
可在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

  • filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
  • filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
  • format:指定handler使用的日志显示格式。
  • datefmt:指定日期时间格式。
  • level:设置rootlogger(后边会讲解具体概念)的日志级别
  • stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
format参数中可能用到的格式化串:

  • %(name)s Logger的名字
  • %(levelno)s 数字形式的日志级别
  • %(levelname)s 文本形式的日志级别
  • %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
  • %(filename)s 调用日志输出函数的模块的文件名
  • %(module)s 调用日志输出函数的模块名
  • %(funcName)s 调用日志输出函数的函数名
  • %(lineno)d 调用日志输出函数的语句所在的代码行
  • %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
  • %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
  • %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
  • %(thread)d 线程ID。可能没有
  • %(threadName)s 线程名。可能没有
  • %(process)d 进程ID。可能没有
  • %(message)s用户输出的消息
v2版本不能指定字符编码;只能往文件中打印。
3.v3

logging模块包含四种角色:logger、Filter、Formatter对象、Handler

  • logger:产生日志的对象
  • Filter:过滤日志的对象
  • Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式
  • Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端
  1. '''
  2. critical=50
  3. error =40
  4. warning =30
  5. info = 20
  6. debug =10
  7. '''
  8. import logging
  9. # 1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
  10. logger = logging.getLogger(__file__)
  11. # 2、Filter对象:不常用,略
  12. # 3、Handler对象:接收logger传来的日志,然后控制输出
  13. h1 = logging.FileHandler('t1.log')  # 打印到文件
  14. h2 = logging.FileHandler('t2.log')  # 打印到文件
  15. sm = logging.StreamHandler()  # 打印到终端
  16. # 4、Formatter对象:日志格式
  17. formmater1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
  18.                                datefmt='%Y-%m-%d %H:%M:%S %p',)
  19. formmater2 = logging.Formatter('%(asctime)s :  %(message)s',
  20.                                datefmt='%Y-%m-%d %H:%M:%S %p',)
  21. formmater3 = logging.Formatter('%(name)s %(message)s',)
  22. # 5、为Handler对象绑定格式
  23. h1.setFormatter(formmater1)
  24. h2.setFormatter(formmater2)
  25. sm.setFormatter(formmater3)
  26. # 6、将Handler添加给logger并设置日志级别
  27. logger.addHandler(h1)
  28. logger.addHandler(h2)
  29. logger.addHandler(sm)
  30. # 设置日志级别,可以在两个关卡进行设置logger与handler
  31. # logger是第一级过滤,然后才能到handler
  32. logger.setLevel(30)
  33. h1.setLevel(10)
  34. h2.setLevel(10)
  35. sm.setLevel(10)
  36. # 7、测试
  37. logger.debug('debug')
  38. logger.info('info')
  39. logger.warning('warning')
  40. logger.error('error')
  41. logger.critical('critical')
复制代码
二、高配logging

1.配置日志文件

以上三个版本的日志只是为了引出我们下面的日志配置文件
  1. import os
  2. import logging.config
  3. # 定义三种日志输出格式 开始
  4. standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
  5.                   '[%(levelname)s][%(message)s]'  # 其中name为getLogger()指定的名字;lineno为调用日志输出函数的语句所在的代码行
  6. simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
  7. id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
  8. # 定义日志输出格式 结束
  9. logfile_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # log文件的目录,需要自定义文件路径 # atm
  10. logfile_dir = os.path.join(logfile_dir, 'log')  # C:\Users\oldboy\Desktop\atm\log
  11. logfile_name = 'log.log'  # log文件名,需要自定义路径名
  12. # 如果不存在定义的日志目录就创建一个
  13. if not os.path.isdir(logfile_dir):  # C:\Users\oldboy\Desktop\atm\log
  14.     os.mkdir(logfile_dir)
  15. # log文件的全路径
  16. logfile_path = os.path.join(logfile_dir, logfile_name)  # C:\Users\oldboy\Desktop\atm\log\log.log
  17. # 定义日志路径 结束
  18. # log配置字典
  19. LOGGING_DIC = {
  20.     'version': 1,
  21.     'disable_existing_loggers': False,
  22.     'formatters': {
  23.         'standard': {
  24.             'format': standard_format
  25.         },
  26.         'simple': {
  27.             'format': simple_format
  28.         },
  29.     },
  30.     'filters': {},  # filter可以不定义
  31.     'handlers': {
  32.         # 打印到终端的日志
  33.         'console': {
  34.             'level': 'DEBUG',
  35.             'class': 'logging.StreamHandler',  # 打印到屏幕
  36.             'formatter': 'simple'
  37.         },
  38.         # 打印到文件的日志,收集info及以上的日志
  39.         'default': {
  40.             'level': 'INFO',
  41.             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
  42.             'formatter': 'standard',
  43.             'filename': logfile_path,  # 日志文件
  44.             'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M  (*****)
  45.             'backupCount': 5,
  46.             'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
  47.         },
  48.     },
  49.     'loggers': {
  50.         # logging.getLogger(__name__)拿到的logger配置。如果''设置为固定值logger1,则下次导入必须设置成logging.getLogger('logger1')
  51.         '': {
  52.             # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
  53.             'handlers': ['default', 'console'],
  54.             'level': 'DEBUG',
  55.             'propagate': False,  # 向上(更高level的logger)传递
  56.         },
  57.     },
  58. }
  59. def load_my_logging_cfg():
  60.     logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
  61.     logger = logging.getLogger(__name__)  # 生成一个log实例
  62.     logger.info('It works!')  # 记录该文件的运行状态
  63.    
  64.     return logger
  65. if __name__ == '__main__':
  66.     load_my_logging_cfg()
复制代码
2.使用日志
  1. import time
  2. import logging
  3. import my_logging  # 导入自定义的logging配置
  4. logger = logging.getLogger(__name__)  # 生成logger实例
  5. def demo():
  6.     logger.debug("start range... time:{}".format(time.time()))
  7.     logger.info("中文测试开始。。。")
  8.     for i in range(10):
  9.         logger.debug("i:{}".format(i))
  10.         time.sleep(0.2)
  11.     else:
  12.         logger.debug("over range... time:{}".format(time.time()))
  13.     logger.info("中文测试结束。。。")
  14. if __name__ == "__main__":
  15.     my_logging.load_my_logging_cfg()  # 在你程序文件的入口加载自定义logging配置
  16.     demo()
复制代码
三、Django日志配置文件
  1. # logging_config.py
  2. # 学习中遇到问题没人解答?小编创建了一个Python学习交流群:489111204
  3. LOGGING = {
  4.     'version': 1,
  5.     'disable_existing_loggers': False,
  6.     'formatters': {
  7.         'standard': {
  8.             'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
  9.                       '[%(levelname)s][%(message)s]'
  10.         },
  11.         'simple': {
  12.             'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
  13.         },
  14.         'collect': {
  15.             'format': '%(message)s'
  16.         }
  17.     },
  18.     'filters': {
  19.         'require_debug_true': {
  20.             '()': 'django.utils.log.RequireDebugTrue',
  21.         },
  22.     },
  23.     'handlers': {
  24.         # 打印到终端的日志
  25.         'console': {
  26.             'level': 'DEBUG',
  27.             'filters': ['require_debug_true'],
  28.             'class': 'logging.StreamHandler',
  29.             'formatter': 'simple'
  30.         },
  31.         # 打印到文件的日志,收集info及以上的日志
  32.         'default': {
  33.             'level': 'INFO',
  34.             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
  35.             'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
  36.             'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
  37.             'backupCount': 3,
  38.             'formatter': 'standard',
  39.             'encoding': 'utf-8',
  40.         },
  41.         # 打印到文件的日志:收集错误及以上的日志
  42.         'error': {
  43.             'level': 'ERROR',
  44.             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
  45.             'filename': os.path.join(BASE_LOG_DIR, "xxx_err.log"),  # 日志文件
  46.             'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
  47.             'backupCount': 5,
  48.             'formatter': 'standard',
  49.             'encoding': 'utf-8',
  50.         },
  51.         # 打印到文件的日志
  52.         'collect': {
  53.             'level': 'INFO',
  54.             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
  55.             'filename': os.path.join(BASE_LOG_DIR, "xxx_collect.log"),
  56.             'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
  57.             'backupCount': 5,
  58.             'formatter': 'collect',
  59.             'encoding': "utf-8"
  60.         }
  61.     },
  62.     'loggers': {
  63.         # logging.getLogger(__name__)拿到的logger配置
  64.         '': {
  65.             'handlers': ['default', 'console', 'error'],
  66.             'level': 'DEBUG',
  67.             'propagate': True,
  68.         },
  69.         # logging.getLogger('collect')拿到的logger配置
  70.         'collect': {
  71.             'handlers': ['console', 'collect'],
  72.             'level': 'INFO',
  73.         }
  74.     },
  75. }
  76. # -----------
  77. # 用法:拿到俩个logger
  78. logger = logging.getLogger(__name__)  # 线上正常的日志
  79. collect_logger = logging.getLogger("collect")  # 领导说,需要为领导们单独定制领导们看的日志
复制代码
来源:https://www.cnblogs.com/python1111/p/17161849.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具