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 相关文章推荐
详解Python中的strftime()方法的使用
May 22 Python
分享Python开发中要注意的十个小贴士
Aug 30 Python
Python subprocess模块详细解读
Jan 29 Python
代码分析Python地图坐标转换
Feb 08 Python
Python学习_几种存取xls/xlsx文件的方法总结
May 03 Python
Python爬虫包BeautifulSoup异常处理(二)
Jun 17 Python
python多进程间通信代码实例
Sep 30 Python
pytorch 自定义卷积核进行卷积操作方式
Dec 30 Python
Python多线程获取返回值代码实例
Feb 17 Python
Python 如何测试文件是否存在
Jul 31 Python
Pytest单元测试框架如何实现参数化
Sep 05 Python
python3 os进行嵌套操作的实例讲解
Nov 19 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 中的一些经验积累
2006/10/09 PHP
让PHP以ROOT权限执行系统命令的方法
2011/02/10 PHP
php使用pear_smtp发送邮件
2016/04/15 PHP
PHP 进度条函数的简单实例
2017/09/19 PHP
yii2.0框架数据库操作简单示例【添加,修改,删除,查询,打印等】
2020/04/13 PHP
javascript级联下拉列表实例代码(自写)
2013/05/10 Javascript
js截取小数点后几位的写法
2013/11/14 Javascript
Java/JS获取flash高宽的具体方法
2013/12/27 Javascript
JS+JSP通过img标签调用实现静态页面访问次数统计的方法
2015/12/14 Javascript
深入理解JavaScript中Ajax
2016/08/02 Javascript
解决vue cli使用typescript后打包巨慢的问题
2019/09/30 Javascript
分享Angular http interceptors 拦截器使用(推荐)
2019/11/10 Javascript
微信小程序中的video视频实现 自定义播放按钮、封面图、视频封面上文案
2020/01/02 Javascript
在react中使用vue的状态管理的方法示例
2020/05/02 Javascript
vue 清空input标签 中file的值操作
2020/07/21 Javascript
vue v-on:click传递动态参数的步骤
2020/09/11 Javascript
[01:12]快闪回顾DOTA2亚洲邀请赛(DAC) 静候2018新征程开启
2018/03/11 DOTA
python处理json数据中的中文
2014/03/06 Python
使用python开发vim插件及心得分享
2014/11/04 Python
python将MongoDB里的ObjectId转换为时间戳的方法
2015/03/13 Python
python中实现k-means聚类算法详解
2017/11/11 Python
解决Python获取字典dict中不存在的值时出错问题
2018/10/17 Python
Python闭包思想与用法浅析
2018/12/27 Python
Python 3.3实现计算两个日期间隔秒数/天数的方法示例
2019/01/07 Python
python实现银联支付和支付宝支付接入
2019/05/07 Python
python字符串Intern机制详解
2019/07/01 Python
Python3中的tuple函数知识点讲解
2021/01/03 Python
PyQt5通过信号实现MVC的示例
2021/02/06 Python
日本最大的购物网站乐天市场国际版:Rakuten Global Market(支持中文)
2020/02/03 全球购物
日语专业毕业生自荐信
2013/11/11 职场文书
个人借款担保书
2014/04/02 职场文书
建筑技术负责人岗位职责
2015/04/13 职场文书
公司人力资源管理制度
2015/08/05 职场文书
mysql sum(if())和count(if())的用法说明
2022/01/18 MySQL
Python正则表达式中flags参数的实例详解
2022/04/01 Python
利用Python实时获取steam特惠游戏数据
2022/06/25 Python