python-日志模块以及实际使用设计

python-日志模块以及实际使用设计

1. 基本组成

日志模块四个组成部分:

  1. 日志对象:产生日志信息
  2. 日志处理器:将日志信息输出到指定地方,例如终端、文件。
  3. 格式器:在日志处理器输出之前,对信息进行各方面的美化。
  4. 过滤器:在日志处理器输出之前,将信息按照过滤器的条件过滤一遍。比如按照日志级别进行过滤。

日志本质上就是如下流程:
日志信息 日志信息 日志信息 日志信息 过滤的日志信息 过滤日志信息 格式的日志信息 格式的日志信息 日志对象 日志处理器1 日志处理器2 过滤器:过滤日志信息 过滤器:过滤日志信息 格式器:格式日志信息 格式器:格式日志信息 输出 输出

日志级别:

  1. logging.DEBUG,是个int数,等于10
  2. logging.INFO == 20
  3. logging.WARNING == 30
  4. logging.ERROR == 40
  5. logging.CRITICAL == 50
2. 基本使用-在终端打印日志

logging.StreamHandler将日志信息输出到终端上。

python 复制代码
import logging 

# 1,创建日志对象
logger = logging.getLogger() 

# 2,设置日志对象级别,INFO以及INFO以上信息被输出。
# 本质上就是自己规定哪些信息属于INFO级别,比如正常运行的记录。
logger.setLevel(logging.INFO) 

# 3,创建日志处理器
# 将日志处理器加入到日志对象中,可以绑定多个。
# 绑定终端处理器,将日志信息输出到终端上。
stream_handler_1 = logging.StreamHandler()
stream_handler_2 = logging.StreamHandler()
logger.addHandler(stream_handler_1)
# 绑定第二个终端处理器。
logger.addHandler(stream_handler_2)

# 4,日志对象产生日志信息
# 日志对象可以产生五种级别的日志信息。
logger.debug('这是一个debug级别的日志信息')
logger.info('这是一个info级别的日志信息')
logger.warning('这是一个warning级别的日志信息')
logger.error('这是一个error级别的日志信息')
logger.critical('这是一个critical级别的日志信息')
3. 基本使用-日志打印到文件

本质就是更换日志处理器,利用logging.FileHandler()将日志信息输出到文件内。

python 复制代码
import logging

logger = logging.getLogger()
# 设置日志最低级别。
logger.setLevel(logging.INFO)

# 绑定第一个文件处理器, 将日志信息输出到文件内。
file_handler = logging.FileHandler(filename='../logs/test.log', mode='a', encoding='utf8')
logger.addHandler(file_handler)
# 绑定第二个终端处理器,将日志信息输出到终端上。
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)


# 日志对象产生日志信息
logger.debug('这是一个debug级别的日志信息')
logger.info('这是一个info级别的日志信息')
logger.warning('这是一个warning级别的日志信息')
logger.error('这是一个error级别的日志信息')
logger.critical('这是一个critical级别的日志信息')
4. 基本使用-使用格式器美化日志信息
  1. 创建方法:使用logging.Formatter()。
  2. 使用方法:处理器绑定格式器。通过setFormatter()方法进行绑定。
  3. 使用目的:日志信息需要提供功能:查看什么时间哪个文件的哪一行发生了什么情况。
python 复制代码
import logging

logger = logging.getLogger()

# 设置日志最低级别。
logger.setLevel(logging.INFO)

# 绑定终端处理器
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)

# 绑定文件处理器
file_handler = logging.FileHandler(filename='../logs/test.log', mode='a', encoding='utf8')
logger.addHandler(file_handler)

# 创建格式器
# asctime:时间。
# levelname: 日志信息级别。
# filename: 输出日志信息代码所在的文件名称。
# lineno:输出语句所在文件的行数。
# message: 日志信息。
fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')

# 将格式器绑定到处理器上
stream_handler.setFormatter(fmt)
file_handler.setFormatter(fmt)

# 日志对象产生日志信息
logger.debug('这是一个debug级别的日志信息')
logger.info('这是一个info级别的日志信息')
logger.warning('这是一个warning级别的日志信息')
logger.error('这是一个error级别的日志信息')
logger.critical('这是一个critical级别的日志信息')

# 终端中会输出如下信息:
'''
2024-01-06 18:42:43,755 - [INFO] - 1.py[25]:这是一个info级别的日志信息
2024-01-06 18:42:43,756 - [WARNING] - 1.py[26]:这是一个warning级别的日志信息
2024-01-06 18:42:43,756 - [ERROR] - 1.py[27]:这是一个error级别的日志信息
2024-01-06 18:42:43,757 - [CRITICAL] - 1.py[28]:这是一个critical级别的日志信息
'''
5. 基本使用-使用过滤器过滤日志信息
  1. 创建方法:继承重写一下logging.Filter类的filter方法。
  2. 使用方法:处理器通过addFilter()方法绑定过滤器。
  3. 使用目的:一般情况都是按照日志级别进行过滤,目的在于对将不同级别的日志信息输出到不同的文件中,方便进行查看。
python 复制代码
import logging

# 1. 创建过滤器
class LogFilter(logging.Filter):
    def __init__(self, name, low_level=10, high_level=50):
        super().__init__(name=name)
        self.low_level = low_level
        self.high_level = high_level

    def filter(self, record):
        return True if self.low_level <= record.levelno <= self.high_level else False


logger = logging.getLogger()

# 2. 设置日志最低级别。
logger.setLevel(logging.DEBUG)

# 3. 绑定终端处理器
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)
# 绑定文件处理器
file_handler = logging.FileHandler(filename='./test.log', mode='a', encoding='utf8')
logger.addHandler(file_handler)

# 4. 创建格式器
fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')
# 将格式器绑定到处理器上
stream_handler.setFormatter(fmt)
file_handler.setFormatter(fmt)

# 5. 创建过滤器
normal_filter = LogFilter('normal', logging.DEBUG, 20)
nonormal_filter = LogFilter('nonormal', logging.WARNING, logging.CRITICAL)

# 6. 终端处理器绑定正常过滤器
stream_handler.addFilter(normal_filter)

# 7. 文件处理器绑定非正常过滤器
file_handler.addFilter(nonormal_filter)

# 日志对象产生日志信息
logger.debug('这是一个debug级别的日志信息')
logger.info('这是一个info级别的日志信息')
logger.warning('这是一个warning级别的日志信息')
logger.error('这是一个error级别的日志信息')
logger.critical('这是一个critical级别的日志信息')


# 终端中打印以下信息:
'''
2024-01-06 20:40:14,689 - [DEBUG] - 1.py[46]:这是一个debug级别的日志信息
2024-01-06 20:40:14,689 - [INFO] - 1.py[47]:这是一个info级别的日志信息
'''

# 文件中打印以下信息
'''
2024-01-06 20:40:14,689 - [WARNING] - 1.py[48]:这是一个warning级别的日志信息
2024-01-06 20:40:14,689 - [ERROR] - 1.py[49]:这是一个error级别的日志信息
2024-01-06 20:40:14,689 - [CRITICAL] - 1.py[50]:这是一个critical级别的日志信息
'''
6. 进阶使用-日常工作中的日志模块设计

日常工作中日志模块设计思路:

  1. 使用时只需要配置日志文件存放地址就可以。
  2. 日志文件的存放时间间隔:每小时或者每天。
  3. 设置日志的输出级别。
  4. 在服务模块中,存放间隔、存放路径都可以放在配置文件中。
  5. 日志模块一般情况下放在工程中的util文件中。看自己习惯。
    util/logger.py,设计如下,也可以按照自己的额外思路进行设计。
python 复制代码
import logging
import time
import os

# 一个logging.Logger()对象
class Logging:
    def __init__(self):
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)

# 一个自定义过滤器
class Filter(logging.Filter):
    def __init__(self, name, low_level, high_level):
        super().__init__(name=name)
        self.low_level = low_level
        self.high_level = high_level

    def filter(self, record):
        return True if self.low_level <= record.levelno <= self.high_level else False

# 主函数,从logger.py文件汇总引人get_logger函数
def get_logger(log_root_path, low_level=logging.INFO, high_level=logging.CRITICAL):
    logger = Logging().logger
    log_file_name = f"{time.strftime('%Y%m%d-%H', time.localtime())}.log"
    handler = logging.FileHandler(filename=os.path.join(log_root_path, log_file_name),
                                  mode='a',
                                  encoding='utf-8')
    fmt = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s[%(lineno)d]:%(message)s')
    filter = Filter('dev', low_level, high_level)
    handler.setFormatter(fmt)
    handler.addFilter(filter)
    logger.addHandler(handler)
    return logger


if __name__ == "__main__":
    # 正常情况下只需要输入日志路径即可。
    logger = get_logger('./')
    logger.info('这是一个测试')
相关推荐
BD_Marathon7 分钟前
SpringBoot——辅助功能之切换web服务器
服务器·前端·spring boot
张登杰踩28 分钟前
VIA标注格式转Labelme标注格式
python
Learner1 小时前
Python数据类型(四):字典
python
AI大模型应用之禅1 小时前
全球股市估值与可持续农业垂直种植技术的关系
网络·ai
掘根1 小时前
【仿Muduo库项目】HTTP模块2——HttpRequest子模块,HttpResponse子模块
网络·网络协议·http
odoo中国1 小时前
Odoo 19 模块结构概述
开发语言·python·module·odoo·核心组件·py文件按
Jelena157795857922 小时前
Java爬虫api接口测试
python
necessary6532 小时前
使用Clion查看linux环境中的PG源码
linux·运维·服务器
踩坑记录3 小时前
leetcode hot100 3.无重复字符的最长子串 medium 滑动窗口(双指针)
python·leetcode
MOON404☾4 小时前
006.Backdoor后门编写
网络·安全·网络安全·系统安全