python logging
Posted 风流 少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python logging相关的知识,希望对你有一定的参考价值。
一:日志级别
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
二:日志格式化
https://docs.python.org/3/library/logging.html#logrecord-attributes
Attribute name | Format | Description |
---|---|---|
args | You shouldn’t need to format this yourself. | The tuple of arguments merged into msg to produce message , or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary). |
asctime | %(asctime)s | 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 | %(created)f | Time when the LogRecord was created (as returned by time.time() ). |
exc_info | You shouldn’t need to format this yourself. | Exception tuple (à la sys.exc_info ) or, if no exception has occurred, None . |
filename | %(filename)s | Filename portion of pathname . |
funcName | %(funcName)s | Name of function containing the logging call. |
levelname | %(levelname)s | Text logging level for the message (DEBUG , INFO , WARNING , ERROR , CRITICAL ). |
levelno | %(levelno)s | Numeric logging level for the message (DEBUG , INFO , WARNING , ERROR , CRITICAL ). |
lineno | %(lineno)d | Source line number where the logging call was issued (if available). |
message | %(message)s | The logged message, computed as msg % args . This is set when Formatter.format() is invoked. |
module | %(module)s | Module (name portion of filename ). |
msecs | %(msecs)d | 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 args to produce message , or an arbitrary object (see Using arbitrary objects as messages). |
name | %(name)s | Name of the logger used to log the call. |
pathname | %(pathname)s | Full pathname of the source file where the logging call was issued (if available). |
process | %(process)d | Process ID (if available). |
processName | %(processName)s | Process name (if available). |
relativeCreated | %(relativeCreated)d | 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)d | Thread ID (if available). |
threadName | %(threadName)s | Thread name (if available). |
三:使用
3.1 编码方式(个人推荐使用这种)
封装一个日志类。
import os
import sys
import logging
from logging.handlers import RotatingFileHandler
import datetime
current_path = os.path.dirname(__file__)
log_path = os.path.join(current_path, f'../logs/app-datetime.date.today().log')
class LogUtils:
def __init__(self):
self.log_path = log_path
self.logger = logging.getLogger(__name__)
self.logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(
fmt='%(asctime)s %(levelname)s %(thread)d --- [%(threadName)s] %(filename)s %(funcName)s:%(lineno)d:%(message)s')
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
# 单个文件最大3k,最多保存3份文件(除了当前写入的文件外),实际情况这个值要设的很大sys.maxsize,防止覆盖 超过则循环式覆盖
rotating_file_handler = RotatingFileHandler(log_path, maxBytes=1024 * 3, backupCount=3, encoding='utf-8')
rotating_file_handler.setFormatter(formatter)
file_handler = logging.FileHandler(log_path, encoding='utf-8')
file_handler.setFormatter(formatter)
self.logger.addHandler(console_handler)
# self.logger.addHandler(file_handler)
self.logger.addHandler(rotating_file_handler)
def get_logger(self):
return self.logger
logger = LogUtils().get_logger()
日志测试
from common.log_utils import logger
if __name__ == '__main__':
for i in range(40):
logger.info(f" i info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试info测试.")
注意:这里和我的认知不太一样,这里先从最后一个日志文件开始写,即先从2号开始写,然后是1号,最后是没有标号的文件。
3.2 配置文件方式 fileConfig
logging.conf
[loggers]
# 配置logger信息。必须包含一个名字叫做root的logger,当使用无参函数logging.getLogger()时,默认返回root这个logger,
# 其他自定义logger可以通过 logging.getLogger("fileAndConsole") 方式进行调用
keys=root,fileAndConsole
[handlers]
# 定义声明handlers信息。
keys=fileHandler,consoleHandler
[formatters]
# 设置日志格式
keys=simpleFormatter
[logger_root]
# 对loggers中声明的logger进行逐个配置,且要一一对应,在所有的logger中,必须制定level和handlers这两个选项,
# 对于非roothandler,还需要添加一些额外的option,其中qualname表示它在logger层级中的名字,在应用代码中通过这个名字制定所使用的handler,
# 即 logging.getLogger("fileAndConsole"),handlers可以指定多个,中间用逗号隔开,比如handlers=fileHandler,consoleHandler,同时制定使用控制台和文件输出日志
level=DEBUG
handlers=consoleHandler,fileHandler
[logger_fileAndConsole]
level=DEBUG
handlers=fileHandler,consoleHandler
qualname=fileAndConsole
propagate=0
[handler_consoleHandler]
# 在handler中,必须指定class和args这两个option,常用的class包括
# StreamHandler(仅将日志输出到控制台)、FileHandler(将日志信息输出保存到文件)、
# RotaRotatingFileHandler(将日志输出保存到文件中,并设置单个日志wenj文件的大小和日志文件个数),
# args表示传递给class所指定的handler类初始化方法参数,它必须是一个元组(tuple)的形式,即便只有一个参数值也需要是一个元组的形式;
# 里面指定输出路径,比如输出的文件名称等。level与logger中的level一样,而formatter指定的是该处理器所使用的格式器,
# 这里指定的格式器名称必须出现在formatters这个section中,且在配置文件中必须要有这个formatter的section定义;
# 如果不指定formatter则该handler将会以消息本身作为日志消息进行记录,而不添加额外的时间、日志器名称等信息;
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter
[handler_fileHandler]
class=FileHandler
args=('test.log', 'a')
level=DEBUG
formatter=simpleFormatter
[formatter_simpleFormatter]
format=%(asctime)s %(levelname)s %(thread)d --- [%(threadName)s] %(filename)s %(funcName)s:%(lineno)d:%(message)s
datefmt=%Y-%m-%d %H:%M:%S
import logging.config
logging.config.fileConfig('./config/logging.conf')
logger = logging.getLogger()
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
3.3 配置字典方式 dictConfig
LOGGING_CONFIG =
"version": 1,
"formatters":
"default":
'format': '%(asctime)s %(levelname)s %(thread)d --- [%(threadName)s] %(filename)s %(funcName)s:%(lineno)d:%(message)s',
,
"handlers":
"console":
"class": "logging.StreamHandler",
"level": logging.DEBUG,
"formatter": "default"
,
"file":
"class": "logging.FileHandler",
"level": logging.DEBUG,
"filename": "./log.txt",
"formatter": "default",
,
"root":
"handlers": ["console", "file"],
"level": "DEBUG"
,
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger()
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
以上是关于python logging的主要内容,如果未能解决你的问题,请参考以下文章