mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
feat: add session log usage tracking without proxy
Parse Claude Code JSONL session files (~/.claude/projects/) and Codex SQLite database (~/.codex/state_5.sqlite) to track API usage without requiring proxy interception. This enables usage statistics for users who don't use the proxy feature. Key changes: - Add session_usage.rs: incremental JSONL parser with message.id dedup - Add session_usage_codex.rs: import thread-level token data from Codex - Add data_source column to proxy_request_logs (proxy/session_log/codex_db) - Add session_log_sync table for tracking parse offsets - Background sync every 60s + manual sync via DataSourceBar UI - Schema migration v7→v8 - i18n support for zh/en/ja
This commit is contained in:
@@ -189,7 +189,8 @@ impl Database {
|
||||
total_cost_usd TEXT NOT NULL DEFAULT '0', latency_ms INTEGER NOT NULL, first_token_ms INTEGER,
|
||||
duration_ms INTEGER, status_code INTEGER NOT NULL, error_message TEXT, session_id TEXT,
|
||||
provider_type TEXT, is_streaming INTEGER NOT NULL DEFAULT 0,
|
||||
cost_multiplier TEXT NOT NULL DEFAULT '1.0', created_at INTEGER NOT NULL
|
||||
cost_multiplier TEXT NOT NULL DEFAULT '1.0', created_at INTEGER NOT NULL,
|
||||
data_source TEXT NOT NULL DEFAULT 'proxy'
|
||||
)", []).map_err(|e| AppError::Database(e.to_string()))?;
|
||||
|
||||
conn.execute("CREATE INDEX IF NOT EXISTS idx_request_logs_provider ON proxy_request_logs(provider_id, app_type)", [])
|
||||
@@ -271,6 +272,18 @@ impl Database {
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
|
||||
// 18. Session Log Sync 表 (会话日志同步状态)
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS session_log_sync (
|
||||
file_path TEXT PRIMARY KEY,
|
||||
last_modified INTEGER NOT NULL,
|
||||
last_line_offset INTEGER NOT NULL DEFAULT 0,
|
||||
last_synced_at INTEGER NOT NULL
|
||||
)",
|
||||
[],
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
|
||||
// 尝试添加 live_takeover_active 列到 proxy_config 表
|
||||
let _ = conn.execute(
|
||||
"ALTER TABLE proxy_config ADD COLUMN live_takeover_active INTEGER NOT NULL DEFAULT 0",
|
||||
@@ -400,6 +413,11 @@ impl Database {
|
||||
Self::migrate_v6_to_v7(conn)?;
|
||||
Self::set_user_version(conn, 7)?;
|
||||
}
|
||||
7 => {
|
||||
log::info!("迁移数据库从 v7 到 v8(会话日志使用追踪)");
|
||||
Self::migrate_v7_to_v8(conn)?;
|
||||
Self::set_user_version(conn, 8)?;
|
||||
}
|
||||
_ => {
|
||||
return Err(AppError::Database(format!(
|
||||
"未知的数据库版本 {version},无法迁移到 {SCHEMA_VERSION}"
|
||||
@@ -1060,6 +1078,34 @@ impl Database {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// v7 -> v8: 会话日志使用追踪(无代理模式统计支持)
|
||||
fn migrate_v7_to_v8(conn: &Connection) -> Result<(), AppError> {
|
||||
// 1. 为 proxy_request_logs 添加 data_source 列,区分数据来源
|
||||
if Self::table_exists(conn, "proxy_request_logs")? {
|
||||
Self::add_column_if_missing(
|
||||
conn,
|
||||
"proxy_request_logs",
|
||||
"data_source",
|
||||
"TEXT NOT NULL DEFAULT 'proxy'",
|
||||
)?;
|
||||
}
|
||||
|
||||
// 2. 创建会话日志同步状态表
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS session_log_sync (
|
||||
file_path TEXT PRIMARY KEY,
|
||||
last_modified INTEGER NOT NULL,
|
||||
last_line_offset INTEGER NOT NULL DEFAULT 0,
|
||||
last_synced_at INTEGER NOT NULL
|
||||
)",
|
||||
[],
|
||||
)
|
||||
.map_err(|e| AppError::Database(format!("创建 session_log_sync 表失败: {e}")))?;
|
||||
|
||||
log::info!("v7 -> v8 迁移完成:已添加 data_source 列和 session_log_sync 表");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 插入默认模型定价数据
|
||||
/// 格式: (model_id, display_name, input, output, cache_read, cache_creation)
|
||||
/// 注意: model_id 使用短横线格式(如 claude-haiku-4-5),与 API 返回的模型名称标准化后一致
|
||||
|
||||
Reference in New Issue
Block a user