零碎知识 Python 之日志处理(logging 模块)详解

大海 · 2022年04月27日 · 2045 次阅读

Python 之日志处理(logging 模块)详解

logging 模块简介

logging 模块是 Python 内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比 print,具备如下优点
1、可以通过设置不同的日志等级,在 release 版本中只输出重要信息,而不必显示大量的调试信息
2、print 将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging 则可以由开发者决定将信息输出到什么地方,以及怎么输出

日志等级(level)

DEBUG < INFO < WARNING < ERROR < CRITICAL

  • DEBUG 最详细的日志信息,典型应用场景是 问题诊断
  • INFO 信息详细程度仅次于 DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作
  • WARNING 当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的
  • ERROR 由于一个更严重的问题导致某些功能不能正常运行时记录的信息
  • CRITICAL 当发生严重错误,导致应用程序不能继续运行时记录的信息

logging 模块可以指定日志记录器的日志级别,只有级别大于或等于该指定日志级别的日志记录才会被输出,小于该等级的日志记录将会被丢弃

logger

logger:日志对象,logging 模块中最基础的对象,用 logging.getLogger(name) 方法进行初始化,name 可以不填。通常 logger 的名字我们对应模块名,如聊天模块、数据库模块、验证模块等
为程序提供记录日志的接口
判断日志所处级别,并判断是否要过滤
根据其日志级别将该条日志分发给不同 handler

其常用函数有:
Logger.setLevel() 设置日志级别
Logger.addHandler() 和 Logger.removeHandler() 添加和删除一个 Handler
Logger.addFilter() 添加一个 Filter

setLevel:设置日志等级
logger=logging.getLogger()
logger.setLevel(logging.DEBUG) # 设置日志等级

logging

1、Formatter 用于控制日志信息的最终输出格式

logging.Formatter(参数)
formatter=logging.Formatter('[%(asctime) s]-%(filename) s]-%(levelname) s:%(message) s')

  • %(name) s Logger 的名字
  • %(levelno) s 数字形式的日志级别
  • %(levelname) s 文本形式的日志级别
  • %(pathname) s 调用日志输出函数的模块的完整路径名,可能没有
  • %(filename) s 调用日志输出函数的模块的文件名
  • %(module) s 调用日志输出函数的模块名
  • %(funcName) s 调用日志输出函数的函数名
  • %(lineno) d 调用日志输出函数的语句所在的代码行
  • %(created) f 当前时间,用 UNIX 标准的表示时间的浮 点数表示
  • %(relativeCreated) d 输出日志信息时的,自 Logger 创建以 来的毫秒数
  • %(asctime) s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
  • %(thread) d 线程 ID。可能没有
  • %(threadName) s 线程名。可能没有
  • %(process) d 进程 ID。可能没有
  • %(message) s 用户输出的消息
2、Handler 基于日志级别对日志进行分发,如设置为 WARNING 级别的 Handler 只会处理 WARNING 及以上级别的日志。具体的应用如一个应用要把所有的日志打在文件中,并把 ERROR 以上级别的日志打印到屏幕,把 CRITICAL 级别的日志发邮件

常用函数有:

  • setLevel() 设置级别
  • setFormatter() 设置 Formatter
  • logging.FileHandler(参数) 创建一个 FileHandler
  • logger.addHandler(fh) 添加
  • logging.StreamHandler() 创建一个 StreamHandler
  • logger.addHandler(ch) 添加

创建一个 FileHandler,用于写到本地
fh=logging.FileHandler(logname,'a',"utf-8")
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
logger.addHandler(fh)

创建一个 StreamHandler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
logger.addHandler(ch)

import os,time,logging
#日志存放路径
log_path=os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))),'logs')
# 如果不存在这个logs文件夹,就自动创建一个
if not os.path.exists(log_path):os.mkdir(log_path)
class Log():
    def __init__(self):
        #在日志路径下添加日志文件名
        self.logname=os.path.join(log_path,'%s.log'%time.strftime('%Y_%m_%d'))
        #logger日志对象初始化
        self.logger=logging.getLogger()
        #设置日志等级
        self.logger.setLevel(logging.DEBUG)
        #日志输出格式
        self.formatter=logging.Formatter('[%(asctime)s]-%(filename)s]-%(levelname)s:%(message)s')
    def __console(self,level,message):
        # 创建一个 FileHandler,用于写到本地
        fh=logging.FileHandler(self.logname,'a',"utf-8")
        fh.setLevel(logging.DEBUG)
        fh.setFormatter(self.formatter)
        self.logger.addHandler(fh)
        # 创建一个 StreamHandler,用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(self.formatter)
        self.logger.addHandler(ch)
        if level=='info':
            self.logger.info(message)
        elif level=='debug':
            self.logger.debug(message)
        elif level=='warning':
            self.logger.warning(message)
        elif level=='error':
            self.logger.error(message)
        # 这两行代码是为了避免日志输出重复问题
        self.logger.removeHandler(ch)
        self.logger.removeHandler(fh)
        # 关闭打开的文件
        fh.close()
    def debug(self, message):
        self.__console('debug', message)
    def info(self, message):
        self.__console('info', message)
    def warning(self, message):
        self.__console('warning', message)
    def error(self, message):
        self.__console('error', message)
if __name__ == "__main__":
    log=Log()
    log.info("---测试开始---")
    log.info("操作步骤1,2,3")
    log.warning("---测试结束---")



C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py
[2019-04-10 17:17:18,025]-test.py]-INFO:---测试开始---
[2019-04-10 17:17:18,026]-test.py]-INFO:操作步骤1,2,3
[2019-04-10 17:17:18,028]-test.py]-WARNING:---测试结束---

Process finished with exit code 0
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册