使用配置文件管理Python项目日志
使用配置文件管理Python项目日志
logging
记录日志
使用 logging
模块能够灵活的进行日志的管理,如下是一个简单的日志示例:
# myapp.py
import logging
logger = logging.getLogger(__name__)
def main():
logging.basicConfig(filename='myapp.log', level=logging.INFO)
logger.info('Started')
logger.info('Finished')
if __name__ == '__main__':
main()
使用后,能够在日志文件 myapp.log
中看到如下内容:
INFO:__main__:Started
INFO:__main__:Finished
如果项目中 Python
文件较少,能够使用如上的方式进行日志管理,如果遇到项目中 Python
文件较多的场景,每个 Python
文件中单独指定日志文件,就很繁琐了,一旦遇到日志目录更改的情况,就需要修改使用 logging
模块的每个 Python
文件,不但工作复杂而且容器出错,这里记录一种 logging
模块使用配置文件管理日志的方式,也即日志的配置单独在一个文件中,而非每个文件单独指定。
logging
使用配置配置
logging
使用配置文件管理日志的核心是 logging.config.fileConfig
,也即加载文件配置到日志模块,这里建议直接使用 log.conf
作为日志配置的文件名称,一个基础的日志配置文件示例如下:
[loggers]
keys=root
[logger_root]
# 日志级别:DEBUG、INFO、WARNING、ERROR、CRITICAL
level=DEBUG
# 处理器
handlers=consoleHandler,fileHandler
[logger_api]
level=ERROR
handlers=apiHandler
# 如果不是logger_root,这里一定要指定
qualname=api
[handlers]
keys=consoleHandler,fileHandler,apiHandler
[handler_consoleHandler]
# 处理类:StreamHandler(控制台)、FileHandler(文件)、NullHandler(无)
class=StreamHandler
level=DEBUG
formatter=default
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=default
# 日志文件,写入的模式(追加),
args=('%LOG_DIR%/error.log', 'a')
[handler_apiHandler]
class=FileHandler
level=DEBUG
formatter=default
args=('%LOG_DIR%/api.log', 'a')
[formatters]
keys=default,error
[formatter_default]
# 日志输出的格式
format=%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s
[formatter_error]
format=%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s
如上配置文件中,有三个重要的概念:
loggers
:定义了所有的日志器列表。logger_*
:定义日志器的配置,指定日志的级别和处理器。
handlers
:定义了日志对应的处理器的列表。handler_*
:将日志输出到控制台或者文件,处理器都有对应的登记和格式。
formatters
:定义了日志的格式的列表。formatter_*
:指定日志的输出样式的详细定义。
在 Flask
项目运行前,进行日志的配置,启动 Flask
项目前调用 setup_log
,如下所示:
import os
import logging.config
import configparser
def setup_log():
"""
日志预处理:
1.日志配置中环境变量的替换。
"""
log_config_path = os.path.join(os.environ.get('PROJECT_ROOT'), 'conf', 'log.conf')
# 读取日志配置文件内容
with open(log_config_path, 'r', encoding='utf-8') as file:
log_config_content = file.read()
# 替换配置文件中的占位符 %LOG_DIR% 为环境变量 LOG_DIR 的值
log_config_content = log_config_content.replace('%LOG_DIR%', os.environ.get('LOG_DIR'))
# 将替换后的配置写入一个临时文件
temp_log_config_path = os.path.join(os.environ.get('PROJECT_ROOT'), 'conf', 'tmp.conf')
with open(temp_log_config_path, 'w', encoding='utf-8') as temp_file:
temp_file.write(log_config_content)
# 加载临时文件中的日志配置
logging.config.fileConfig(temp_log_config_path)
# 删除临时的日志文件
os.remove(temp_log_config_path)
在需要记录日志的 Python
代码中,按照如下方式引用:
import logging
# 使用root日志处理器
LOG = logging.getLogger('root')
@api_bp.route('/execute', methods=['POST'])
def execute():
# 日志打印
LOG.exception("sql request")
# ...
进行请求后,能够在 root
日志处理器对应的日志文件 error.log
中查看到 sql request
的 ERROR
级别的日志打印,如下所示:
日志文件和控制台均出现对应的日志打印。