apppublic/aidocs/app_logger.md
2025-10-05 11:23:33 +08:00

7.9 KiB
Raw Blame History

AppLogger 技术文档

概述

AppLogger 是一个基于 Python 标准库 logging 模块封装的日志工具模块,旨在简化日志系统的初始化与使用。它提供全局日志实例、便捷的函数式接口以及面向对象的日志类,支持控制台输出和文件输出,并可自定义日志级别与格式。


功能特性

  • 支持常见的日志级别:debug, info, warning, error, critical
  • 可选日志输出方式:控制台(默认)或文件
  • 全局单例模式管理日志器,避免重复创建
  • 提供函数式调用接口(如 info(), debug() 等)
  • 提供面向对象的 AppLogger 类,便于在项目中集成
  • 自定义日志格式和时间戳

依赖说明

外部依赖

import os
import sys
import logging
from functools import partial

内部依赖

from appPublic.timeUtils import timestampstr

注意:timestampstr 在当前代码中未被实际调用,可能是预留功能或冗余导入。


配置常量

日志级别映射表

levels = {
    "debug": logging.DEBUG,
    "info": logging.INFO,
    "warning": logging.WARNING,
    "error": logging.ERROR,  # 原始代码有误,应为 logging.ERROR 而非 logging.error
    "critical": logging.CRITICAL
}

将字符串级别的名称映射为 logging 模块对应的标准级别常量。

⚠️ Bug 提示:原始代码中 "error": logging.error 是错误的!logging.error 是一个方法,不是常量。正确应为 logging.ERROR


默认日志格式

defaultfmt = '%(asctime)s[%(name)s][%(levelname)s][%(filename)s:%(lineno)s]%(message)s'

格式说明:

占位符 含义
%(asctime)s 时间戳(自动格式化)
%(name)s Logger 名称
%(levelname)s 日志级别(如 INFO, DEBUG
%(filename)s 发出日志的源文件名
%(lineno)s 发出日志的行号
%(message)s 日志内容

示例输出:

2025-04-05 10:23:45,123[MyApp][INFO][main.py:42]Application started successfully.

全局变量

变量名 类型 初始值 说明
logfile str / None / int -1 记录日志文件路径;-1 表示尚未设置,None 表示输出到控制台
logger Logger or None None 全局 logger 实例
g_levelname str 'info' 当前日志级别名称(字符串)
level int logging.INFO 对应的日志级别数值

核心函数

create_logger(name, formater=defaultfmt, levelname=None, file=None)

创建并返回一个配置好的 Logger 实例。采用单例模式,确保多次调用只创建一次。

参数说明

参数 类型 必填 默认值 说明
name str 日志记录器名称,通常为模块或类名
formater str defaultfmt 日志输出格式字符串
levelname str None 指定日志级别(如 'debug', 'warning'),若不传则使用全局 g_levelname
file str or None None 日志输出文件路径。若为 None,则输出到控制台

返回值

  • logging.Logger:已配置的日志记录器实例

行为逻辑

  1. logfile == -1(首次调用),则设置 logfile = file
  2. logger 已存在,则直接返回,防止重复初始化
  3. 创建 Logger 实例
  4. 设置日志级别:
    • 若传入 levelname,更新全局 g_levelnamelevel
    • 否则使用当前全局级别
  5. 创建 Formatter 使用指定格式
  6. 创建处理器:
    • logfile 不为 None → 使用 FileHandler
    • 否则 → 使用 StreamHandler(标准输出)
  7. 为处理器设置格式并添加到 logger
  8. 返回 logger

支持热切换日志文件路径(仅限第一次)


函数式日志接口

提供顶层函数用于快速写日志,无需显式获取 logger。

函数 说明
info(*args, **kw) 输出 INFO 级别日志
debug(*args, **kw) 输出 DEBUG 级别日志
warning(*args, **kw) 输出 WARNING 级别日志
error(*args, **kw) 输出 ERROR 级别日志
critical(*args, **kw) 输出 CRITICAL 级别日志
exception(*args, **kw) 输出异常堆栈信息(等价于 logger.exception()

⚠️ Bug 提示:warning() 函数中参数拼错:*aegs 应为 *args

示例

from your_module import info, error

info("程序启动")
error("发生错误", exc_info=True)

注:所有函数内部检查 if logger is None,若未初始化则静默忽略。


类:AppLogger

面向对象风格的日志封装类,每个实例拥有独立但共享配置的 logger。

初始化

def __init__(self):
    self.logger = create_logger(self.__class__.__name__)
    self.debug = self.logger.debug
    self.info = self.logger.info
    self.warning = self.logger.warning
    self.error = self.logger.error
    self.critical = self.logger.critical
    self.exception = self.logger.exception

特性

  • 使用类名作为 logger 名称(例如 AppLogger 实例的日志名为 "AppLogger"
  • 将 logger 的方法绑定到自身属性,实现链式调用
  • 所有实例共用同一个底层 loggercreate_logger 是单例)

使用示例

class MyApp:
    def __init__(self):
        self.log = AppLogger()

    def run(self):
        self.log.info("应用正在运行")
        try:
            1 / 0
        except Exception as e:
            self.log.exception("捕获异常")

app = MyApp()
app.run()

输出示例:

2025-04-05 10:30:12,456[AppLogger][ERROR][myapp.py:15]捕获异常
Traceback (most recent call last):
  File "myapp.py", line 14, in run
    1 / 0
ZeroDivisionError: division by zero

已知问题Bug与改进建议

问题 描述 建议修复
levels["error"] 错误 使用了 logging.error 方法而非常量 logging.ERROR 改为 "error": logging.ERROR
warning() 函数参数拼写错误 *aegs 应为 *args 修正拼写
⚠️ exception() 参数错误 调用时写成 logger.exception(**args, **kw) 应为 logger.exception(*args, **kw),且通常只需 exc_info=True
⚠️ 全局状态耦合 多次调用 create_logger 无法更改 fileformat 可考虑增加重置机制或移除单例限制
💡 缺少关闭资源接口 未提供关闭 handler 的方法 建议添加 close_logger() 清理文件句柄

使用示例

示例 1基础使用控制台输出

from your_module import create_logger, info, debug

# 初始化 logger
create_logger("MyApp", levelname="debug")

# 使用函数接口
info("这是信息")
debug("这是调试消息")

示例 2输出到文件

from your_module import create_logger, error

create_logger("MyService", levelname="warning", file="logs/app.log")
error("发生严重错误!")

示例 3使用 AppLogger 类

from your_module import AppLogger

class DataProcessor:
    def __init__(self):
        self.log = AppLogger()
    
    def process(self):
        self.log.info("开始处理数据")
        self.log.warning("发现可疑数据点")

dp = DataProcessor()
dp.process()

总结

本模块通过封装 logging 模块,提供了简洁易用的日志接口,适用于中小型项目的快速开发。虽然存在少量 bug 和设计局限,但整体结构清晰,扩展性强。

建议在正式使用前修复已知问题,并根据需要增强配置灵活性(如支持多 handler、动态调整级别等


📌 版本建议v1.0.1(需修复 bug 后发布)
📅 最后更新2025年4月5日