logging模块是Python中专业的日志记录工具。相比简单的print语句,logging提供了更强大、更灵活的日志功能,适合从开发调试到生产部署的各种场景。
使用logging模块的好处:
分级记录:不同重要程度的日志可以分开处理
多种输出:可以同时输出到控制台、文件、网络等
格式统一:所有日志保持一致的格式
性能更好:比print更适合生产环境
方便排查:出现问题时有完整的日志可查
import logging
# 基本配置
logging.basicConfig(level=logging.INFO)
# 记录不同级别的日志
logging.debug("这是调试信息") # 不会显示,因为级别是INFO
logging.info("程序启动完成")
logging.warning("内存使用较高")
logging.error("数据库连接失败")
logging.critical("系统即将崩溃")运行结果:
INFO:root:程序启动完成
WARNING:root:内存使用较高
ERROR:root:数据库连接失败
CRITICAL:root:系统即将崩溃import logging
# 配置日志保存到文件
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='app.log', # 日志文件名
filemode='w' # 写入模式:'w'覆盖,'a'追加
)
# 记录日志
logging.info("应用程序启动")
logging.debug("加载配置文件")
logging.warning("配置文件不存在,使用默认配置")
logging.info("应用程序初始化完成")查看生成的app.log文件,内容类似:
2024-01-20 10:30:15,123 - INFO - 应用程序启动
2024-01-20 10:30:15,124 - DEBUG - 加载配置文件
2024-01-20 10:30:15,125 - WARNING - 配置文件不存在,使用默认配置
2024-01-20 10:30:15,126 - INFO - 应用程序初始化完成Python定义了6个日志级别:
import logging
# 查看各级别的数值
print(f"DEBUG: {logging.DEBUG}")
print(f"INFO: {logging.INFO}")
print(f"WARNING: {logging.WARNING}")
print(f"ERROR: {logging.ERROR}")
print(f"CRITICAL: {logging.CRITICAL}")
# 设置级别为DEBUG,记录所有日志
logging.basicConfig(level=logging.DEBUG)
def test_levels():
logging.debug("详细的调试信息")
logging.info("程序运行状态")
logging.warning("需要注意的情况")
logging.error("错误信息")
logging.critical("严重错误")
test_levels()import logging
# 详细配置日志格式
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)-8s - [%(filename)s:%(lineno)d] - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# 创建不同模块的日志记录器
logger1 = logging.getLogger("database")
logger2 = logging.getLogger("web_server")
logger1.info("数据库连接成功")
logger2.warning("请求超时")输出示例:
2024-01-20 10:30:15 - database - INFO - [example.py:15] - 数据库连接成功
2024-01-20 10:30:16 - web_server - WARNING - [example.py:16] - 请求超时import logging
def setup_logger():
"""创建自定义日志记录器"""
# 创建记录器
logger = logging.getLogger("my_app")
logger.setLevel(logging.DEBUG) # 设置记录器级别
# 避免重复添加处理器
if logger.handlers:
return logger
# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # 控制台只显示INFO及以上
# 创建文件处理器
file_handler = logging.FileHandler("debug.log")
file_handler.setLevel(logging.DEBUG) # 文件记录所有DEBUG及以上日志
# 创建格式器
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# 为处理器设置格式
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 为记录器添加处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)
return logger
# 使用自定义记录器
logger = setup_logger()
logger.debug("调试信息") # 只写入文件
logger.info("普通信息") # 同时输出到控制台和文件
logger.error("错误信息") # 同时输出到控制台和文件import logging
# 配置基础格式
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
class DatabaseManager:
def __init__(self):
self.logger = logging.getLogger("app.database")
def connect(self):
self.logger.info("连接数据库")
# 模拟连接过程
self.logger.debug("数据库连接参数: host=localhost, port=5432")
def query(self, sql):
self.logger.info(f"执行SQL查询: {sql}")
self.logger.debug(f"查询详情: {sql}")
class WebServer:
def __init__(self):
self.logger = logging.getLogger("app.webserver")
def handle_request(self, path):
self.logger.info(f"处理请求: {path}")
self.logger.debug(f"请求头信息: ...")
# 使用不同模块的记录器
db = DatabaseManager()
server = WebServer()
db.connect()
db.query("SELECT * FROM users")
server.handle_request("/api/users")import logging
import logging.handlers
import os
def setup_application_logging(app_name="my_app"):
"""设置应用程序日志"""
# 创建日志目录
log_dir = "logs"
if not os.path.exists(log_dir):
os.makedirs(log_dir)
# 主记录器
logger = logging.getLogger(app_name)
logger.setLevel(logging.DEBUG)
# 避免重复配置
if logger.handlers:
return logger
# 1. 控制台处理器 - 显示重要信息
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 2. 详细文件处理器 - 记录所有调试信息
debug_handler = logging.FileHandler(
os.path.join(log_dir, f"{app_name}_debug.log")
)
debug_handler.setLevel(logging.DEBUG)
# 3. 错误文件处理器 - 只记录错误和严重错误
error_handler = logging.FileHandler(
os.path.join(log_dir, f"{app_name}_error.log")
)
error_handler.setLevel(logging.ERROR)
# 4. 轮转文件处理器 - 自动分割大文件
rotating_handler = logging.handlers.RotatingFileHandler(
os.path.join(log_dir, f"{app_name}.log"),
maxBytes=10*1024*1024, # 10MB
backupCount=5
)
rotating_handler.setLevel(logging.INFO)
# 创建格式器
detailed_formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)-8s - %(filename)s:%(lineno)d - %(message)s'
)
simple_formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(message)s'
)
# 设置格式
console_handler.setFormatter(simple_formatter)
debug_handler.setFormatter(detailed_formatter)
error_handler.setFormatter(detailed_formatter)
rotating_handler.setFormatter(simple_formatter)
# 添加处理器
logger.addHandler(console_handler)
logger.addHandler(debug_handler)
logger.addHandler(error_handler)
logger.addHandler(rotating_handler)
return logger
# 使用应用程序日志
app_logger = setup_application_logging("my_application")
def process_data(data):
app_logger.info(f"开始处理数据,大小: {len(data)}")
app_logger.debug(f"数据内容: {data[:100]}...")
try:
# 模拟数据处理
result = len(data) * 2
app_logger.info(f"数据处理完成,结果: {result}")
return result
except Exception as e:
app_logger.error(f"数据处理失败: {e}")
raise
# 测试日志记录
data = "这是一些测试数据" * 10
process_data(data)import logging
import traceback
# 配置日志
logging.basicConfig(
level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='error.log'
)
logger = logging.getLogger("error_tracker")
def safe_divide(a, b):
"""安全除法,记录异常"""
try:
result = a / b
logger.info(f"除法计算: {a} / {b} = {result}")
return result
except ZeroDivisionError:
logger.error(f"除零错误: {a} / {b}")
return None
except Exception as e:
# 记录完整的异常信息
logger.error(f"计算错误: {e}")
logger.error(f"异常详情:\n{traceback.format_exc()}")
return None
def process_calculation():
"""处理计算任务"""
logger.info("开始处理计算任务")
results = []
calculations = [(10, 2), (8, 0), ("10", 2), (15, 3)]
for a, b in calculations:
result = safe_divide(a, b)
if result is not None:
results.append(result)
logger.info(f"计算结果: {result}")
else:
logger.warning(f"计算失败: {a} / {b}")
logger.info(f"计算任务完成,成功: {len(results)}/{len(calculations)}")
return results
# 运行测试
process_calculation()import logging
from logging.handlers import RotatingFileHandler
def setup_rotating_log():
"""设置轮转日志"""
logger = logging.getLogger("rotating_log")
logger.setLevel(logging.INFO)
# 创建轮转处理器
handler = RotatingFileHandler(
"app.log",
maxBytes=1024, # 1KB,实际使用时应该设置更大
backupCount=3 # 保留3个备份文件
)
formatter = logging.Formatter('%(asctime)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
# 测试轮转日志
logger = setup_rotating_log()
for i in range(100):
logger.info(f"这是第{i}条日志记录,用于测试日志轮转功能")import logging
from logging.handlers import TimedRotatingFileHandler
import time
def setup_timed_rotating_log():
"""设置按时间轮转的日志"""
logger = logging.getLogger("timed_log")
logger.setLevel(logging.INFO)
# 创建时间轮转处理器
handler = TimedRotatingFileHandler(
"timed_app.log",
when='S', # 每秒轮转,实际可用 'H'(小时)、'D'(天)、'W0'(周)
interval=5, # 每5秒
backupCount=3
)
formatter = logging.Formatter('%(asctime)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
# 测试时间轮转
logger = setup_timed_rotating_log()
start_time = time.time()
while time.time() - start_time < 20: # 运行20秒
logger.info("时间轮转日志测试")
time.sleep(1)import logging
import sys
def setup_production_logging():
"""生产环境日志配置"""
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# 清除现有处理器
for handler in logger.handlers[:]:
logger.removeHandler(handler)
# JSON格式处理器(便于日志分析)
json_handler = logging.StreamHandler(sys.stdout)
json_handler.setLevel(logging.INFO)
# 错误邮件处理器(实际使用时需要配置SMTP)
# error_mail_handler = logging.handlers.SMTPHandler(
# mailhost=('smtp.example.com', 587),
# fromaddr='app@example.com',
# toaddrs=['admin@example.com'],
# subject='Application Error',
# credentials=('username', 'password')
# )
# error_mail_handler.setLevel(logging.ERROR)
# 设置格式
formatter = logging.Formatter(
'{"time": "%(asctime)s", "level": "%(levelname)s", '
'"logger": "%(name)s", "message": "%(message)s"}'
)
json_handler.setFormatter(formatter)
# error_mail_handler.setFormatter(formatter)
# 添加处理器
logger.addHandler(json_handler)
# logger.addHandler(error_mail_handler)
return logger
# 生产环境使用
setup_production_logging()
logging.info("应用程序在生产环境启动")import logging
# 在调试时使用,生产环境应该关闭
DEBUG_MODE = False
class OptimizedLogger:
"""优化性能的日志记录器"""
def __init__(self, name):
self.logger = logging.getLogger(name)
self.debug_mode = DEBUG_MODE
def debug(self, message, *args):
"""只在调试模式记录DEBUG日志"""
if self.debug_mode:
self.logger.debug(message, *args)
def info(self, message, *args):
self.logger.info(message, *args)
def error(self, message, *args):
self.logger.error(message, *args)
# 使用优化后的记录器
app_log = OptimizedLogger("optimized_app")
def expensive_operation():
# 昂贵的调试信息计算
debug_info = "详细的调试数据..." # 这个计算在非调试模式下也会执行
app_log.debug(debug_info) # 但只在调试模式下记录
def better_expensive_operation():
# 更好的方式:使用lambda延迟计算
app_log.debug(lambda: "详细的调试数据..." + expensive_calculation())
# 或者在方法内判断
if app_log.debug_mode:
debug_info = "详细的调试数据..." + expensive_calculation()
app_log.logger.debug(debug_info)
def expensive_calculation():
return "计算结果"| 类 | 说明 | 示例 |
|---|---|---|
| logging.Logger | 记录器,用于发出日志消息(通过 logging.getLogger(name) 获取) | logger = logging.getLogger("my_logger") |
| logging.Handler | 处理器,决定日志输出位置(如文件、控制台等) | handler = logging.FileHandler("app.log") |
| logging.Formatter | 格式化器,控制日志输出的格式 | formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') |
| logging.Filter | 过滤器,用于更精细地控制日志记录 | filter = logging.Filter("module.name") |
| 方法 | 说明 | 示例 |
|---|---|---|
| logger.setLevel(level) | 设置日志级别(如 logging.DEBUG、logging.INFO) | logger.setLevel(logging.DEBUG) |
| logger.debug(msg) | 记录 DEBUG 级别日志 | logger.debug("调试信息") |
| logger.info(msg) | 记录 INFO 级别日志 | logger.info("程序启动") |
| logger.warning(msg) | 记录 WARNING 级别日志 | logger.warning("磁盘空间不足") |
| logger.error(msg) | 记录 ERROR 级别日志 | logger.error("操作失败") |
| logger.critical(msg) | 记录 CRITICAL 级别日志 | logger.critical("系统崩溃") |
| logger.addHandler(handler) | 添加处理器 | logger.addHandler(handler) |
| logger.addFilter(filter) | 添加过滤器 | logger.addFilter(filter) |
| Handler 类型 | 说明 | 示例 |
|---|---|---|
| StreamHandler | 输出到流(如控制台) | handler = logging.StreamHandler() |
| FileHandler | 输出到文件 | handler = logging.FileHandler("app.log") |
| RotatingFileHandler | 按文件大小分割日志 | handler = logging.RotatingFileHandler("app.log", maxBytes=1e6, backupCount=3) |
| TimedRotatingFileHandler | 按时间分割日志 | handler = logging.TimedRotatingFileHandler("app.log", when="midnight") |
| SMTPHandler | 通过邮件发送日志 | handler = logging.SMTPHandler("mail.example.com", "from@example.com", "to@example.com", "Error Log") |
| 级别 | 数值 | 说明 |
|---|---|---|
| CRITICAL | 50 | 严重错误,程序可能无法继续运行 |
| ERROR | 40 | 错误,但程序仍可运行 |
| WARNING | 30 | 警告信息(默认级别) |
| INFO | 20 | 程序运行信息 |
| DEBUG | 10 | 调试信息 |
| NOTSET | 0 | 继承父记录器的级别 |
| 字段 | 说明 | 示例输出 |
|---|---|---|
| %(asctime)s | 日志创建时间 | 2023-01-01 12:00:00,123 |
| %(levelname)s | 日志级别名称 | INFO |
| %(message)s | 日志消息内容 | 程序启动成功 |
| %(name)s | 记录器名称 | my_logger |
| %(filename)s | 生成日志的文件名 | app.py |
| %(lineno)d | 生成日志的行号 | 42 |
| %(funcName)s | 生成日志的函数名 | main |
| 方法 | 说明 | 示例 |
|---|---|---|
| logging.basicConfig() | 一键配置日志级别、处理器和格式(通常在程序入口调用) | logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s') |
常用参数:
level:设置根记录器级别
filename:输出到文件
filemode:文件模式(如 'w' 覆盖)
format:格式字符串
datefmt:日期格式(如 "%Y-%m-%d %H:%M:%S")
logging模块是Python中专业的日志记录解决方案:
分级管理:DEBUG、INFO、WARNING、ERROR、CRITICAL五个级别
灵活输出:可以输出到控制台、文件、网络等
格式自定义:完全控制日志的显示格式
性能优化:适合生产环境使用
异常跟踪:完整记录异常信息
使用建议:
开发时使用DEBUG级别,生产环境使用INFO或WARNING
为不同模块创建不同的记录器
重要应用配置日志轮转,避免日志文件过大
记录异常时要包含完整的堆栈信息
合理的日志记录是程序可维护性的重要保障。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!