Python log日志

结构

下面列出了模块定义的基本类及其功能。

  • 记录器::公开应用程序代码直接使用的接口。
  • 处理程序: 将日志记录(由记录器创建)发送到适当的目的地。
  • 过滤器::提供了一种更细粒度的设施,用于确定要输出哪些日志记录。
  • 格式化程序: 指定最终输出中日志记录的布局。

日志级别

日志级别的数值如下表所示。如果您想定义自己的级别,并且需要它们具有相对于预定义级别的特定值,那么这些主要是有用的。如果您定义一个具有相同数值的级别,它会覆盖预定义的值;预定义的名称丢失。

等级 数值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

LogRecord

属性名称 格式 描述
参数 你不应该需要自己格式化。 合并成的参数元组msg产生message,或一个字典,其值用于合并(当只有一个参数时,它是一个字典)。
上升时间 %(asctime)s LogRecord创建时的人类可读时间 。默认情况下,它的格式为“2003-07-08 16:49:45,896”(逗号后面的数字是时间的毫秒部分)。
创建 %(created)f LogRecord创建 的时间(由 返回time.time())。
exc_info 你不应该需要自己格式化。 异常元组 (à la sys.exc_info) 或者,如果没有发生异常,则为None.
文件名 %(filename)s 的文件名部分pathname
函数名 %(funcName)s 包含日志调用的函数名称。
级别名称 %(levelname)s 消息的文本记录级别('DEBUG''INFO''WARNING'、 'ERROR''CRITICAL')。
水平诺 %(levelno)s 消息的数字日志记录级别 ( DEBUGINFOWARNINGERRORCRITICAL)。
线诺 %(lineno)d 发出日志记录调用的源行号(如果可用)。
模块 %(module)s 模块( 的名称部分filename)。
毫秒 %(msecs)d LogRecord创建时间的毫秒部分 。
信息 %(message)s 记录的消息,计算为。这是在调用时设置的 。msg % argsFormatter.format()
留言 你不应该需要自己格式化。 在原始日志记录调用中传递的格式字符串。与args产生message或任意对象合并(请参阅使用任意对象作为消息)。
名称 %(name)s 用于记录呼叫的记录器的名称。
路径名 %(pathname)s 发出日志记录调用的源文件的完整路径名(如果可用)。
过程 %(process)d 进程 ID(如果可用)。
进程名 %(processName)s 进程名称(如果可用)。
相对创建 %(relativeCreated)d 创建 LogRecord 的时间(以毫秒为单位),相对于加载日志记录模块的时间。
堆栈信息 你不应该需要自己格式化。 从当前线程中的堆栈底部到并包括导致创建此记录的日志记录调用的堆栈帧的堆栈帧信息(如果可用)。
线 %(thread)d 线程 ID(如果可用)。
线程名 %(threadName)s 线程名称(如果可用)。

在 3.1 版更改:添加了processName


基本应用

日志文件名可动态生成变更

# 生成动态日志
import logging.handlers
import logging


class GetLog:
    def __init__(self, log_abs_path):
        self.log_abs_path = log_abs_path
        self.logger = None

    def log(self, name, level):
        if self.logger is None:
            self.logger = logging.getLogger(name=name)
            self.logger.setLevel(logging.DEBUG)
            fm = "%(asctime)s:%(levelname)s:%(name)s:%(filename)s:%(lineno)d:%(message)s"
            fmt = logging.Formatter(fm)
            cl = logging.handlers.TimedRotatingFileHandler("{}".format(self.log_abs_path),
                                                           when="midnight",
                                                           interval=31,
                                                           encoding="utf8")
            cl.setLevel(level)
            cl.setFormatter(fmt)
            cl.suffix = "%Y-%m-%d"
            self.logger.addHandler(cl)
        return self.logger

    def debug(self):
        return self.log(name="debug", level="DEBUG")

    def info(self):
        return self.log(name="info", level="INFO")

    def warning(self):
        return self.log(name="warning", level="WARNING")

    def error(self):
        return self.log(name="error", level="ERROR")

    def critical(self):
        return self.log(name="critical", level="CRITICAL")

实例化

# 创建info级别的实例,单独的文件记录info日志
log_info = GetLog(log_path="./info.log").info()
log_info.info("info")

# 创建error级别的实例,单独的文件记录error日志
log_error = GetLog(log_path="./error.log").error()
log_error.error("error")


日志分等级输出

import logging
import os


class BaseLog:
    def __init__(self, level, is_file_handler=False, is_consol_handler=False, log_file_name="default.log"):
        """
        日志类,创建实例时,指定日志输出位置(默认不输出;is_file_handler:输出到指定文件,此时log_file_name必填;
        is_consol_handler:输出到控制台).
        建议创建多个实例,每个实例只记录一种级别的日志信息
        :param is_file_handler: 是否输出到指定文件
        :param is_consol_handler: 是否输出到控制台
        :param log_file_name: 生成的日志文件
        """
        current_dir = os.path.abspath(os.path.curdir)
        self.log_file_name = os.path.join(current_dir, log_file_name)
        self.is_file_handler = is_file_handler
        self.is_consol_handler = is_consol_handler
        # 创建记录器 ***注意有坑:不同name的Logger对象才可以创建不同的实例,名字一致时,会被覆盖***
        self.log = logging.getLogger(name=level)
        # 设置日志格式
        self.base_format = logging.Formatter(
            '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
        self.level = level
        self._add_filter_info(level=level)
        self.log.setLevel(level)

    def create(self):
        """
        返回可调用的log对象
        :return: log对象
        """
        self._add_filter_info(self.level)
        self.log.setLevel(self.level)
        return self.log

    def _add_file_handler(self, level):
        """
        添加处理器,根据等级输出日志到文件
        :param level: 记录的日志最低等级
        :return: 文件处理器
        """
        if self.is_file_handler:
            self.file_handler = logging.FileHandler(filename=self.log_file_name, mode="a", encoding="utf-8")
            self.file_handler.setLevel(level=level)
            self.file_handler.setFormatter(self.base_format)
            # 添加文件处理器
            self.log.addHandler(self.file_handler)
            return self.file_handler

    def _add_consol_handler(self, level):
        """
        添加控制台处理器, 根据日志等级输出到控制台
        :param level: 日志最低等级
        :return: 控制台处理器
        """
        if self.is_consol_handler:
            # 设置处理器--控制台输出
            self.console_handler = logging.StreamHandler()
            self.console_handler.setLevel(level=level)
            self.console_handler.setFormatter(self.base_format)
            # 添加控制台处理器
            self.log.addHandler(self.console_handler)
            return self.console_handler

    def _add_filter_info(self, level):
        """
        添加过滤器,根据日志等级添加过滤器
        :param level: 过滤的最低日志等级
        :return:
        """
        self.log_filter = logging.Filter()
        self.log_filter.filter(record=level)
        # 将过滤器添加到处理器
        if self.is_consol_handler:
            self._add_consol_handler(level=level).addFilter(self.log_filter)
        if self.is_file_handler:
            self._add_file_handler(level=level).addFilter(self.log_filter)


# 创建base_log实例 每个等级创建一个  
from base_log.base_log import BaseLog

debug_log = BaseLog(level="DEBUG", is_consol_handler=False, is_file_handler=True,
                    log_file_name="logs/debug.log").create()
info_log = BaseLog(level="INFO", is_consol_handler=False, is_file_handler=True,
                   log_file_name="logs/info.log").create()
warn_log = BaseLog(level="WARN", is_consol_handler=False, is_file_handler=True,
                   log_file_name="logs/warn.log").create()
error_log = BaseLog(level="ERROR", is_consol_handler=False, is_file_handler=True,
                    log_file_name="logs/error.log").create()
critical_log = BaseLog(level="CRITICAL", is_consol_handler=False, is_file_handler=True,
                       log_file_name="logs/critical.log").create()

debug_log.debug("debug--------")

info_log.info("info-----------")
info_log.error("info --error")

warn_log.warning("info-----------")
error_log.error("info-----------")
critical_log.critical("info-----------")

执行后文件输出

Python log日志_第1张图片

loguru 别人封装的log库

from loguru import logger
"""
git地址:https://github.com/emilk/loguru

"""

# 配置
logger.add("demo_log.log",  # log文件地址
           level="DEBUG",  # log记录最低级别
           rotation="00:00",  # 将日志记录以大小、时间等方式进行分割或划分
           retention="30 days", # 文件保留时间
           compression="zip",  # 文件压缩格式
           backtrace=True
           )
# logger.remove(handler_id=None)  # 禁用控制台日志输出

# 装饰器
@logger.catch
def demo_test_loguru(str):
    for i in range(str):
        # 直接使用
        logger.info(f"this is the {i} range")


if __name__ == "__main__":
    logger.debug("this is debug ")
    logger.info("this is info")
    logger.error("this is error message")
    demo_test_loguru("haha")
    note_loguru_2.note_2()

你可能感兴趣的:(JAVA,Python,Go,logging,python)