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 相关文章推荐
使用IPython来操作Docker容器的入门指引
Apr 08 Python
Python科学画图代码分享
Nov 29 Python
解决python3中解压zip文件是文件名乱码的问题
Mar 22 Python
Python 实现Windows开机运行某软件的方法
Oct 14 Python
Python 加密与解密小结
Dec 06 Python
简单了解Python3 bytes和str类型的区别和联系
Dec 19 Python
Pytorch 的损失函数Loss function使用详解
Jan 02 Python
python turtle工具绘制四叶草的实例分享
Feb 14 Python
scrapy redis配置文件setting参数详解
Nov 18 Python
Python中Pyspider爬虫框架的基本使用详解
Jan 27 Python
利用Python网络爬虫爬取各大音乐评论的代码
Apr 13 Python
浅谈Python响应式类库RxPy
Jun 14 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
php递归json类实例
2014/12/02 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
Yii2框架类自动加载机制实例分析
2018/05/02 PHP
javascript下阻止表单重复提交、防刷新、防后退
2007/08/17 Javascript
统计出现最多的字符次数的js代码
2010/12/03 Javascript
关闭浏览器输入框自动补齐 兼容IE,FF,Chrome等主流浏览器
2014/02/11 Javascript
js实现复选框的全选和取消全选效果
2017/01/03 Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
2017/01/11 Javascript
微信小程序实战之轮播图(3)
2017/04/17 Javascript
一篇文章让你彻底弄懂JS的事件冒泡和事件捕获
2017/08/14 Javascript
微信小程序 获取javascript 里的数据
2017/08/17 Javascript
JavaScript callback回调函数用法实例分析
2018/05/08 Javascript
vue使用ElementUI时导航栏默认展开功能的实现
2018/07/04 Javascript
浅谈JavaScript中this的指向更改
2020/07/28 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
解决vue页面刷新,数据丢失的问题
2020/11/24 Vue.js
js实现随机点名
2021/01/19 Javascript
[27:39]Ti4 循环赛第二日 LGD vs Fnatic
2014/07/11 DOTA
使用简单工厂模式来进行Python的设计模式编程
2016/03/01 Python
python机器学习库常用汇总
2017/11/15 Python
Python:Scrapy框架中Item Pipeline组件使用详解
2017/12/27 Python
python如何爬取个性签名
2018/06/19 Python
Python创建或生成列表的操作方法
2019/06/19 Python
Python Django 实现简单注册功能过程详解
2019/07/29 Python
pytorch中的embedding词向量的使用方法
2019/08/18 Python
详解mac python+selenium+Chrome 简单案例
2019/11/08 Python
python中的TCP(传输控制协议)用法实例分析
2019/11/15 Python
整理HTML5的一些新特性与Canvas的常用属性
2016/01/29 HTML / CSS
数据库方面面试题
2012/04/22 面试题
老师推荐信
2013/10/28 职场文书
学习党章思想汇报
2014/01/07 职场文书
大学考试作弊检讨书
2014/01/30 职场文书
刑事上诉状(无罪)
2015/05/23 职场文书
工作证明格式范文
2015/06/15 职场文书
教师信息技术学习心得体会
2016/01/21 职场文书
2019年预备党员的思想汇报:加深对党的认知
2019/09/25 职场文书