logging 笔记¶
logging 是 Python 的标准库模块,用于记录程序运行时的信息。它比简单的 print() 语句更强大,提供了灵活的日志记录系统。
日志级别¶
logging 模块定义了以下几个级别,按严重程度递增:
| 级别 | 数值 | 描述 |
|---|---|---|
| NOTSET | 0 | 未设置 |
| DEBUG | 10 | 详细的信息,通常只在诊断问题时使用 |
| INFO | 20 | 一般信息,证明程序按预期工作 |
| WARNING | 30 | 警告信息,程序仍能正常工作,但可能存在问题 |
| ERROR | 40 | 错误信息,程序某些功能无法正常执行 |
| CRITICAL | 50 | 严重错误,程序可能无法继续运行 |
基础用法¶
简单使用¶
logging.debug('这是调试信息')
logging.info('这是一般信息')
logging.warning('这是警告信息')
logging.error('这是错误信息')
logging.critical('这是严重错误信息')
基本配置¶
logging.basicConfig() 用于配置日志系统的基本设置,其有以下常用参数:
level: 设置日志级别,默认是WARNINGformat: 设置日志输出格式,默认为%(levelname)s:%(name)s:%(message)s%(name)sLogger 名称%(levelno)s日志级别数值%(levelname)s日志级别名称%(pathname)s调用日志记录函数的文件路径%(filename)s文件名%(module)s模块名%(lineno)d行号%(funcName)s函数名%(created)f创建时间%(asctime)s格式化时间%(msecs)03d毫秒%(message)s日志消息%(thread)d线程 ID%(threadName)s线程名称%(process)d进程 ID
datefmt: 设置时间格式%Y/%y/%m/%d年/两位数年/月/日%H/%M/%S小时/分钟/秒%z/%Z时区代码/时区名称%a/%A星期几缩写/全称%b/%B月份缩写/全称%pAM/PM%j一年中的第几天%U一年中的第几周,以周日为一周的开始%W一年中的第几周,以周一为一周的开始%x本地化的日期,包含年月日%X本地化的时间,包含时分秒%c本地化的日期和时间
filename: 指定日志输出到文件,若不指定则输出到控制台filemode: 设置文件模式,默认为'a'(追加模式)encoding: 设置文件编码force: 强制覆盖已有的日志配置
Logger 对象¶
当使用 logging.info() 等函数时,实际上是使用了一个默认的 root logger。可以通过 logging.getLogger(name) 创建独立的 logger 来更好地管理日志:
logging.getLogger()不输入参数时会返回 root logger- 支持层级结构,可以输入
parent.child形式的名称,子 Logger 可继承父 Logger 的配置
logger 的常见属性有:
name: Logger 名称level: 当前日志级别parent: 父 Logger,若不存在则为根日志器handlers: 处理器列表propagate: 是否将日志消息传递给父 Logger,若为 True 可能会导致日志重复输出,默认为 True
常见方法有:
setLevel(level): 设置日志级别addHandler(handler): 添加处理器removeHandler(handler): 移除处理器hasHandlers(): 检查是否有处理器isEnabledFor(level): 检查是否启用指定级别的日志记录
Handler 对象¶
Handler 是日志记录的处理器,用于将日志消息发送到不同的目的地,如控制台、文件、网络等。每个 Handler 都可以有自己的日志级别和格式化器。
常见的 Handler 有:
logging.StreamHandler: 输出到控制台stream: 指定输出流,默认为sys.stderr
logging.FileHandler: 输出到文件filename: 指定输出文件名mode: 文件模式,默认为'a'(追加模式)encoding: 文件编码
logging.handlers.RotatingFileHandler: 按大小轮转日志文件,当日志文件达到指定大小时,自动创建新文件并归档旧日志filenamemodeencoding: 同FileHandlermaxBytes: 单个文件的最大字节数,默认为 0backupCount: 保留的备份文件数量,默认为 0
logging.handlers.TimedRotatingFileHandler: 按时间轮转日志文件filenamemodeencodingbackupCount: 同RotatingFileHandlerwhen: 轮转时间单位,支持S(秒)、M(分钟)、H(小时)、D(天)、midnight(午夜)interval: 轮转间隔,单位为when
logging.handlers.SMTPHandler: 通过 SMTP 发送日志邮件mailhost: 邮件服务器地址,元组形式(host, port),例如("smtp.example.com", 587)fromaddr: 发件人地址,email 格式的字符串toaddrs: 收件人地址列表,email 格式的字符串列表subject: 邮件主题credentials: 邮箱登录凭据,可以是元组形式(username, password)
logging.handlers.HTTPHandler: 通过 HTTP 发送日志host: 服务器地址url: 发送日志的 URL 路径method: HTTP 方法,默认为GET
Handler 的常见方法有:
setLevel(level): 设置 Handler 的日志级别setFormatter(formatter): 设置 Handler 的格式化器,其中 Formatter 格式化器通过logging.Formatter创建,其参数为fmt和datefmt,基本用法如前文basicConfig中所述
使用示例:
import logging
# 创建 logger
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG)
# 创建 handler
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler('app.log')
# 设置级别
console_handler.setLevel(logging.WARNING)
file_handler.setLevel(logging.DEBUG)
# 创建 formatter
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(name)s: %(message)s')
# 设置 formatter
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 添加 handler
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 使用 logger
logger.debug('这是调试信息')
logger.info('这是信息')
logger.warning('这是警告')
logger.error('这是错误')
日志配置¶
通过字典配置¶
logging.config.dictConfig() 可以通过字典配置日志系统,一个典型的配置字典包括:
version: 配置版本,必须为 1disable_existing_loggers: 是否禁用已存在的日志器,默认为 Falseformatters: 格式化器配置handlers: 处理器配置loggers: 日志器配置
import logging
import logging.config
LOGGING_CONFIG = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
'detailed': {
'format': '%(asctime)s [%(levelname)s] %(name)s %(filename)s:%(lineno)d: %(message)s'
}
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'standard',
'stream': 'ext://sys.stdout'
},
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'formatter': 'detailed',
'filename': 'app.log',
'encoding': 'utf-8',
'mode': 'w'
}
},
'loggers': {
'': { # root logger
'handlers': ['console', 'file'],
'level': 'DEBUG',
'propagate': False
}
}
}
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)
logger.info('配置完成')
需要注意的是,ext:// 是一种外部引用语法,格式为 ext://<python_import_path>,解析时会通过 importlib 动态导入模块并获取属性。
通过文件配置¶
logging.config.fileConfig() 可以通过配置文件来设置日志系统,支持 INI 格式的配置文件。
例如,先创建一个名为 logging.conf 的配置文件,内容如下:
[loggers]
keys=root,my_app
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_my_app]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=my_app
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('app.log',)
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
然后使用配置文件:
import logging
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger('my_app')
logger.debug('这是调试信息')