log更新
This commit is contained in:
+66
-22
@@ -3,28 +3,72 @@
|
||||
### 程序框架
|
||||
```angular2html
|
||||
intelligence_system/
|
||||
├── config/ # 配置管理
|
||||
│ ├── __init__.py
|
||||
│ ├── settings.py # 全局参数
|
||||
│ └── logging.conf # 日志配置
|
||||
├── collectors/ # 数据采集
|
||||
│ ├── news_api.py
|
||||
│ └── complaint_spider.py
|
||||
├── processors/ # 数据处理
|
||||
│ ├── text_processor.py
|
||||
│ └── image_processor.py
|
||||
├── storage/ # 数据存储
|
||||
│ ├── database.py
|
||||
│ └── cache_manager.py
|
||||
├── applications/ # 应用层
|
||||
│ ├── reporter/
|
||||
│ │ ├── daily.py
|
||||
│ │ └── monthly.py
|
||||
│ └── alert.py
|
||||
├── utils/ # 工具类
|
||||
│ ├── logger.py
|
||||
│ └── network.py
|
||||
└── main.py # 调度入口
|
||||
├── config/ # 系统配置中心
|
||||
│ ├── __init__.py # 配置包初始化
|
||||
│ ├── settings.py # 主配置文件(数据库连接、API密钥等)
|
||||
│ └── scheduler_rules.yaml # 任务调度规则
|
||||
|
||||
├── data_collection/ # 数据采集层
|
||||
│ ├── spiders/ # 网络爬虫子系统
|
||||
│ │ ├── weibo_spider.py # 黑猫爬虫
|
||||
│ │
|
||||
│ ├── api_integration/ # API接口子系统
|
||||
│ │ ├── news_api.py # 新闻接口
|
||||
│ │
|
||||
│ └── internal/ # 内部数据收集
|
||||
│ ├── jian_dao_cloud.py # 简道云表单收集器
|
||||
|
||||
├── data_processing/ # 数据处理层
|
||||
│ ├── structured/ # 结构化数据处理
|
||||
│ │ ├── data_cleaner.py # 数据清洗(去重/标准化)
|
||||
│ │ └── schema_mapper.py # 数据结构转换器
|
||||
│ │
|
||||
│ ├── unstructured/ # 非结构化数据处理
|
||||
│ │ ├── text_parser.py # 文本解析(PDF/HTML等)
|
||||
│ │ ├── image_analyzer.py # 图像识别(OpenCV集成)
|
||||
│ │ └── video_processor.py # 音视频分离分析
|
||||
│ │
|
||||
│ └── ai_engine/ # AI分析核心
|
||||
│ ├── nlp_processor.py # 自然语言处理引擎
|
||||
│ ├── sentiment_analyzer.py # 情感分析模型
|
||||
│ └── topic_modeler.py # LDA主题建模工具
|
||||
|
||||
├── storage/ # 数据存储层
|
||||
│ ├── mysql_agent.py # MySQL读写管理器
|
||||
│ └── query_builder.py # SQL动态构建器
|
||||
|
||||
├── services/ # 应用服务层
|
||||
│ ├── monitoring/ # 舆情监控
|
||||
│ │ ├── opinion_monitor.py # 实时舆情追踪
|
||||
│ │ └── brand_reputation.py # 品牌口碑分析
|
||||
│ │
|
||||
│ ├── analysis/ # 竞品分析
|
||||
│ │ ├── competitor_tracker.py # 竞品动态监控
|
||||
│ │ └── swot_generator.py # SWOT分析报告
|
||||
│ │
|
||||
│ ├── reporting/ # 报告服务
|
||||
│ │ ├── daily_reporter.py # 自动化日报生成
|
||||
│ │ └── weekly_digest.py # 周报汇编系统
|
||||
│ │
|
||||
│ └── alert/ # 预警服务
|
||||
│ ├── alert_trigger.py # 动态阈值告警
|
||||
│ └── notification_center.py # 邮件/短信通知
|
||||
|
||||
├── system_management/ # 系统管理层
|
||||
│ ├── scheduler/ # 任务调度
|
||||
│ │ ├── task_scheduler.py # 分布式任务调度器
|
||||
│ │ └── cron_manager.py # 定时规则配置
|
||||
│ │
|
||||
│ └── monitor/ # 系统监控
|
||||
│ ├── health_monitor.py # 服务健康检测
|
||||
│ └── performance_watcher.py # 资源占用监控
|
||||
|
||||
├── utils/ # 工具库
|
||||
│ ├── file_handler.py # 通用文件操作
|
||||
│ ├── logger.py # 日志系统
|
||||
│ └── datetime_parser.py # 时间格式处理
|
||||
|
||||
└── main.py # 系统入口(启动所有服务)
|
||||
```
|
||||
### 程序设计原则
|
||||
1. 所有程序尽可能在py文件中运行,尽量避免使用命令行执行
|
||||
|
||||
+76
-107
@@ -1,129 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
跨平台日志工具模块
|
||||
功能:
|
||||
1. 自动适配不同操作系统的日志路径
|
||||
2. 支持中文等非ASCII字符
|
||||
3. 日志文件自动按日期分割
|
||||
4. 控制台与文件双输出
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from loguru import logger
|
||||
import platform
|
||||
from datetime import datetime
|
||||
import zipfile
|
||||
|
||||
class CrossPlatformLog:
|
||||
"""跨平台日志系统(支持Linux/Windows/Mac)"""
|
||||
|
||||
class CrossPlatformLogger:
|
||||
def __init__(self, name="intelligence_system"):
|
||||
"""
|
||||
初始化跨平台日志系统
|
||||
def __init__(self):
|
||||
self.log_dir = self._get_log_dir()
|
||||
self._setup_logger()
|
||||
|
||||
参数:
|
||||
name: 日志名称(用于创建日志文件夹)
|
||||
"""
|
||||
self.system = platform.system().lower()
|
||||
self.logger = logging.getLogger(name)
|
||||
self.logger.setLevel(logging.INFO)
|
||||
def _get_log_dir(self):
|
||||
"""获取跨平台日志目录(相对路径)"""
|
||||
base_dir = Path(__file__).parent.parent # 项目根目录
|
||||
log_dir = base_dir / "logs"
|
||||
|
||||
# 确保日志目录存在
|
||||
self.log_dir = self._get_log_dir(name)
|
||||
os.makedirs(self.log_dir, exist_ok=True)
|
||||
# 自动创建日志目录
|
||||
log_dir.mkdir(exist_ok=True)
|
||||
|
||||
# 配置日志格式
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
|
||||
# 控制台处理器
|
||||
self._setup_console_handler(formatter)
|
||||
|
||||
# 文件处理器(按天分割)
|
||||
self._setup_file_handler(formatter)
|
||||
|
||||
# 处理未捕获的异常
|
||||
sys.excepthook = self.handle_uncaught_exception
|
||||
|
||||
def _get_log_dir(self, name: str) -> str:
|
||||
"""获取适合当前平台的日志目录路径"""
|
||||
if self.system == 'windows':
|
||||
base_dir = os.path.join(os.environ['APPDATA'], name)
|
||||
elif self.system == 'darwin': # macOS
|
||||
base_dir = os.path.expanduser(f"~/Library/Logs/{name}")
|
||||
else: # Linux及其他Unix-like系统
|
||||
base_dir = f"/var/log/{name}" if os.access("/var/log", os.W_OK) \
|
||||
else os.path.expanduser(f"~/.local/share/{name}")
|
||||
|
||||
return base_dir
|
||||
|
||||
def _setup_console_handler(self, formatter: logging.Formatter):
|
||||
"""配置控制台输出(兼容不同终端的编码)"""
|
||||
console = logging.StreamHandler()
|
||||
|
||||
# Windows终端特殊处理
|
||||
if self.system == 'windows' and not sys.stdout.isatty():
|
||||
import colorama
|
||||
# Windows特殊权限处理
|
||||
if platform.system() == "Windows":
|
||||
try:
|
||||
colorama.init()
|
||||
except ImportError:
|
||||
os.chmod(log_dir, 0o777) # 确保写入权限
|
||||
except:
|
||||
pass
|
||||
|
||||
# 解决Windows控制台编码问题
|
||||
if sys.stdout.encoding != 'utf-8':
|
||||
import io
|
||||
sys.stdout = io.TextIOWrapper(
|
||||
sys.stdout.buffer,
|
||||
encoding='utf-8',
|
||||
errors='replace'
|
||||
)
|
||||
return log_dir
|
||||
|
||||
console.setFormatter(formatter)
|
||||
self.logger.addHandler(console)
|
||||
def _setup_logger(self):
|
||||
"""配置跨平台日志处理器"""
|
||||
logger.remove() # 清除默认配置
|
||||
|
||||
def _setup_file_handler(self, formatter: logging.Formatter):
|
||||
"""配置日志文件输出(UTF-8编码)"""
|
||||
log_file = os.path.join(
|
||||
self.log_dir,
|
||||
f"{datetime.now().strftime('%Y%m%d')}.log"
|
||||
# 统一控制台输出格式
|
||||
logger.add(
|
||||
sys.stdout,
|
||||
level="INFO",
|
||||
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{module}</cyan> - <level>{message}</level>",
|
||||
filter=lambda record: record["level"].no >= 20 # INFO及以上级别
|
||||
)
|
||||
|
||||
# 使用TimedRotatingFileHandler实现日志分割
|
||||
file_handler = TimedRotatingFileHandler(
|
||||
filename=log_file,
|
||||
when='midnight', # 每天午夜分割
|
||||
encoding='utf-8',
|
||||
backupCount=30 # 保留30天日志
|
||||
)
|
||||
file_handler.setFormatter(formatter)
|
||||
self.logger.addHandler(file_handler)
|
||||
# 主日志文件(兼容所有平台路径)
|
||||
self._add_main_log()
|
||||
|
||||
def handle_uncaught_exception(self, exc_type, exc_value, exc_traceback):
|
||||
"""全局异常捕获"""
|
||||
self.logger.error(
|
||||
"未捕获的异常:",
|
||||
exc_info=(exc_type, exc_value, exc_traceback)
|
||||
# 错误日志单独存储
|
||||
self._add_error_log()
|
||||
|
||||
def _add_main_log(self):
|
||||
"""主日志文件配置"""
|
||||
main_log = self.log_dir / "application.log"
|
||||
logger.add(
|
||||
str(main_log),
|
||||
rotation="20 MB",
|
||||
compression=self._compress_log,
|
||||
encoding="utf-8",
|
||||
level="DEBUG",
|
||||
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {module}:{line} - {message}",
|
||||
retention="30 days",
|
||||
enqueue=True # 线程安全
|
||||
)
|
||||
|
||||
def _add_error_log(self):
|
||||
"""错误日志专用配置"""
|
||||
error_log = self.log_dir / "errors.log"
|
||||
logger.add(
|
||||
str(error_log),
|
||||
level="ERROR",
|
||||
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | ERROR | {module}:{line} - {message}\n{exception}",
|
||||
rotation="10 MB",
|
||||
retention="90 days"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_logger(name: str = None) -> logging.Logger:
|
||||
"""获取配置好的日志实例"""
|
||||
return CrossPlatformLogger(name).logger
|
||||
def _compress_log(log_path):
|
||||
"""通用日志压缩方法(兼容所有平台)"""
|
||||
if not os.path.exists(log_path):
|
||||
return
|
||||
|
||||
try:
|
||||
zip_path = f"{log_path}.{datetime.now().strftime('%Y%m%d')}.zip"
|
||||
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
||||
zipf.write(log_path, arcname=os.path.basename(log_path))
|
||||
os.remove(log_path)
|
||||
return zip_path
|
||||
except Exception as e:
|
||||
print(f"日志压缩失败: {str(e)}")
|
||||
return log_path # 返回原文件路径继续使用
|
||||
|
||||
def setup_logging(name: str = "intelligence_system"):
|
||||
"""快速配置日志(兼容旧代码)"""
|
||||
return CrossPlatformLogger(name).logger
|
||||
@classmethod
|
||||
def get_logger(cls, module_name=None):
|
||||
"""获取模块专属日志器"""
|
||||
return logger.bind(module=module_name or "__main__")
|
||||
|
||||
|
||||
# 测试代码
|
||||
if __name__ == "__main__":
|
||||
logger = CrossPlatformLogger().logger
|
||||
logger.info("这是一条info日志(包含中文测试)")
|
||||
try:
|
||||
1 / 0
|
||||
except Exception as e:
|
||||
logger.error("除零错误示例", exc_info=True)
|
||||
# 初始化全局日志器
|
||||
log = CrossPlatformLog().get_logger()
|
||||
Reference in New Issue
Block a user