Vanna.ai 作为一个基于 RAG 的 SQL 生成框架,其日志系统设计相对简化且主要针对 Jupyter Notebook 环境进行优化。通过对源码的深入分析,我发现该项目采用了最小化日志设计,优先考虑交互式环境的用户体验而非传统的企业级日志管理。
在 src/vanna/base/base.py
的 VannaBase 抽象基类中,存在一个可重写的日志方法(第77-78行):
def log(self, message: str):
"""
可被子类重写的日志方法
默认使用 print 语句输出
"""
print(message)
设计特点分析:
message
参数,不支持日志级别区分print()
语句,无格式化或时间戳经过全面的源码结构分析,vanna.ai 项目中不存在项目级别的统一日志对象:
logging.py
、logger.py
等专门文件logger.debug()
、logger.warning()
等标准方法通过对各模块的代码分析,发现日志使用主要集中在以下场景:
1. SQL 提取成功通知
def _extract_sql(self, llm_response: str) -> str:
# SQL 提取逻辑
if sqls:
sql = sqls[-1]
self.log(f"Extracted SQL: {sql}") # 关键操作日志
return sql
2. 模型调用信息
# 在 OpenAI_Chat 模块中
print(f"Using model {model} for {num_tokens} tokens (approx)")
3. 错误信息输出
# 嵌入生成错误
print(f"Error generating embedding: {e}")
print()
而非标准 logging 模块基础配置结构:
class VannaBase(ABC):
def __init__(self, config=None):
if config is None:
config = {}
self.config = config
# 无日志相关配置参数
配置局限性:
log_level
参数尽管功能简化,vanna.ai 的架构具备良好的扩展性基础:
1. 策略模式支持
class CustomVanna(VannaBase):
def log(self, message: str):
# 自定义日志实现
import logging
logging.info(message)
2. 多重继承兼容
class MyVanna(ChromaDB_VectorStore, OpenAI_Chat):
def log(self, message: str):
# 统一的日志策略
self._custom_logger.info(message)
基于当前架构,为支持企业级日志管理,建议采用以下实现模式:
1. 基础日志增强
import logging
import os
from typing import Optional
class EnhancedVannaBase(VannaBase):
def __init__(self, config=None):
super().__init__(config)
self._setup_logging()
def _setup_logging(self):
"""设置增强的日志系统"""
log_config = self.config.get('logging', {})
# 日志级别配置
level = log_config.get('level', 'INFO')
# 日志格式配置
format_str = log_config.get(
'format',
'%(asctime)s [%(levelname)s] %(name)s: %(message)s'
)
# 输出配置
log_file = log_config.get('file_path')
# 创建logger
self.logger = logging.getLogger(f'vanna.{self.__class__.__name__}')
self.logger.setLevel(getattr(logging, level.upper()))
# 添加处理器
if log_file:
handler = logging.FileHandler(log_file)
else:
handler = logging.StreamHandler()
formatter = logging.Formatter(format_str)
handler.setFormatter(formatter)
self.logger.addHandler(handler)
def log(self, message: str, level: str = 'info'):
"""增强的日志方法"""
log_method = getattr(self.logger, level.lower(), self.logger.info)
log_method(message)
# 标准日志方法
def debug(self, message: str):
self.log(message, 'debug')
def info(self, message: str):
self.log(message, 'info')
def warning(self, message: str):
self.log(message, 'warning')
def error(self, message: str):
self.log(message, 'error')
2. 配置文件支持
# config.yaml
logging:
level: DEBUG
format: "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
file_path: "/var/log/vanna/app.log"
rotation:
max_size: "10MB"
backup_count: 5
3. 日志滚动策略实现
from logging.handlers import RotatingFileHandler
def _setup_file_handler(self, log_config):
"""设置带滚动的文件处理器"""
log_file = log_config.get('file_path')
rotation = log_config.get('rotation', {})
max_bytes = self._parse_size(rotation.get('max_size', '10MB'))
backup_count = rotation.get('backup_count', 5)
handler = RotatingFileHandler(
log_file,
maxBytes=max_bytes,
backupCount=backup_count
)
return handler
社区对日志系统改进存在强烈需求:
阶段1:兼容性增强
阶段2:功能完善
阶段3:企业级特性
对于基于 vanna 框架进行定制开发的项目,建议采用以下策略:
1. 重写基类日志方法
class ProductionVanna(ChromaDB_VectorStore, OpenAI_Chat):
def __init__(self, config=None):
super().__init__(config)
self.setup_production_logging()
def log(self, message: str):
self.logger.info(message)
def setup_production_logging(self):
# 实现企业级日志配置
pass
2. 环境变量配置
import os
LOG_LEVEL = os.getenv('VANNA_LOG_LEVEL', 'INFO')
LOG_FILE = os.getenv('VANNA_LOG_FILE', None)
1. 独立日志模块设计
vanna.logging
模块2. 配置驱动的日志系统
Vanna.ai 当前的日志系统体现了简化设计的理念,优先考虑 Jupyter 环境的用户体验。虽然缺乏企业级日志管理功能,但其良好的架构扩展性为自定义实现提供了坚实基础。
关键技术特征:
log()
方法可实现完全自定义的日志策略定制开发建议: 对于需要企业级日志功能的项目,建议通过继承和配置的方式实现增强的日志系统,在保持 vanna.ai 核心功能的同时,添加生产环境所需的日志管理能力。这种方式既能利用现有的架构优势,又能满足复杂的日志需求。