Logging in python 最速配置
Moevis
在这之前我还是用 print 更多一点,但是现在意识到,print 无法方便修改日志等级,也无法方便打印具体的模块与函数,所以打算以后都用 logging 来。
logging 本身是 python 内置的一个库,用起来也很方便。现在备份一点最小的可运行的配置 setup_logging.py
:
import json
import logging.config
import os
def setup_logging(
default_path='logging.json',
default_level=logging.INFO,
env_key='LOG_CFG'
):
"""Setup logging configuration
"""
path = default_path
value = os.getenv(env_key, None)
if value:
path = value
if os.path.exists(path):
with open(path, 'rt') as f:
config = json.load(f)
logging.config.dictConfig(config)
else:
logging.basicConfig(level=default_level)
这里包含的 setup_logging
函数所做的工作就是读取本地的 logging.json
日志配置文件,然后设置输出。
配置文件如下 logging.json
:
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"simple": {
"format": "%(asctime)s, %(levelname)-6s [%(filename)s:%(lineno)d] %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "simple",
"stream": "ext://sys.stdout"
},
"info_file_handler": {
"class": "logging.handlers.RotatingFileHandler",
"level": "INFO",
"formatter": "simple",
"filename": "info.log",
"maxBytes": 10485760,
"backupCount": 20,
"encoding": "utf8"
},
"error_file_handler": {
"class": "logging.handlers.RotatingFileHandler",
"level": "ERROR",
"formatter": "simple",
"filename": "errors.log",
"maxBytes": 10485760,
"backupCount": 20,
"encoding": "utf8"
}
},
"loggers": {
"my_module": {
"level": "ERROR",
"handlers": ["console"],
"propagate": "no"
}
},
"root": {
"level": "INFO",
"handlers": ["console", "info_file_handler", "error_file_handler"]
}
}
在运行时可以这样来:
$ LOG_CFG=logging.json python my_server.py
如果你喜欢 yaml 配置版本,那么可以用这个:
import os
import logging.config
import yaml
def setup_logging(
default_path='logging.yaml',
default_level=logging.INFO,
env_key='LOG_CFG'
):
"""Setup logging configuration
"""
path = default_path
value = os.getenv(env_key, None)
if value:
path = value
if os.path.exists(path):
with open(path, 'rt') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
else:
logging.basicConfig(level=default_level)
以及 yaml 版本的配置文件 logging.yaml
:
version: 1
disable_existing_loggers: False
formatters:
simple:
format: "%(asctime)s, %(levelname)-6s [%(filename)s:%(lineno)d] %(message)s"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: simple
filename: info.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
error_file_handler:
class: logging.handlers.RotatingFileHandler
level: ERROR
formatter: simple
filename: errors.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
loggers:
my_module:
level: ERROR
handlers: [console]
propagate: no
root:
level: INFO
handlers: [console, info_file_handler, error_file_handler]
不过 yaml 由于不是 python 默认自带的库,需要你自己手动装一下。
还有在使用 logging 的时候有个小技巧,通过调用 logger.exception(msg)
时还会把当前抛出的错误的调用栈打印出来,当然也可以用 logger.error(msg, exc_info=True)
来打印。
参考:https://logmatic.io/blog/python-logging-with-json-steroids/