python logging四大组件使用示例
1. Logger
作用:日志的“入口”,负责创建和管理日志记录,可按模块/功能划分(如logger = logging.getLogger("module_a")),支持级别控制(低于设置级别的日志会被过滤),还存在父子Logger继承关系(子Logger默认向上传递日志给父Logger)。
示例1:创建模块级Logger并设置级别
import logging
# 创建Logger(推荐用模块名命名,便于区分日志来源)
logger_api = logging.getLogger("api_module")
logger_db = logging.getLogger("db_module")
# 设置级别:只处理INFO及以上日志
logger_api.setLevel(logging.INFO)
logger_db.setLevel(logging.DEBUG)
# 添加控制台Handler(用于输出)
console_handler = logging.StreamHandler()
logger_api.addHandler(console_handler)
logger_db.addHandler(console_handler)
logger_api.debug("API模块的DEBUG日志(被过滤,不输出)")
logger_api.info("API模块的INFO日志(输出)")
logger_db.debug("DB模块的DEBUG日志(输出)")
示例2:父子Logger继承(root是顶级父Logger)
import logging
# 父Logger:parent_logger
parent_logger = logging.getLogger("parent")
parent_logger.setLevel(logging.DEBUG)
parent_handler = logging.StreamHandler()
parent_logger.addHandler(parent_handler)
# 子Logger:parent.child(自动继承父Logger的Handler和级别)
child_logger = logging.getLogger("parent.child")
child_logger.info("子Logger的日志会传递给父Logger的Handler输出") # 输出
2. Handler
作用:日志的“输出管道”,决定日志发送到哪里(控制台、文件、网络、邮件等),支持多Handler组合(一个Logger可绑定多个Handler,实现日志多端输出)。
示例1:输出到控制台(StreamHandler)
import logging
logger = logging.getLogger("console_logger")
logger.setLevel(logging.DEBUG)
# 创建控制台Handler
console_handler = logging.StreamHandler() # 默认输出到sys.stderr
console_handler.setLevel(logging.DEBUG) # Handler级别需≤Logger级别才生效
logger.addHandler(console_handler)
logger.debug("控制台输出的DEBUG日志")
示例2:输出到文件(FileHandler/RotatingFileHandler)
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger("file_logger")
logger.setLevel(logging.INFO)
# 基础文件Handler(写入单个文件)
# file_handler = logging.FileHandler("app.log", encoding="utf-8")
# 轮转文件Handler(避免文件过大,单个文件10MB,保留5个备份)
rotating_handler = RotatingFileHandler(
"app_rotate.log",
maxBytes=10*1024*1024, # 10MB
backupCount=5,
encoding="utf-8"
)
logger.addHandler(rotating_handler)
logger.info("写入到轮转文件的INFO日志")
示例3:输出到网络(SocketHandler,通过TCP发送日志)
import logging
from logging.handlers import SocketHandler
logger = logging.getLogger("network_logger")
logger.setLevel(logging.ERROR)
# 创建SocketHandler(连接到远程日志服务器的IP和端口)
socket_handler = SocketHandler("127.0.0.1", 9000) # 需提前启动日志服务器监听9000端口
logger.addHandler(socket_handler)
logger.error("通过TCP发送到远程服务器的ERROR日志")
补充:若需HTTP协议发送,可使用HTTPHandler:
from logging.handlers import HTTPHandler
http_handler = HTTPHandler("127.0.0.1:8000", "/log", method="POST")
logger.addHandler(http_handler)
3. Formatter
作用:日志的“格式化工具”,定义日志输出的样式(如包含时间、模块名、行号、日志级别等),需绑定到Handler使用(一个Handler只能绑定一个Formatter,不同Handler可绑定不同Formatter)。
示例1:基础格式(时间+级别+消息)
import logging
logger = logging.getLogger("basic_formatter")
logger.setLevel(logging.INFO)
console_handler = logging.StreamHandler()
# 定义Formatter:%(asctime)s(时间)、%(levelname)s(级别)、%(message)s(消息)
basic_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
console_handler.setFormatter(basic_formatter)
logger.addHandler(console_handler)
logger.info("基础格式的日志输出")
# 输出示例:2025-12-02 15:30:00 - INFO - 基础格式的日志输出
示例2:详细格式(含模块、行号、进程ID)
import logging
logger = logging.getLogger("detail_formatter")
logger.setLevel(logging.DEBUG)
file_handler = logging.FileHandler("detail.log", encoding="utf-8")
# 详细格式:模块名+行号+进程ID+线程名+日志内容
detail_formatter = logging.Formatter(
"%(asctime)s - %(module)s:%(lineno)d - %(process)d:%(threadName)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S" # 自定义时间格式
)
file_handler.setFormatter(detail_formatter)
logger.addHandler(file_handler)
logger.debug("详细格式的DEBUG日志")
# 输出示例:2025-12-02 15:35:00 - demo:10 - 12345:MainThread - DEBUG - 详细格式的DEBUG日志
示例3:不同Handler绑定不同Formatter
import logging
logger = logging.getLogger("multi_formatter")
logger.setLevel(logging.DEBUG)
# 控制台Handler用简单格式
console_handler = logging.StreamHandler()
console_formatter = logging.Formatter("%(levelname)s - %(message)s")
console_handler.setFormatter(console_formatter)
# 文件Handler用详细格式
file_handler = logging.FileHandler("multi.log", encoding="utf-8")
file_formatter = logging.Formatter("%(asctime)s - %(module)s - %(levelname)s - %(message)s")
file_handler.setFormatter(file_formatter)
logger.addHandler(console_handler)
logger.addHandler(file_handler)
logger.info("控制台显示简单格式,文件显示详细格式")
4. Filter
作用:日志的“筛选器”,实现比级别更细粒度的日志控制(如只允许特定模块、特定内容、特定用户的日志通过),可绑定到Logger或Handler上。
示例1:按模块筛选(只允许特定模块的日志)
import logging
class ModuleFilter(logging.Filter):
"""自定义Filter:只允许'module_order'模块的日志"""
def filter(self, record): # record是日志记录对象,包含name/levelno/message等属性
return record.name == "module_order"
logger_order = logging.getLogger("module_order")
logger_pay = logging.getLogger("module_pay")
console_handler = logging.StreamHandler()
console_handler.addFilter(ModuleFilter()) # 绑定到Handler
logger_order.addHandler(console_handler)
logger_pay.addHandler(console_handler)
logger_order.info("订单模块日志(通过筛选,输出)")
logger_pay.info("支付模块日志(被过滤,不输出)")
示例2:按内容+级别筛选(只允许包含"ERROR"且级别≥ERROR的日志)
import logging
class ContentLevelFilter(logging.Filter):
def filter(self, record):
return record.levelno >= logging.ERROR and "ERROR" in record.message
logger = logging.getLogger("content_filter")
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.addFilter(ContentLevelFilter())
logger.addHandler(console_handler)
logger.error("ERROR: 数据库连接失败(符合条件,输出)")
logger.warning("WARNING: 配置缺失(级别不够,不输出)")
logger.error("数据校验失败(不含'ERROR',不输出)")
示例3:绑定到Logger的Filter(全局筛选)
import logging
class LevelFilter(logging.Filter):
"""只允许INFO级别日志"""
def filter(self, record):
return record.levelno == logging.INFO
logger = logging.getLogger("logger_filter")
logger.addFilter(LevelFilter()) # 绑定到Logger,所有Handler都会应用此Filter
logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
logger.addHandler(console_handler)
logger.debug("DEBUG日志(被过滤)")
logger.info("INFO日志(输出)")
logger.warning("WARNING日志(被过滤)")
浙公网安备 33010602011771号