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('这是一个测试')
相关推荐
Honmaple17 小时前
从零搭建与使用OpenClaw:一站式AI自动化代理工具部署指南
服务器·人工智能
Diros1g17 小时前
ubuntu多网卡网络配置
网络·ubuntu·php
小徐敲java17 小时前
视频推流服务器与FFmpeg 安装配置
服务器·ffmpeg·音视频
深蓝电商API17 小时前
aiohttp中间件实现异步请求日志与重试
爬虫·python
cici1587417 小时前
基于MATLAB的非正交多址(NOMA)系统协同中继技术提升小区边缘用户性能实现
java·服务器·matlab
Swift社区17 小时前
Docker 构建 Python FastAPI 镜像最佳实践
python·docker·fastapi
MarkHD17 小时前
Python RPA七日实战:用pyautogui打造第一个自动化脚本
python·自动化·rpa
m0_7369191017 小时前
实战:用Python分析某电商销售数据
jvm·数据库·python
蜡笔小炘17 小时前
LVS -- 部署NAT模式集群案例
linux·运维·服务器·lvs
翼龙云_cloud17 小时前
阿里云渠道商:如何优化阿里云弹性伸缩的性能?
服务器·阿里云·云计算