一、背景
需要对服务的日志信息按照INFO信息和ERROR信息进行日志输出,需要将不同级别的日志输出到不同的文件中,这样方便后续进行问题定位
二、基于python的logging.config.fileConfig配置日志
[loggers]
# 配置logger信息,必须包含一个名字叫做root的logger,当使用无参数 logging.getLogger()时,默认返回root这个logger,其它自定义logger可以通过logging.getLogger('fileLogger')方式进行调用
keys=root,fileLogger,rotatingFileLogger
[handlers]
# 定义handlers信息,常用的handlers包括StreamHandler(仅将日志输出到控制台)、FileHandler(将日志信息输出保存文件)、RotatingFileHandler(将日志输出保存到文件中,并设置单个日志文件的大小和日志文件个数)
keys=consoleHandler,fileHandler,rotatingFileHandler
[formatters]
# 设置日志格式
keys=simpleFormatter
[logger_root]
# 对loggers中声明的logger进行逐个配置
level=DEBUG
handlers=consoleHandler
[logger_fileLogger]
# 对handlers中声明的handler进行逐个配置
level=DEBUG
# 该logger中配置的handler
handlers=fileHandler
# logger 的名称
qualname=fileLogger
propagate=0
[logger_rotatingFileLogger]
level=DEBUG
# 这样配置,rotatingFileLogger中就同时配置了consoleHandler,rotatingFileHandler
# consoleHandler 负责将日志输出到控制台
# rotatingFileHandler 负责将日志输出保存到文件中
handlers=consoleHandler,rotatingFileHandler
qualname=rotatingFileLogger
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('logs/logging.log', 'a')
[handler_rotatingFileHandler]
class=handlers.RotatingFileHandler
level=WARNING
formatter=simpleFormatter
args=("logs/rotating_logging.log", "a", 1*1024*1024, 5)
[formatter_simpleFormatter]
format=%(asctime)s - %(module)s - %(thread)d - %(levelname)s : %(message)s
datefmt=%Y-%m-%d %H:%M:%S
代码示例
logging.config.fileConfig(“logging.conf”)
# 输出日志到控制台,获取的是root对应的logger
console_logger = logging.getLogger()
# 输出日志到单个文件
file_logger = logging.getLogger(name="fileLogger")
# rotatingFileLogger中的consoleHandler输出到控制台,rotatingHandler输出日志到文件
rotating_logger = logging.getLogger(name="rotatingFileLogger")
注意:使用这种方式配置日志,一定要在项目的入口函数中就调用 logging.config.fileConfig(“logging.conf”)函数,因为 logging.conf 文件中,在handler中配置的是日志文件的相对地址,如果在其他代码文件中进行调用,由于相对地址的原因,将导致日志文件会出现在意想不到的位置。
三、基于python代码将日志按照不同级别输出到不同文件中
info_logger = logging.getLogger()
error_logger = logging.getLogger()
info_logger.setLevel(logging.INFO)
error_logger.setLevel(logging.INFO)
handler_info = logging.FileHandler(filename='info.log')
handler_error = logging.FileHandler(filename='error.log')
handler_info.setLevel(logging.INFO)
handler_error.setLevel(logging.ERROR)
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler_info.setFormatter(formatter)
handler_error.setFormatter(formatter)
filter_info = logging.Filter()
filter_error = logging.Filter()
filter_info.filter = lambda record: record.levelno == logging.INFO
filter_error.filter = lambda record: record.levelno == logging.ERROR
handler_info.addFilter(filter_info)
handler_error.addFilter(filter_error)
info_logger.addHandler(handler_info)
error_logger.addHandler(handler_error)
基本的思路是 初始化logger,初始化handler,在handler里面设置level,设置formatter,增加过滤器filter,之后为初始化的logger设置增加这个handler
针对setLevel的优先级如下
logging.basicConfig < handler.setLevel < logger.setLevel
网友评论