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

作用:

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

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记录日志实现过程及封装成类的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • python写日志封装类实例

    本文实例讲述了python实现写日志封装类.分享给大家供大家参考.具体如下: # encoding:utf-8 import sys import logging import time def writeLog(message): logger=logging.getLogger() filename = time.strftime('%Y-%m-%d',time.localtime(time.time())) handler=logging.FileHandler("./log/"

  • python3 配置logging日志类的操作

    配置类config_file: from configparser import ConfigParser class config_file: def __init__(self,conf_filePath,encoding="utf-8"): #打开配置文件,实例化ConfigParser类,并以默认utf-8的编码格式读取文件 self.cf = ConfigParser() self.cf.read(conf_filePath,encoding) def get_Int_Val

  • python3 logging日志封装实例

    一个完整的程序离不开日志,无论是开发阶段,还是测试阶段,亦或程序运行阶段,都可以通过日志查看程序的运行情况,或是定位问题. 下面是对 python3 的日志库 logging 进行了封装,对于大部分的需求应该是能满足的.(如果有不满足的地方,欢迎在下方留言) 程序结构: |--logger.py | |--singleton.py | |--demo.py | |--log | | | 2018-10-12.log logger.py import os import sys import ti

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

    作用: 主要记录信息,便于定位查看问题. python logging模块官网: https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects 三种定位问题方法: print debug调试:代码写好后,就不需要再进行调试了,所以引入了logger logging.debug() – 一般在测试环境中用 logger:当生产环境中有问题时,可以查看logger定位问题 步骤: 1.初始化日志 收集器 2.设置日志

  • js实现Element中input组件的部分功能并封装成组件(实例代码)

    现在实现的有基础用法.可清空.密码框,参考链接:https://element.eleme.cn/#/zh-CN/component/input HTML代码:想要测试哪个组件,直接将对应组件解开注释即可,标红的js和css记得修改成你自己的位置. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>js实现可清空input组件</title> &

  • Python3中的bytes和str类型详解

    Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和bytes,你不能拼接字符串和字节流,也无法在字节流里搜索字符串(反之亦然),也不能将字符串传入参数为字节流的函数(反之亦然). 下面让我们深入分析一下二者的区别和联系. 编码发展的历史 在谈bytes和str之前,需要先说说关于编码是如何发展的.. 在计算机历史的早期,美国为代表的英语系国家主导了整

  • Python3中函数参数传递方式实例详解

    本文实例讲述了Python3中函数参数传递方式.分享给大家供大家参考,具体如下: 之前在看北理工嵩天等老师的python3的课程,在第五周中老师讲到了函数的调用传递.老师讲了这样一个例子 #处理多个银行账户的余额信息 def addInterest(balances, rate): for i in range(len(balances)): balances[i] = balances[i] * (1+rate) def test(): amounts = [1000, 105, 3500,

  • 详解Python3中的迭代器和生成器及其区别

    介绍 本篇将介绍Python3中的迭代器与生成器,描述可迭代与迭代器关系,并实现自定义类的迭代器模式. 迭代的概念 上一次输出的结果为下一次输入的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值 注:循环不是迭代 while True: #只满足重复,因而不是迭代 print('====>')  迭代器 1.为什么要有迭代器? 对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式. 2.迭代器定义: 迭代器:可迭代对象执行__iter__方法,得到的结果

  • Python3中的列表生成式、生成器与迭代器实例详解

    本文实例讲述了Python3中的列表生成式.生成器与迭代器.分享给大家供大家参考,具体如下: 列表生成式 Python内置的一种极其强大的生成列表 list 的表达式.返回结果必须是列表. 基本语法: [ 变量表达式 for 变量 in 表达式 ] 示例 a = [x ** 2 for x in range(1, 10)] b = [x * x for x in range(1, 11) if x % 2 == 0] c = [m + n for m in 'ABC' for n in '123

  • 解析Python3中的Import

    Python import的搜索路径 import的搜索路径为: 搜索「内置模块」(built-in module) 搜索 sys.path 中的路径 而sys.path在初始化时,又会按照顺序添加以下路径: foo.py 所在目录(如果是软链接,那么是真正的 foo.py 所在目录)或当前目录: 环境变量 PYTHONPATH中列出的目录(类似环境变量 PATH,由用户定义,默认为空): site 模块被 import 时添加的路径1(site 会在运行时被自动 import). import

  • 对python3 中方法各种参数和返回值详解

    如下所示: # -*- coding:utf-8 -*- # Author: Evan Mi # 函数 def func1(): print('in the func1') return 0 # 过程 def func2(): print('in the func2') """ 多个值用逗号分割后返回,会分装到一个tuple中返回, 接收的时候,如果使用一个变量接收,那么这个接收变量就是一个tuple类型的 如果接收的时候也用逗号分割多个值来接收,那么可以分别对应返回tupl

  • python3.6、opencv安装环境搭建过程(图文教程)

    我需要使用tesseract-OCR的模块,vs的配置有点麻烦,所以采用py的环境,搭建. 1.在python.org网站下载python3.6版本 我下载的3.6.8的python的安装 选存放的路径和把配置环境变量选项勾上否则需要自己配置环境变量  遇 到这个页面点击一下disable path length limit 再点 close cmd或者power shell里面测试: py IDE的安装与py的配置 双击桌面图标 使用软件 安装opencv-python 在命令行中直接使用pi

  • python3中pip3安装出错,找不到SSL的解决方式

    最近在Ubuntu16.04上安装Python3.6之后,使用pip命令出现了问题,提示说找不到ssl模块,出现错误如下: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. Could not fetch URL https:*******: There was a problem confirming the ssl certific

随机推荐