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
: 设置日志级别,默认是WARNING
format
: 设置日志输出格式,默认为%(levelname)s:%(name)s:%(message)s
%(name)s
Logger 名称%(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
月份缩写/全称%p
AM/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
: 按大小轮转日志文件,当日志文件达到指定大小时,自动创建新文件并归档旧日志filename
mode
encoding
: 同FileHandler
maxBytes
: 单个文件的最大字节数,默认为 0backupCount
: 保留的备份文件数量,默认为 0
logging.handlers.TimedRotatingFileHandler
: 按时间轮转日志文件filename
mode
encoding
backupCount
: 同RotatingFileHandler
when
: 轮转时间单位,支持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('这是调试信息')