python3中的logging记录日志实现过程及封装成类的操作


Posted in Python onMay 12, 2020

作用:

主要记录信息,便于定位查看问题。

python logging模块官网:

https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects

三种定位问题方法:

print

debug调试:代码写好后,就不需要再进行调试了,所以引入了logger

logging.debug() ? 一般在测试环境中用

logger:当生产环境中有问题时,可以查看logger定位问题

步骤:

1.初始化日志 收集器

2.设置日志 收集器级别 -默认是warning

3.初始化日志 处理器 - 可以理解为写日志的笔

4.设置日志 处理器级别

5.添加handler

6.设置日志的格式

7.添加日志处理器

8.设置不同级别的logger

这里是引用

日志收集器级别

1.NOSET 0 等于没写,废话

2.DEBUG 10 程序调试bug时使用

3.INFO 20 程序正常运行时使用

4.WARNING 30 警告,程序未按预期运行时使用

5.ERROE 40 程序出错

6.CRITICAL 50 严重问题

如何定义级别:自己定的 可以结合try: except: 记录log

代码实现过程如下:

```python
import logging # 标准库,直接导入。
logger = logging.getLogger("日志名字") # 初始化日志收集器
logger.setLevel("DEBUG") # 设置日志收集器级别

handler = logging.FileHandler("日志路径") # 初始化日志处理器 - 文件输出(指定位置使用绝对路径,默认当前目录下)
handler.setLevel("warning") # 设置日志处理器级别 默认warning

console_handler = logging.StreamHandler() # 控制台输出
console_handler.setLevel("DEBUG")

logger.addHandler(handler) # 添加handler
logger.addHandler(console_handler)
 # 设置日志格式,中间间隔使用冒号也可以(模块名字-报错行-收集器名字-级别-信息)
fmt = logging.Formatter("%(filename)s-%(lineno)s-%(name)s-%(levelname)s-%(massage)s")
handler.setFormat(fmt) # 日志轮转 - 添加日志处理器
# 设置不同级别的logger -- 选择一个级别就可以
logging.info("")
logging.debug("")
logging.waring("")
logging.error("")
logging.critical("")

问题1:级别设置

如当设成debug的时候,只有高于,等于该级别的才会打印

如当你设成warning的时候,只有warning.error,critical才会打印

不用管(日志收集器)的级别是啥,这里设置就以(日志处理器)的级别

为准,两者中选择最高的如果(日志收集器)是warning,(日志处理器)

是debug,就以warning为准,两个都设置,这样可以添加多个handler

问题2:实例化

在模块中直接实例化,如果在外部实例化,容易造成多个日志文件的生成

问题3:日志格式设置,python logging官网,查找需要用到的。

https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects

封装为类

import logging
class LoggerHandler(logging.Logger):

  def __init__(self,
         name="root",
         level="DEBUG",
         file=None,
         format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s"
         ):

    # 初始化日志收集器
    logger = logging.getLogger(name)

    # 设置收集器级别
    logger.setLevel(level) # 继承了Logger 返回的实例就是自己

    # 初始化format,设置格式
    fmt = logging.Formatter(format)

    # 初始化处理器
    # 如果file为空,就执行stream_handler,如果有,两个都执行
    if file:
      file_handler = logging.FileHandler(file)
      # 设置handler级别
      file_handler.setLevel(level)
      # 添加handler
      logger.addHandler(file_handler)
      # 添加日志处理器
      file_handler.setFormatter(fmt)

    stream_handler = logging.StreamHandler()
    stream_handler.setLevel(level)
    logger.addHandler(stream_handler)
    stream_handler.setFormatter(fmt)

    self.logger = logger

	  def debug(self, msg):
	    return self.logger.debug(msg)
	  def info(self,msg):
	    return self.logger.info(msg)

	  def warning(self,msg):
	    return self.logger.warning(msg)
	 
	  def error(self,msg):
	    return self.logger.error(msg)
	 
	  def critical(self,msg):
	    return self.logger.critical(msg)
# 为了确保每次是同一个文件,调用同样的logger对象(防止手误写错文件名字),所以在这里直接初始化logger这个对象比较好
# 可以将name,file参数写入配置文件中(这里我是直接写到了配置文件当中,也可以直接传)
logger = LoggerHandler(config.logger_name,config.level,config.logger_file) 
# logger = LoggerHandler("python21",file="demo.txt")

if __name__ == '__main__':
  logger = LoggerHandler()
  logger.debug("world")
  # 测试.py:40:root:DEBUG:world - 应该是59行打印,因为信息早就保存到logger当中了 -- 可以直接继承logging.Logger使用

重新封装 - 继承logger后,发现可以直接定位到哪一行打印,可以查看源码

import logging

class LoggerHandler(logging.Logger):

  def __init__(self,
         name="root",
         level="DEBUG",
         file=None,
         format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s"
         ):

    # logger(name) 直接超继承logger当中的name
    super().__init__(name) 

    # 设置收集器级别
    # logger.setLevel(level)
    self.setLevel(level) # 继承了Logger 返回的实例就是自己

    # 初始化format,设置格式
    fmt = logging.Formatter(format)

    # 初始化处理器
    # 如果file为空,就执行stream_handler,如果有,两个都执行
    if file:
      file_handler = logging.FileHandler(file)
      # 设置handler级别
      file_handler.setLevel(level)
      # 添加handler
      self.addHandler(file_handler)
      # 添加日志处理器
      file_handler.setFormatter(fmt)

    stream_handler = logging.StreamHandler()
    stream_handler.setLevel(level)
    self.addHandler(stream_handler)
    stream_handler.setFormatter(fmt) 
# 为了确保每次是同一个文件,调用同样的logger对象(防止手误写错文件名字),所以在这里直接初始化logger这个对象比较好
# 可以将name,file参数写入配置文件中(这里我是直接写到了配置文件当中,也可以直接传)
logger = LoggerHandler(config.logger_name,config.level,config.logger_file)
# logger = LoggerHandler("python21",file="demo.txt") 

if __name__ == '__main__':
  logger = LoggerHandler()
  logger.debug("world")
  # 继承后---测试.py:44:root:DEBUG:world

补充知识:python3使用logging包,把日志写到系统的rsyslog中

最近要写一个python程序写日志到rsyslog中,并通过配置rsyslog的文件来将他存到一个指定文件中。

首先,我想来看看logging提供的常用模块:

logger:logger主要是用来配置和发送日志消息的。可通过logging.getLogger(name)来返回一个logger对象。

不指定name就默认为root。

这里可以取一个合适的名字。

相同的name会返回同一个logger对象。在Formatter方法中用%(name)s在日志中打印出这个name。例如:

log = logging.getLogger('mylog')
log_format = logging.Formatter(
  'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s')
 
#打印结果示例:
#Aug 2 12:44:41 [localhost] hhl-mylog-server[7409]-DEBUG: debug message
handler:将日志记录发送到目的地,如文件,socket等。这里可以通过addHandler方法添加多个handler,可以实现日志的分级过滤。如果要把日志发送到rsyslog中,就可以采用SysLogHandler(),使用这个方法前需要导入他

from logging.handlers import SysLogHandler
这个方法有两个参数、一个是rsyslog中的facility:指定的是发送的设备,如kernel,mail,system等等,他还有local0-local7预留。这里我采用local5。还有一个参数指定的是log程序的地址,在centos7上默认是/dev/log。示例如下:

log_hdlr=SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log')
对应的rsyslog设置文件(/etc/rsyslog.conf):

local5.*   /var/log/all.log
#将local5的所有日志存入all.log文件中

如果想用handler对日志信息进行过滤,可以这样:

log_hdlr.setLevel(logging.ERROR)
#这里就指定了接收error以及更高级别的日志
 

formatter:指定日志的输出格式,包括消息格式和日期字符格式,例如:

log_format = logging.Formatter(
  'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s')
#输出示例
#Aug 2 12:44:41 [localhost] hhl-mylog-server[7409]-DEBUG: debug message

formatter可调用参数有:

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

由上面的这些模块就可以实现我想要的功能啦

将日志写入到all.log文件中-----源代码:

import logging
from logging.handlers import SysLogHandler
 
log = logging.getLogger('mylog')
log.setLevel(logging.DEBUG)
log_hdlr=SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log')
log_format = logging.Formatter(
  'hhl-%(name)s-server[%(process)d]-%(levelname)s: %(message)s')
log_hdlr.setFormatter(log_format)
log_hdlr.setLevel(logging.ERROR)#接受error及以上的日志信息
log.addHandler(log_hdlr)
log.debug('debug message test')#指明级别为debug
log.error('error message test')#指明级别为error
#最后只保存error及更高优先级的日志

可能有些地方说的不对,还望大家能够指正!

以上这篇python3中的logging记录日志实现过程及封装成类的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python3 shelve模块的详解
Jul 08 Python
django实现同一个ip十分钟内只能注册一次的实例
Nov 03 Python
python实现flappy bird小游戏
Dec 24 Python
Python秒算24点实现及原理详解
Jul 29 Python
Python re 模块findall() 函数返回值展现方式解析
Aug 09 Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
Oct 30 Python
Python数据可视化:泊松分布详解
Dec 07 Python
python numpy实现rolling滚动案例
Jun 08 Python
python中的时区问题
Jan 14 Python
深入理解python多线程编程
Apr 18 Python
Python趣味爬虫之用Python实现智慧校园一键评教
May 28 Python
教你怎么用PyCharm为同一服务器配置多个python解释器
May 31 Python
Pycharm激活方法及详细教程(详细且实用)
May 12 #Python
PyTorch在Windows环境搭建的方法步骤
May 12 #Python
pycharm 2018 激活码及破解补丁激活方式
Sep 21 #Python
pycharm 激活码及使用方式的详细教程
May 12 #Python
Python-jenkins模块之folder相关操作介绍
May 12 #Python
使用python-Jenkins批量创建及修改jobs操作
May 12 #Python
Python如何使用队列方式实现多线程爬虫
May 12 #Python
You might like
php url地址栏传中文乱码解决方法集合
2010/06/25 PHP
php删除与复制文件夹及其文件夹下所有文件的实现代码
2013/01/23 PHP
PHP应用JSON技巧讲解
2013/02/03 PHP
浅谈php serialize()与unserialize()的用法
2013/06/05 PHP
对于PHP 5.4 你必须要知道的
2013/08/07 PHP
微信推送功能实现方式图文详解
2019/07/12 PHP
jQuery旋转插件jqueryrotate用法详解
2016/10/13 Javascript
JS给按钮添加跳转功能类似a标签
2017/05/30 Javascript
JavaScript中正则表达式判断匹配规则及常用方法
2017/08/03 Javascript
Vue三种常用传值示例(父传子、子传父、非父子)
2018/07/24 Javascript
使用koa-log4管理nodeJs日志笔记的使用方法
2018/11/30 NodeJs
vue2.0实现的tab标签切换效果(内容可自定义)示例
2019/02/11 Javascript
js实现星星打分效果
2020/07/05 Javascript
js前端传json后台接收‘‘被转为quot的问题解决
2020/11/12 Javascript
[01:01:42]Secret vs Optic Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
Python解释执行原理分析
2014/08/22 Python
用Python写一个无界面的2048小游戏
2016/05/24 Python
Django 导出 Excel 代码的实例详解
2017/08/11 Python
Python实现的当前时间多加一天、一小时、一分钟操作示例
2018/05/21 Python
Python之时间和日期使用小结
2019/02/14 Python
Django admin model 汉化显示文字的实现方法
2019/08/12 Python
Python脚本导出为exe程序的方法
2020/03/25 Python
Django 多对多字段的更新和插入数据实例
2020/03/31 Python
史泰博(Staples)中国官方网站:办公用品一站式采购
2016/09/05 全球购物
Spartoo英国:欧洲最大的网上鞋店
2016/09/13 全球购物
新西兰网上购物,折扣店:BestDeals.co.nz
2019/03/20 全球购物
美国珠宝精品店:Opulent Jewelers
2019/08/20 全球购物
教师节演讲稿
2014/05/06 职场文书
给校长的建议书500字
2014/05/15 职场文书
主题班会演讲稿
2014/05/22 职场文书
新农村建设汇报材料
2014/08/15 职场文书
公司2014年度工作总结
2014/12/10 职场文书
2015年前台个人工作总结
2015/04/03 职场文书
安全守法证明
2015/06/23 职场文书
编写python程序的90条建议
2021/04/14 Python
Python中常见的导入方式总结
2021/05/06 Python