feat: 实现 db_enabled/db_path 热重载支持,修复文档格式

- logger-db.ts: 新增 closeDb(),修复 initDb() 支持安全重复调用
- logger.ts: 注册 onConfigReload 回调,db_enabled/db_path 变更后无需重启
- config.yaml.example: 删除「需重启」警告注释,补充热重载说明
- README.md: 修复环境变量表格被 blockquote 截断的格式问题,更新热重载说明
- vue-ui/README.md: 删除「需重启服务」错误说明
- ConfigDrawer.vue: 删除「需重启」提示
This commit is contained in:
huangzhenting
2026-03-23 08:45:21 +08:00
parent 1bc91cac24
commit a84dfd6d03
6 changed files with 39 additions and 11 deletions

View File

@@ -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
**本项目仅供学习、研究和接口调试目的使用。**

View File

@@ -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"

View File

@@ -19,7 +19,15 @@ let db: InstanceType<typeof Database> | 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 });

View File

@@ -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;

View File

@@ -106,8 +106,6 @@ open http://localhost:3010/vuelogs
| 日志持久化 | `logging.file_enabled` / `logging.dir` / `logging.persist_mode` | JSONL 文件持久化 |
| 高级 | `refusal_patterns` | 自定义拒绝检测正则 |
> **注意**`logging.*` 属于启动时初始化参数,修改后**需重启服务**才能生效;其余配置热重载,下一次请求即生效。
## 与原有日志页面的关系
| 路由 | 实现 | 鉴权方式 |

View File

@@ -94,7 +94,6 @@
<!-- 日志 -->
<Group title="日志持久化logging">
<div class="restart-notice"> 此分组所有配置修改后需重启服务才能生效</div>
<Field label="logging.db_enabled" desc="SQLite 持久化推荐。启动时仅加载摘要payload 按需查询,彻底避免大文件 OOMVue UI 支持重启后翻页查看完整历史">
<Toggle v-model="draft.logging.db_enabled" />
</Field>