新增RAG日志与事件接口,权限页面移除删除按钮
This commit is contained in:
parent
ca07f08e67
commit
b08a3a2ee2
|
|
@ -5,15 +5,46 @@ RAG 知识库服务 - Flask API
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import logging
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
from flask import Flask, request, jsonify
|
from flask import Flask, request, jsonify
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
from config import HOST, PORT, KNOWLEDGE_DIR, BASE_DIR
|
from config import HOST, PORT, KNOWLEDGE_DIR, BASE_DIR
|
||||||
from knowledge_service import knowledge_service
|
from knowledge_service import knowledge_service
|
||||||
from file_watcher import FileWatcher
|
from file_watcher import FileWatcher
|
||||||
|
from event_store import get_events, record_event
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
CORS(app) # 允许跨域请求
|
CORS(app) # 允许跨域请求
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_logging():
|
||||||
|
log_dir = os.path.join(BASE_DIR, "logs")
|
||||||
|
os.makedirs(log_dir, exist_ok=True)
|
||||||
|
log_path = os.path.join(log_dir, "rag-python.log")
|
||||||
|
|
||||||
|
root = logging.getLogger()
|
||||||
|
if root.handlers:
|
||||||
|
return
|
||||||
|
|
||||||
|
root.setLevel(logging.INFO)
|
||||||
|
file_handler = RotatingFileHandler(
|
||||||
|
log_path,
|
||||||
|
maxBytes=10 * 1024 * 1024,
|
||||||
|
backupCount=10,
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
formatter = logging.Formatter(
|
||||||
|
fmt="%(asctime)s [%(levelname)s] %(name)s - %(message)s",
|
||||||
|
datefmt="%Y-%m-%d %H:%M:%S",
|
||||||
|
)
|
||||||
|
file_handler.setFormatter(formatter)
|
||||||
|
root.addHandler(file_handler)
|
||||||
|
|
||||||
|
|
||||||
|
_setup_logging()
|
||||||
|
log = logging.getLogger("rag.app")
|
||||||
|
|
||||||
# 文件监控器
|
# 文件监控器
|
||||||
file_watcher = None
|
file_watcher = None
|
||||||
|
|
||||||
|
|
@ -27,6 +58,18 @@ def health_check():
|
||||||
'base_dir': BASE_DIR
|
'base_dir': BASE_DIR
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/events', methods=['GET'])
|
||||||
|
def list_events():
|
||||||
|
"""返回最近的索引事件(用于隐藏窗口时查看索引更新情况)"""
|
||||||
|
try:
|
||||||
|
limit = request.args.get('limit', default=None, type=int)
|
||||||
|
events = get_events(limit=limit, newest_first=True)
|
||||||
|
return jsonify({'success': True, 'data': events})
|
||||||
|
except Exception as e:
|
||||||
|
log.exception("Failed to list events")
|
||||||
|
return jsonify({'success': False, 'error': str(e)}), 500
|
||||||
|
|
||||||
@app.route('/api/documents', methods=['GET'])
|
@app.route('/api/documents', methods=['GET'])
|
||||||
def list_documents():
|
def list_documents():
|
||||||
"""列出所有文档"""
|
"""列出所有文档"""
|
||||||
|
|
@ -210,25 +253,31 @@ def rag_analyze():
|
||||||
|
|
||||||
def init_service():
|
def init_service():
|
||||||
"""初始化服务"""
|
"""初始化服务"""
|
||||||
print("=" * 50)
|
log.info("%s", "=" * 50)
|
||||||
print("RAG 知识库服务启动中...")
|
log.info("RAG 知识库服务启动中...")
|
||||||
print("=" * 50)
|
log.info("%s", "=" * 50)
|
||||||
|
record_event("service_start", knowledge_dir=KNOWLEDGE_DIR, base_dir=BASE_DIR)
|
||||||
|
|
||||||
# 初始化知识库服务
|
# 初始化知识库服务
|
||||||
knowledge_service.init()
|
knowledge_service.init()
|
||||||
|
record_event("index_loaded")
|
||||||
|
|
||||||
# 扫描并索引新文件
|
# 扫描并索引新文件
|
||||||
knowledge_service.scan_and_index_folder()
|
scan_result = knowledge_service.scan_and_index_folder()
|
||||||
|
record_event("startup_scan", result=scan_result)
|
||||||
|
|
||||||
# 启动文件监控
|
# 启动文件监控
|
||||||
global file_watcher
|
global file_watcher
|
||||||
file_watcher = FileWatcher(knowledge_service)
|
file_watcher = FileWatcher(knowledge_service)
|
||||||
file_watcher.start()
|
file_watcher.start()
|
||||||
|
|
||||||
|
record_event("watcher_started", path=KNOWLEDGE_DIR)
|
||||||
|
|
||||||
print("=" * 50)
|
log.info("%s", "=" * 50)
|
||||||
print(f"服务已启动: http://{HOST}:{PORT}")
|
log.info("服务已启动: http://%s:%s", HOST, PORT)
|
||||||
print(f"知识库文件夹: {KNOWLEDGE_DIR}")
|
log.info("知识库文件夹: %s", KNOWLEDGE_DIR)
|
||||||
print("=" * 50)
|
log.info("%s", "=" * 50)
|
||||||
|
record_event("service_ready", host=HOST, port=PORT)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
init_service()
|
init_service()
|
||||||
|
|
|
||||||
29
rag-python/event_store.py
Normal file
29
rag-python/event_store.py
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections import deque
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from threading import Lock
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
_events: "deque[Dict[str, Any]]" = deque(maxlen=2000)
|
||||||
|
_lock = Lock()
|
||||||
|
|
||||||
|
|
||||||
|
def record_event(event_type: str, **payload: Any) -> None:
|
||||||
|
event = {
|
||||||
|
"ts": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"type": event_type,
|
||||||
|
"payload": payload,
|
||||||
|
}
|
||||||
|
with _lock:
|
||||||
|
_events.append(event)
|
||||||
|
|
||||||
|
|
||||||
|
def get_events(limit: Optional[int] = None, newest_first: bool = True) -> List[Dict[str, Any]]:
|
||||||
|
with _lock:
|
||||||
|
items = list(_events)
|
||||||
|
if newest_first:
|
||||||
|
items.reverse()
|
||||||
|
if limit is not None:
|
||||||
|
return items[: max(0, limit)]
|
||||||
|
return items
|
||||||
|
|
@ -62,9 +62,6 @@
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['psychology:permission:add']">新增</el-button>
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['psychology:permission:add']">新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['psychology:permission:remove']">删除</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user