logging

logging库日志级别

级别 级别数值 使用时机
DEGUG 10 详细信息,常用于调试
INFO 20 程序正常运行过程中产生的一些信息
WARNING 30 警告用户,虽然程序还在正常工作,但有可能发生错误
ERROR 40 由于更严重的问题,程序已不能执行一些功能了
CRITICAL 50 严重错误,程序已不能继续运行

默认的日志级别事warning

import logging

# 默认的日志输出级别为warning
#使用baseConfig()来指定日志输出级别
logging.basicConfig(level=logging.DEBUG) # 控制台输出
# logging.basicConfig(filename="demo.log", level=logging.DEBUG) # 文件输出(文件追加模式)
# logging.basicConfig(filename="demo.log", filemode="w",level=logging.DEBUG) # 文件输出(清空写入)
logging.debug("This is debug log")
logging.info("This is info log")
logging.warning("This is warning log")
logging.error("This is error log")
logging.critical("This is critical log")
"""
日志输出格式
DEBUG: root : This is debug log
INFO:root: This is info log
WARNING: root: This is warning log
ERROR: root: This is error log
CRITICAL: root : This is critical log
"""
# 向日志输出变量
name = "张三"
age = 18
logging.debug("姓名 %s, 年龄 %d", "张三", 18)
logging.debug(f"姓名 {name}, 年龄 {age}", "张三", 18)

# 输出格式和添加一些公共信息
# 公告参数包括日志级别和计数器名字
logging.basicConfig(format="%(message)s",level=logging.DEBUG)
logging.basicConfig(format="%(asctime)s|%(message)s",level=logging.DEBUG) # 时间
logging.basicConfig(format="%(asctime)s|%(levelname)|%(message)s",level=logging.DEBUG) # 时间,级别
logging.basicConfig(format="%(asctime)s|%(levelname)s|%(line)s|%(message)s",level=logging.DEBUG) # 时间,级别,行数
logging.basicConfig(format="%(asctime)s|%(levelname)s|%(line)s|%(message)s",datefmt="%Y-%m-%d %H:%M:%S", level=logging.DEBUG) # 定义时间格式,级别,行数

logging的高级应用

logging模块采用了模块化设计,主要包含四种组件:

Loggers:记录器,提供应用程序代码能直接使用的接口;
Handlers:处理器,将记录器产生的日志发送至目的地;
Filters:过滤器,提供更好的粒度控制,决定哪些日志会被输出
Formatters:格式化器,设置日志内容的组成结构和消息字段。

loggers记录器

1.提供应用程序的调用接口
logger = logging.getLogger(__name__)
logger是单例的

2.决定日志记录的级别
logger.setLevel()

3.将日志内容传递到相关联的handlers
logger.addHandler()logger.removeHandler()

# 记录器
logger = logging.getLogger('applog')
logger.setLevel(logging.DEBUG)

Handlers处理器

它们将日志分发到不同的目的地。可以是文件、标准输出、
邮件、或者通过socke、http等协议发送到任何地方。

StreamHandler
标准输出stdout(如显示器)分发器。

创建方法:sh=logging.StreamHandler(stream=None)

FileHandler

将日志保存到磁盘文件的处理器。

创建方法:fh=logging.FileHandler(filename, mode='a',encoding=None,delay=False)

setFormatter():设置当前handler对象使用的消息格式。

# 处理器handler
consoleHandler = logging. StreamHandler()
consoleHandler.setLevel(logging. DEBUG)

#没有给handler指定日志级别,将使用logger的级别
fileHandler = logging. FileHandler(filename='addDemo. log')

Handlers处理器

  • StreamHandler
  • FileHandler
  • BaseRotatingHandler
  • RotatingFileHandler
  • TimedRotatingFileHandler
  • SocketHandler
  • DatagramHandler
  • SMTPHandler
  • SysLogHandler
  • NTEventLogHandler
  • HTTPHandler
  • WatchedFileHandler
  • QueueHandler
  • NullHandler

Formatters格式

Formatter对象用来最终设置日志信息的顺序、结构和内容。

其构造方法为
ft = logging.Formatter .init(fmt=None, datefmt=None, style=' %' )

# formatter格式
formatter = logging. Formatter("%(asctime)s|%(levelname)s|%(filename)s:%(lineno)s|%(message)s")

datefmt默认是%Y-%m-%d %H:%M:%S样式的
style参数默认为百分符%,这表示%()s格式的字符串

# 应用关联起来
 # 记录器
logger = logging.getLogger('applog')
logger.setLevel(logging.DEBUG) # 如果logger的级别低,handler事无法设置高级别的

# 处理器handler
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging. DEBUG)

#没有给handler指定日志级别,将使用logger的级别
fileHandler = logging.FileHandler(filename='addDemo. log')
fileHandler.setLevel(logging.INFO)

# formatter格式
formatter = logging.Formatter("%(asctime)s|%(levelname)8s|%(filename)s:%(lineno)s|%(message)s")

# 给处理器设置格式
consoleHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)

# 记录器要设置处理器
logger.addHandler(consoleHandler)
logger.addHandler(fileHandler)

# 定义一个过滤器
flt = logging.Filter("cn.cccb") # 判断是否logger名字以前缀

# 关联过滤器
# logger.addFilter(flt) # 全局logger设置过滤器
fileHandler.addFilter(flt) # 处理器设置过滤器

# 打印日志的代码
logger.debug("This is debug log1")
logger.info("This is info log")
logger.warning("This is warning log")
logger.error("This is error log")
logger.critical("This is critical log")

配置文件使用日志

[loggers]
keys=root,my_logger

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=INFO
handlers=consoleHandler

[logger_my_logger]
level=DEBUG
handlers=fileHandler
qualname=my_logger  # Logger的唯一标识符
propagate=0  # 禁止事件传递给父Logger

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

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('app.log', 'a')  # 文件路径和模式(追加)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
import logging.config

# 加载配置文件
logging.config.fileConfig('logging.ini')

# 获取Logger实例
logger = logging.getLogger('my_logger')

# 记录日志
logger.debug('Debug消息(写入文件)')
logger.info('Info消息(写入文件和控制台?)')  # 注意:my_logger的handler只有fileHandler,所以不会输出到控制台

使用字典配置日志

1、核心步骤:通过字典配置日志
(1) 定义配置字典


import logging.config

LOG_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,  # 不禁用已有的logger
    "formatters": {
        "simple": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
            "datefmt": "%Y-%m-%d %H:%M:%S"
        },
        "detailed": {
            "format": "[%(levelname)s] %(module)s.%(funcName)s (Line %(lineno)d): %(message)s"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "simple",
            "stream": "ext://sys.stdout"
        },
        "file": {
            "class": "logging.FileHandler",
            "level": "DEBUG",
            "formatter": "detailed",
            "filename": "app.log",
            "mode": "a"  # 追加模式
        }
    },
    "loggers": {
        "my_app": {
            "level": "DEBUG",
            "handlers": ["console", "file"],
            "propagate": False  # 不传播到根Logger
        }
    },
    "root": {  # 根Logger配置(处理其他未明确配置的Logger)
        "level": "WARNING",
        "handlers": ["console"]
    }
}

(2) 加载配置并测试

# 应用配置
logging.config.dictConfig(LOG_CONFIG)

# 获取Logger实例
logger = logging.getLogger("my_app")

# 记录日志
logger.debug("Debug消息(写入文件)")
logger.info("Info消息(控制台和文件)")
logger.warning("Warning消息(控制台和文件)")

2、配置字典详解

关键字段说明
version 必须为 1,表示使用新版配置格式
disable_existing_loggers 是否禁用已存在的Logger,通常设为 False
formatters 定义日志格式模板(支持多个)
handlers 定义日志处理器(如控制台、文件、邮件等)
loggers 定义具体Logger的配置(可指定多个)
root 根Logger的配置(处理未明确配置的Logger事件)

Handler 常用参数

  • class: 处理器类名(如 logging.FileHandler、logging.StreamHandler)

  • level: 处理器的最低日志级别(如 DEBUG、INFO)

  • formatter: 使用的格式器名称(对应 formatters 中的键)

  • filename: 文件路径(仅 FileHandler 需要)

  • stream: 输出流(如 ext://sys.stdout 表示控制台)

3、高级用法示例
动态生成日志文件名


import datetime

LOG_CONFIG["handlers"]["file"]["filename"] = f"app_{datetime.date.today()}.log"

添加 RotatingFileHandler(自动分割日志文件)


LOG_CONFIG["handlers"]["rotating_file"] = {
    "class": "logging.handlers.RotatingFileHandler",
    "level": "DEBUG",
    "formatter": "detailed",
    "filename": "app.log",
    "maxBytes": 1024 * 1024,  # 1MB
    "backupCount": 3  # 保留3个备份文件
}

# 将新Handler绑定到Logger
LOG_CONFIG["loggers"]["my_app"]["handlers"].append("rotating_file")

4、常见问题解决
Q1: 日志未输出到文件?

  • 检查 filename 路径是否有写入权限。

  • 确认 handlers 已正确绑定到目标 Logger。

Q2: 日志重复输出?

  • 检查 propagate 是否为 False,避免事件传播到父Logger。

Q3: 动态修改配置后不生效?

  • dictConfig 通常只调用一次,修改字典后需重新加载配置。

5、完整代码示例

import logging.config

# 定义配置字典
LOG_CONFIG = {
    "version": 1,
    "formatters": {
        "simple": {
            "format": "%(asctime)s - %(levelname)s - %(message)s",
            "datefmt": "%Y-%m-%d %H:%M:%S"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "simple"
        }
    },
    "root": {
        "level": "DEBUG",
        "handlers": ["console"]
    }
}

# 应用配置
logging.config.dictConfig(LOG_CONFIG)

# 使用根Logger记录日志
logging.info("这条消息会输出到控制台(INFO级别)")
logging.debug("这条消息不会输出(根Logger的Handler级别为INFO)")

通过字典配置 logging,您可以在代码中直接管理日志行为,无需依赖外部文件,非常适合需要动态调整日志策略的场景。

posted @ 2025-04-03 17:44  UPLY-AI  阅读(28)  评论(0)    收藏  举报