python3 logging日志封装实例


Posted in Python onApril 08, 2020

一个完整的程序离不开日志,无论是开发阶段,还是测试阶段,亦或程序运行阶段,都可以通过日志查看程序的运行情况,或是定位问题。

下面是对 python3 的日志库 logging 进行了封装,对于大部分的需求应该是能满足的。(如果有不满足的地方,欢迎在下方留言)

程序结构:

|--logger.py
|
|--singleton.py
|
|--demo.py
|
|--log
|  |
|  2018-10-12.log

logger.py

import os
import sys
import time
import logging
from singleton import Singleton
 
 
@Singleton   # 如需打印不同路径的日志(运行日志、审计日志),则不能使用单例模式(注释或删除此行)。此外,还需设定参数name。
class Logger:
  def __init__(self, set_level="INFO",
         name=os.path.split(os.path.splitext(sys.argv[0])[0])[-1],
         log_name=time.strftime("%Y-%m-%d.log", time.localtime()),
         log_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "log"),
         use_console=True):
    """
    :param set_level: 日志级别["NOTSET"|"DEBUG"|"INFO"|"WARNING"|"ERROR"|"CRITICAL"],默认为INFO
    :param name: 日志中打印的name,默认为运行程序的name
    :param log_name: 日志文件的名字,默认为当前时间(年-月-日.log)
    :param log_path: 日志文件夹的路径,默认为logger.py同级目录中的log文件夹
    :param use_console: 是否在控制台打印,默认为True
    """
    if not set_level:
      set_level = self._exec_type() # 设置set_level为None,自动获取当前运行模式
    self.__logger = logging.getLogger(name)
    self.setLevel(getattr(logging, set_level.upper()) if hasattr(logging, set_level.upper()) else logging.INFO) # 设置日志级别
    if not os.path.exists(log_path): # 创建日志目录
      os.makedirs(log_path)
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    handler_list = list()
    handler_list.append(logging.FileHandler(os.path.join(log_path, log_name), encoding="utf-8"))
    if use_console:
      handler_list.append(logging.StreamHandler())
    for handler in handler_list:
      handler.setFormatter(formatter)
      self.addHandler(handler)
 
  def __getattr__(self, item):
    return getattr(self.logger, item)
 
  @property
  def logger(self):
    return self.__logger
 
  @logger.setter
  def logger(self, func):
    self.__logger = func
 
  def _exec_type(self):
    return "DEBUG" if os.environ.get("IPYTHONENABLE") else "INFO"

singleton.py

class Singleton:
  """
  单例装饰器。
  """
  __cls = dict()
 
  def __init__(self, cls):
    self.__key = cls
 
  def __call__(self, *args, **kwargs):
    if self.__key not in self.cls:
      self[self.__key] = self.__key(*args, **kwargs)
    return self[self.__key]
 
  def __setitem__(self, key, value):
    self.cls[key] = value
 
  def __getitem__(self, item):
    return self.cls[item]
 
  @property
  def cls(self):
    return self.__cls
 
  @cls.setter
  def cls(self, cls):
    self.__cls = cls

demo.py

import logger
 
x = logger.Logger("debug")
 
x.critical("这是一个 critical 级别的问题!")
x.error("这是一个 error 级别的问题!")
x.warning("这是一个 warning 级别的问题!")
x.info("这是一个 info 级别的问题!")
x.debug("这是一个 debug 级别的问题!")
 
x.log(50, "这是一个 critical 级别的问题的另一种写法!")
x.log(40, "这是一个 error 级别的问题的另一种写法!")
x.log(30, "这是一个 warning 级别的问题的另一种写法!")
x.log(20, "这是一个 info 级别的问题的另一种写法!")
x.log(10, "这是一个 debug 级别的问题的另一种写法!")
 
x.log(51, "这是一个 Level 51 级别的问题!")
x.log(11, "这是一个 Level 11 级别的问题!")
x.log(9, "这条日志等级低于 debug,不会被打印")
x.log(0, "这条日志同样不会被打印")
 
 
"""
运行结果:
2018-10-12 00:18:06,562 - demo - CRITICAL - 这是一个 critical 级别的问题!
2018-10-12 00:18:06,562 - demo - ERROR - 这是一个 error 级别的问题!
2018-10-12 00:18:06,562 - demo - WARNING - 这是一个 warning 级别的问题!
2018-10-12 00:18:06,562 - demo - INFO - 这是一个 info 级别的问题!
2018-10-12 00:18:06,562 - demo - DEBUG - 这是一个 debug 级别的问题!
2018-10-12 00:18:06,562 - demo - CRITICAL - 这是一个 critical 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - ERROR - 这是一个 error 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - WARNING - 这是一个 warning 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - INFO - 这是一个 info 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - DEBUG - 这是一个 debug 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - Level 51 - 这是一个 Level 51 级别的问题!
2018-10-12 00:18:06,562 - demo - Level 11 - 这是一个 Level 11 级别的问题!
"""
2018-10-12.log

2018-10-12 00:18:06,562 - demo - CRITICAL - 这是一个 critical 级别的问题!
2018-10-12 00:18:06,562 - demo - ERROR - 这是一个 error 级别的问题!
2018-10-12 00:18:06,562 - demo - WARNING - 这是一个 warning 级别的问题!
2018-10-12 00:18:06,562 - demo - INFO - 这是一个 info 级别的问题!
2018-10-12 00:18:06,562 - demo - DEBUG - 这是一个 debug 级别的问题!
2018-10-12 00:18:06,562 - demo - CRITICAL - 这是一个 critical 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - ERROR - 这是一个 error 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - WARNING - 这是一个 warning 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - INFO - 这是一个 info 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - DEBUG - 这是一个 debug 级别的问题的另一种写法!
2018-10-12 00:18:06,562 - demo - Level 51 - 这是一个 Level 51 级别的问题!
2018-10-12 00:18:06,562 - demo - Level 11 - 这是一个 Level 11 级别的问题!

以上这篇python3 logging日志封装实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
Oct 01 Python
PyQt实现界面翻转切换效果
Apr 20 Python
Tensorflow中的placeholder和feed_dict的使用
Jul 09 Python
Pandas DataFrame 取一行数据会得到Series的方法
Nov 10 Python
numpy基础教程之np.linalg
Feb 12 Python
计算机二级python学习教程(3) python语言基本数据类型
May 16 Python
python判断自身是否正在运行的方法
Aug 08 Python
Python使用Pandas读写Excel实例解析
Nov 19 Python
python 中的[:-1]和[::-1]的具体使用
Feb 13 Python
Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法
May 26 Python
python绘制分布折线图的示例
Sep 24 Python
pytorch 使用半精度模型部署的操作
May 24 Python
Django实现whoosh搜索引擎使用jieba分词
Apr 08 #Python
Python 输出详细的异常信息(traceback)方式
Apr 08 #Python
python上传时包含boundary时的解决方法
Apr 08 #Python
python MultipartEncoder传输zip文件实例
Apr 07 #Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
Apr 07 #Python
Xadmin+rules实现多选行权限方式(级联效果)
Apr 07 #Python
Django Xadmin多对多字段过滤实例
Apr 07 #Python
You might like
收听困难?教您超简便短波广播抗干扰方法!
2021/03/01 无线电
yii2中添加验证码的实现方法
2016/01/09 PHP
浅谈PHP中的
2016/04/23 PHP
初窥JQuery(一)jquery选择符 必备知识点
2010/11/25 Javascript
js String对象中常用方法小结(字符串操作)
2012/01/27 Javascript
js如何实现设计模式中的模板方法
2013/07/23 Javascript
使用ImageMagick进行图片缩放、合成与裁剪(js+python)
2013/09/16 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
JavaScript中的公有、私有、特权和静态成员用法分析
2014/11/20 Javascript
什么是 AngularJS?AngularJS简介
2014/12/06 Javascript
js超时调用setTimeout和间歇调用setInterval实例分析
2015/01/28 Javascript
浅谈js和css内联外联注意事项
2016/06/30 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
微信小程序实现下拉刷新和轮播图效果
2017/11/21 Javascript
通过vue提供的keep-alive减少对服务器的请求次数
2018/04/01 Javascript
微信小程序实现同一页面取值的方法分析
2019/04/30 Javascript
使用xampp将angular项目运行在web服务器的教程
2019/09/16 Javascript
iSlider手机端图片滑动切换插件使用详解
2019/12/24 Javascript
python通过shutil实现快速文件复制的方法
2015/03/14 Python
python使用win32com库播放mp3文件的方法
2015/05/30 Python
使用pdb模块调试Python程序实例
2015/06/02 Python
全面理解Python中self的用法
2016/06/04 Python
用pickle存储Python的原生对象方法
2017/04/28 Python
python numpy库linspace相同间隔采样的实现
2020/02/25 Python
Python Opencv轮廓常用操作代码实例解析
2020/09/01 Python
pyqt5实现井字棋的示例代码
2020/12/07 Python
html5是什么_动力节点Java学院整理
2017/07/07 HTML / CSS
高中体育教学反思
2014/01/24 职场文书
会计电算化学生个人的自我评价
2014/02/08 职场文书
心灵捕手观后感
2015/06/02 职场文书
英雄儿女观后感
2015/06/09 职场文书
2016年全国助残日活动总结
2016/04/01 职场文书
公开致歉信
2019/06/24 职场文书
解决Golang中ResponseWriter的一个坑
2021/04/27 Golang
MySQL性能指标TPS+QPS+IOPS压测
2022/08/05 MySQL