Python Logging 模块

1. Logging 模块介绍

使用标准库模块提供的日志记录 API 的主要好处是所有 Python 模块都可以参与日志记录,因此您的应用程序日志可以包含您自己的消息与来自第三方模块的消息集成。The key benefit of having the logging API provided by a standard library module is that all Python modules can participate in logging, so your application log can include your own messages integrated with messages from third-party modules.

下面列出了该模块定义的基本类及其功能。The basic classes defined by the module, together with their functions, are listed below.

  • 记录器公开应用程序代码直接使用的接口。Loggers expose the interface that application code directly uses.
  • 处理器将日志记录(由记录器创建)发送到适当的目的地。 send the log records (created by loggers) to the appropriate destination.
  • 过滤器提供了更细粒度的工具来确定要输出哪些日志记录。Filters provide a finer grained facility for determining which log records to output.
  • 格式器指定最终输出中日志记录的布局。Formatters specify the layout of log records in the final output.

2. 日志级别 Logging Levels

LevelNumeric valueDescribe
CRITICAL50当发生严重错误,导致应用程序不能继续运行时记录的信息
ERROR40由于一个更严重的问题导致某些功能不能正常运行时记录的信息
WARNING30当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的
INFO20信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作
DEBUG10最详细的日志信息,典型应用场景是 问题诊断

logging 默认的日志级别为 warning

程序

import logging

logging.debug("debug_msg")
logging.info("info_msg")
logging.warning("warning_msg")
logging.error("error_msg")
logging.critical("critical_msg")

输出

WARNING:root:warning_msg
ERROR:root:error_msg
CRITICAL:root:critical_msg

3. 配置方式

a. basicConfig (不推荐)

logging.basicConfig(**kwargs)

Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger. The functions debug(), info(), warning(), error() and critical() will call basicConfig() automatically if no handlers are defined for the root logger.

如果root logger已经配置了handlers,则此函数不执行任何操作,除非关键字参数force设置为TrueThis function does nothing if the root logger already has handlers configured, unless the keyword argument force is set to True.

FormatDescription
filename使用指定的文件名创建创建FileHandler(默认使用StreamHandler)。 Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler.
filemode如果指定了filename,则以这种filemode打开文件(默认为'a')。 If filename is specified, open the file in this mode. Defaults to 'a'.
formathandler指定的格式字符串。 Use the specified format string for the handler. Defaults to attributes levelname, name and message separated by colons.
datefmt指定日期/时间格式。 Use the specified date/time format, as accepted by time.strftime().
level指定日志级别。 Set the root logger level to the specified level.
stream使用指定的stream来初始化 StreamHandler Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with filename - if both are present, a ValueError is raised.
handlers指定handlerIf specified, this should be an iterable of already created handlers to add to the root logger. Any handlers which don’t already have a formatter set will be assigned the default formatter created in this function. Note that this argument is incompatible with filename or stream - if both are present, a ValueError is raised.
force如果将此关键字参数指定为 true,则在执行其他参数指定的配置之前,将删除并关闭任何附加到根记录器的现有handlerIf this keyword argument is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments.

其中,format 包含以下常用属性:

FormatDescription
%(asctime)sHuman-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).
%(filename)sFilename portion of pathname.
%(levelname)sText logging level for the message ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
%(lineno)dSource line number where the logging call was issued (if available).
%(message)sThe logged message, computed as msg % args. This is set when Formatter.format() is invoked.
%(name)sName of the logger used to log the call.
%(pathname)sFull pathname of the source file where the logging call was issued (if available).
示例 1 (format的使用)

程序

import logging

logging.basicConfig(format="%(asctime)s | %(levelname)-8s | %(filename)8s:%(lineno)-3s | %(message)s",
                    level=logging.DEBUG)
logging.debug("debug_msg")
logging.info("info_msg")
logging.warning("warning_msg")
logging.error("error_msg")
logging.critical("critical_msg")

输出

2022-06-01 09:53:38,618 | DEBUG    |  main.py:5   | debug_msg
2022-06-01 09:53:38,619 | INFO     |  main.py:6   | info_msg
2022-06-01 09:53:38,619 | WARNING  |  main.py:7   | warning_msg
2022-06-01 09:53:38,619 | ERROR    |  main.py:8   | error_msg
2022-06-01 09:53:38,619 | CRITICAL |  main.py:9   | critical_msg
示例 2 (datefmt的使用)

程序

import logging

logging.basicConfig(format="%(asctime)s | %(levelname)-8s | %(filename)8s:%(lineno)-3s | %(message)s",
                    datefmt="%Y-%m-%d %H:%M:%S",
                    level=logging.DEBUG)
logging.debug("debug_msg")
logging.info("info_msg")
logging.warning("warning_msg")
logging.error("error_msg")
logging.critical("critical_msg")

输出

2022-06-01 09:55:55 | DEBUG    |  main.py:6   | debug_msg
2022-06-01 09:55:55 | INFO     |  main.py:7   | info_msg
2022-06-01 09:55:55 | WARNING  |  main.py:8   | warning_msg
2022-06-01 09:55:55 | ERROR    |  main.py:9   | error_msg
2022-06-01 09:55:55 | CRITICAL |  main.py:10  | critical_msg
b. 代码配置(不推荐)
组件名称对应类名功能描述
日志器Logger公开应用程序代码直接使用的接口Loggers expose the interface that application code directly uses.
处理器Handler将日志记录(由记录器创建)发送到适当的目的地。 send the log records (created by loggers) to the appropriate destination.
过滤器Filter提供了更细粒度的工具来确定要输出哪些日志记录。Filters provide a finer grained facility for determining which log records to output.
格式器Formatter指定最终输出中日志记录的布局Formatters specify the layout of log records in the final output.

Logger常用的配置方法:

方法描述
Logger.setLevel()设置日志器将会处理的日志消息的最低日志级别
Logger.addHandler()为该logger对象添加一个handler对象
Logger.addFilter()为该logger对象添加一个filter对象

相较于BasicConfiglogging.getLogger可以更灵活的进行配置。Although there is a default logger, we usually want to make and use other loggers that can be configured separately. This is because we may want a different severity level or format for different loggers. A new logger can be created with:

logger = logging.getLogger("logger_name")

logger具有parentchild的特性。Internally, the loggers are organized in a hierarchy. A logger created with:

logger = logging.getLogger("parent.child")

will be a child logger created under the logger with the name “parent,” which, in turn, is under the root logger. Using a dot in the string signifies that the child logger is a child of the parent logger. In the above case, a logger with the name “parent.child” is created as well as one with the name "parent" implicitly.

在创建子记录器时,子记录器具有父记录器的所有属性,直到重新配置为止。Upon creation, a child logger has all the properties of its parent logger until reconfigured. We can demonstrate this with the following example:

示例 1

程序

import logging

# Create `parent.child` logger
logger = logging.getLogger("parent.child")

# Emit a log message of level INFO, by default this is not print to the screen
logger.info("this is info level")
logger.warning("this is warning level")

# Create `parent` logger
parentlogger = logging.getLogger("parent")

# Set parent's level to INFO and assign a new handler
handler = logging.StreamHandler()
formatter = logging.Formatter("%(asctime)s : %(name)s : %(levelname)s : %(message)s")
handler.setFormatter(formatter)
parentlogger.setLevel(logging.INFO)
parentlogger.addHandler(handler)

# Let child logger emit a log message again
logger.info("this is info level again")

输出

this is warning level
2022-06-01 10:16:16,937 : parent.child : INFO : this is info level again
c. fileConfig(推荐)

配置文件

[loggers]
keys=root,mylog

[handlers]
keys=fileHandler, consoleHandler, smtpHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_mylog]
level=DEBUG
handlers=fileHandler, consoleHandler, smtpHandler
qualname=mylog
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('python.log', 'w')

[handler_smtpHandler]
class=handlers.SMTPHandler
level=DEBUG
formatter=simpleFormatter
args=(("smtp.163.com", 25), "166******23@163.com", ["56****87@qq.com", "87*****21@qq.com"], 'Logger Subject', ("166******23@163.com", "NOMFDG*****Y"))
kwargs={'timeout': 10.0}

[formatter_simpleFormatter]
format=%(asctime)s | %(levelname)8s | %(filename)10s:%(lineno)-3d | %(message)s
import logging
import logging.config

logging.config.fileConfig('log_config.conf')
logger = logging.getLogger('mylog')
d. dictConfig(推荐)

暂时没有总结,灵活性比fileConfig更高。

# !/usr/bin/env python
# -*- coding:utf-8 -*-


'''
@CreateTime : 2020/12/29 14:08
@Author : shouke
@Shource : https://cloud.tencent.com/developer/article/1772559
'''

import logging
import logging.config

LOGGING_CONFIG = {
    "version": 1,
    "formatters": {
        "default": {
            'format': '%(asctime)s %(filename)s %(lineno)s %(levelname)s %(message)s',
        },
        "plain": {
            "format": "%(message)s",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "default",
        },
        "console_plain": {
            "class": "logging.StreamHandler",
            "level": logging.INFO,
            "formatter": "plain"
        },
        "file": {
            "class": "logging.FileHandler",
            "level": 20,
            "filename": "./log.txt",
            "formatter": "default",
        }
    },
    "loggers": {
        "console_logger": {
            "handlers": ["console"],
            "level": "INFO",
            "propagate": False,
        },
        "console_plain_logger": {
            "handlers": ["console_plain"],
            "level": "DEBUG",
            "propagate": False,
        },
        "file_logger": {
            "handlers": ["file"],
            "level": "INFO",
            "propagate": False,
        }
    },
    "disable_existing_loggers": True,
}

# 运行测试
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("console_logger")
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

参考资料:

[1] https://docs.python.org/3/library/logging.html

[2] https://machinelearningmastery.com/logging-in-python/

[3] https://www.cnblogs.com/yyds/p/6901864.html

[4] https://www.cnblogs.com/kangshuaibo/p/14700833.html

[5] https://www.bilibili.com/video/BV1sK4y1x7e1

[6] https://docs.python.org/3/library/logging.config.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值