作为一个Java程序员,我们使用过log4j,logback等一系列的日志打印框架,还有比较简单的@Slf4j,只需要一个annotation,就可以很简单的输出日志了,并且日志文件可以按天或者按大小进行滚动,那么在Python里面该如何做呢?其实Java里面的日志配置可以非常平滑的迁移到Python里面来。
配置文件的格式有非常多的形式,比如.ini格式,.yaml格式,.json格式,.yaml比较好理解,我们就拿这个格式来举例,文件内容如下所示:
version: 1
formatters:
simple:
format: '%(asctime)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
file:
class: logging.handlers.TimedRotatingFileHandler
filename: ./log/logging.log
when: D
interval: 1
backupCount: 5
level: DEBUG
formatter: simple
loggers:
bizLog:
level: DEBUG
handlers: [file]
propagate: no
root:
level: DEBUG
handlers: [console]
首先定义一个formatter,它决定了日志输出的格式,有很多的预置变量,下表个大家列出来了,可以根据自己的需要进行增减:
Attribute name | Format | Description |
---|---|---|
args | You shouldn’t need to format this yourself. | The tuple of arguments merged into? |
asctime |
| Human-readable time when the?LogRecord?was created. By default this is of the form ‘2003-07-08 16:49:45,896’ (the numbers after the comma are millisecond portion of the time). |
created |
| Time when the?LogRecord?was created (as returned by?time.time()). |
exc_info | You shouldn’t need to format this yourself. | Exception tuple (à la? |
filename |
| Filename portion of? |
funcName |
| Name of function containing the logging call. |
levelname |
| Text logging level for the message ( |
levelno |
| Numeric logging level for the message ( |
lineno |
| Source line number where the logging call was issued (if available). |
message |
| The logged message, computed as? |
module |
| Module (name portion of? |
msecs |
| Millisecond portion of the time when the?LogRecord?was created. |
msg | You shouldn’t need to format this yourself. | The format string passed in the original logging call. Merged with? |
name |
| Name of the logger used to log the call. |
pathname |
| Full pathname of the source file where the logging call was issued (if available). |
process |
| Process ID (if available). |
processName |
| Process name (if available). |
relativeCreated |
| Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded. |
stack_info | You shouldn’t need to format this yourself. | Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record. |
thread |
| Thread ID (if available). |
threadName |
| Thread name (if available). |
参考链接:logging — Logging facility for Python — Python 3.7.17 documentation
我们接收到日志输出的消息以后,该如何打印这些日志,是打印到控制台,还是打印到文件里面,就在这个模块里面进行定义,上面例子里面定义了两个handler,一个是打印到控制台的handler,一个是按时间滚动打印到文件里handler,一般情况下用这两个handler就够了。
参考链接:logging.handlers — Logging handlers — Python 3.7.17 documentation
最后我们需要定义的就是logger,它是我们在业务代码里面需要根据名称获取的logger,业务代码通过logger来打印具体的日志。
import logging.config
import yaml
with open('log.yaml', 'r') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
logger = logging.getLogger("bizLog")
logger.error('error message')
如果我们使用.yaml格式的配置文件,我们需要引入yaml包,然后进行配置。从测试代码里面我们看到我们根据配置的logger 名称获取到logger,然后就可以进行打印了。
1、filename: ./log/logging.log:需要我们手动创建/log目录,否则会报错