From a84dfd6d0334acc59749bc94f78f808e810f408d Mon Sep 17 00:00:00 2001 From: huangzhenting Date: Mon, 23 Mar 2026 08:45:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=20db=5Fenabled/db=5F?= =?UTF-8?q?path=20=E7=83=AD=E9=87=8D=E8=BD=BD=E6=94=AF=E6=8C=81=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E6=A1=A3=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - logger-db.ts: 新增 closeDb(),修复 initDb() 支持安全重复调用 - logger.ts: 注册 onConfigReload 回调,db_enabled/db_path 变更后无需重启 - config.yaml.example: 删除「需重启」警告注释,补充热重载说明 - README.md: 修复环境变量表格被 blockquote 截断的格式问题,更新热重载说明 - vue-ui/README.md: 删除「需重启服务」错误说明 - ConfigDrawer.vue: 删除「需重启」提示 --- README.md | 6 ++---- config.yaml.example | 3 +-- src/logger-db.ts | 8 +++++++ src/logger.ts | 30 ++++++++++++++++++++++++-- vue-ui/README.md | 2 -- vue-ui/src/components/ConfigDrawer.vue | 1 - 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9ecb0e4..62acbb7 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,6 @@ cp config.yaml.example config.yaml | `tools.disabled` | 🆕 禁用模式:完全不注入工具定义,极致省上下文 | `false` | > 💡 详细配置说明请参见 `config.yaml.example` 中的注释。 -> -> ⚠️ `logging.*` 所有配置项修改后均需重启服务才能生效(不支持热重载)。 ### 3. 启动 @@ -245,8 +243,6 @@ AI 按此格式输出 → 我们解析并转换为标准的 Anthropic `tool_use` | 环境变量 | 说明 | |----------|------| -> ⚠️ **环境变量优先级高于 `config.yaml`**:若在 docker-compose 等环境中设置了环境变量,该参数的 `config.yaml` 配置会被覆盖,热重载对其**无效**。需要通过 `config.yaml` 动态调整的参数,请勿同时在环境变量中设置。 - | `PORT` | 服务端口 | | `AUTH_TOKEN` | API 鉴权 token(逗号分隔多个) | | `PROXY` | 全局代理地址 | @@ -265,6 +261,8 @@ AI 按此格式输出 → 我们解析并转换为标准的 Anthropic `tool_use` | `TOOLS_PASSTHROUGH` | 🆕 工具透传模式 (`true`/`false`,默认 `false`) | | `TOOLS_DISABLED` | 🆕 工具禁用模式 (`true`/`false`,默认 `false`) | +> ⚠️ **环境变量优先级高于 `config.yaml`**:若在 docker-compose 等环境中设置了环境变量,该参数的 `config.yaml` 配置会被覆盖,热重载对其**无效**。需要通过 `config.yaml` 动态调整的参数,请勿同时在环境变量中设置。 + ## 免责声明 / Disclaimer **本项目仅供学习、研究和接口调试目的使用。** diff --git a/config.yaml.example b/config.yaml.example index 7993df2..5350427 100644 --- a/config.yaml.example +++ b/config.yaml.example @@ -201,7 +201,7 @@ vision: # ==================== 日志持久化配置(可选) ==================== # 支持两种持久化方式,可单独开启或同时开启(双写)。 -# ⚠️ 以下所有配置项修改后需重启服务才能生效(不支持热重载) +# 支持热重载,修改 config.yaml 后无需重启即可生效。 # # 方式一:JSONL 文件(每天一个文件,适合日志量较小的场景) # 环境变量: LOG_FILE_ENABLED=true|false, LOG_DIR=./logs, LOG_PERSIST_MODE=compact|full|summary @@ -225,7 +225,6 @@ logging: persist_mode: summary # 方式二:SQLite 数据库持久化(推荐,默认关闭) - # ⚠️ 修改 db_enabled 或 db_path 后需重启服务才能生效 db_enabled: false # SQLite 文件路径(确保 logs 目录已挂载,Docker 下同 dir 目录) db_path: "./logs/cursor2api.db" diff --git a/src/logger-db.ts b/src/logger-db.ts index 2a57b7e..3b3268e 100644 --- a/src/logger-db.ts +++ b/src/logger-db.ts @@ -19,7 +19,15 @@ let db: InstanceType | null = null; // ==================== 初始化 ==================== +export function closeDb(): void { + if (db) { + db.close(); + db = null; + } +} + export function initDb(dbPath: string): void { + closeDb(); // 关闭旧连接(幂等,支持热重载重新初始化) const dir = dirname(dbPath); if (dir && !existsSync(dir)) { mkdirSync(dir, { recursive: true }); diff --git a/src/logger.ts b/src/logger.ts index 3f1887e..9deb566 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -16,8 +16,8 @@ import { EventEmitter } from 'events'; import { existsSync, mkdirSync, appendFileSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from 'fs'; import { join, basename } from 'path'; -import { getConfig } from './config.js'; -import { initDb, dbInsertRequest, dbGetPayload, dbGetSummaries, dbCountSummaries, dbGetSummaryCount, dbGetStatusCounts, dbGetSummariesSince, dbClear } from './logger-db.js'; +import { getConfig, onConfigReload } from './config.js'; +import { initDb, closeDb, isDbInitialized, dbInsertRequest, dbGetPayload, dbGetSummaries, dbCountSummaries, dbGetSummaryCount, dbGetStatusCounts, dbGetSummariesSince, dbClear } from './logger-db.js'; // ==================== 类型定义 ==================== @@ -552,6 +552,32 @@ export function loadLogsFromFiles(): void { } } +// ==================== SQLite 热重载 ==================== +// 注册配置热重载回调,处理 db_enabled / db_path 运行时变更 +onConfigReload((newCfg, changes) => { + // 只在 logging 配置变更时处理(避免其他字段变更触发不必要的 DB 重初始化) + if (!changes.some(c => c.startsWith('logging'))) return; + + const dbEnabled = newCfg.logging?.db_enabled ?? false; + const dbPath = newCfg.logging?.db_path || './logs/cursor2api.db'; + + if (dbEnabled) { + // 启用或路径变更:重新初始化(initDb 内部会先关闭旧连接) + try { + initDb(dbPath); + console.log(`[Logger] SQLite 热重载:已初始化 ${dbPath}`); + } catch (e) { + console.warn('[Logger] SQLite 热重载初始化失败:', e); + } + } else { + // 禁用:关闭连接 + if (isDbInitialized()) { + closeDb(); + console.log('[Logger] SQLite 热重载:已关闭连接'); + } + } +}); + /** 清空所有日志(内存 + 文件) */ export function clearAllLogs(): { cleared: number } { const count = requestSummaries.size; diff --git a/vue-ui/README.md b/vue-ui/README.md index 772580b..284cbe5 100644 --- a/vue-ui/README.md +++ b/vue-ui/README.md @@ -106,8 +106,6 @@ open http://localhost:3010/vuelogs | 日志持久化 | `logging.file_enabled` / `logging.dir` / `logging.persist_mode` | JSONL 文件持久化 | | 高级 | `refusal_patterns` | 自定义拒绝检测正则 | -> **注意**:`logging.*` 属于启动时初始化参数,修改后**需重启服务**才能生效;其余配置热重载,下一次请求即生效。 - ## 与原有日志页面的关系 | 路由 | 实现 | 鉴权方式 | diff --git a/vue-ui/src/components/ConfigDrawer.vue b/vue-ui/src/components/ConfigDrawer.vue index bff9616..b268354 100644 --- a/vue-ui/src/components/ConfigDrawer.vue +++ b/vue-ui/src/components/ConfigDrawer.vue @@ -94,7 +94,6 @@ -
⚠️ 此分组所有配置修改后需重启服务才能生效