python --logging封装
·
import logging
import time
import threading
from logging.handlers import TimedRotatingFileHandler
class AppLogger:
# 自定义控制台彩色格式器 + 兼容py3.7毫秒处理 + level居中8位
class ColorFormatter(logging.Formatter):
COLOR_MAP = {
logging.DEBUG: "\033[36m",
logging.INFO: "\033[32m",
logging.WARNING: "\033[33m",
logging.ERROR: "\033[31m",
logging.CRITICAL: "\033[41;37m"
}
RESET = "\033[0m"
def formatTime(self, record, datefmt=None):
ct = self.converter(record.created)
t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
ms = f"{int(record.msecs):03d}"
return f"{t},{ms}"
def format(self, record):
old_level = record.levelname
record.levelname = record.levelname.center(8)
raw_msg = super().format(record)
record.levelname = old_level
color = self.COLOR_MAP.get(record.levelno, "")
return f"{color}{raw_msg}{self.RESET}"
# 普通文件格式化器
class PlainFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
ct = self.converter(record.created)
t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
ms = f"{int(record.msecs):03d}"
return f"{t},{ms}"
def format(self, record):
old_level = record.levelname
record.levelname = record.levelname.center(8)
raw_msg = super().format(record)
record.levelname = old_level
return raw_msg
def __init__(self, log_name="app", save_file: bool = True):
self.logger = logging.getLogger(log_name)
if self.logger.handlers:
return
self.logger.setLevel(logging.DEBUG)
self.logger.propagate = False
fmt_str = "%(asctime)s[%(levelname)8s][%(filename)s:%(lineno)d] %(message)s"
# 控制台彩色输出
console_handler = logging.StreamHandler()
console_handler.setFormatter(self.ColorFormatter(fmt_str))
self.logger.addHandler(console_handler)
# 文件按天轮转
if save_file:
file_handler = TimedRotatingFileHandler(
filename=r"D:\code\app.log", # 日志主文件路径,日志默认实时写入这个文件
when="midnight", # 日志切割时机:midnight=每天凌晨0点自动切分日志
interval=1, # 切割间隔倍数,配合when使用;interval=1代表每1天切一次
backupCount=30, # 最多保留30个历史归档日志,超过数量自动删除最旧日志,实现留存一个月
encoding="utf-8", # 日志文件编码为utf-8,避免中文乱码
delay=True # 延迟创建文件:程序启动没有日志写入时,不会自动生成空日志文件,有日志才创建
)
file_handler.suffix = "%Y-%m-%d" # 切割后的历史日志后缀格式,切分后文件名示例:app.log.2026-06-17
file_handler.setFormatter(self.PlainFormatter(fmt_str))
self.logger.addHandler(file_handler)
def get_logger(self):
return self.logger
# ---------------------- 多线程压测逻辑 ----------------------
log = AppLogger(save_file=True).get_logger()
def thread_task(thread_id):
"""单个线程循环打日志"""
for i in range(200):
log.debug(f"线程{thread_id} debug 计数{i}")
log.info(f"线程{thread_id} info 计数{i}")
log.warning(f"线程{thread_id} warn 计数{i}")
log.error(f"线程{thread_id} error 计数{i}")
log.critical(f'asdasdasdsad')
time.sleep(0.001)
if __name__ == "__main__":
thread_count = 20
thread_list = []
log.info(f"===== 启动{thread_count}个线程开始日志压测 =====")
for tid in range(thread_count):
t = threading.Thread(target=thread_task, args=(tid,))
thread_list.append(t)
t.start()
# 等待所有线程结束
for t in thread_list:
t.join()
log.info("===== 所有线程执行完毕 =====")
更多推荐


所有评论(0)