Spaces:
Sleeping
Sleeping
File size: 13,549 Bytes
fcc1a30 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
-- HR 对话质量评估系统 - Supabase 数据库表结构(含日志)
-- 在 Supabase SQL Editor 中执行此脚本
-- ============================================
-- 1. 对话历史表(已有)
-- ============================================
CREATE TABLE IF NOT EXISTS conversation_history (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
session_id TEXT NOT NULL,
user_message TEXT NOT NULL,
assistant_message TEXT NOT NULL,
analysis_report JSONB,
context_summary JSONB,
metadata JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_conversation_history_session_id ON conversation_history(session_id);
CREATE INDEX IF NOT EXISTS idx_conversation_history_created_at ON conversation_history(created_at DESC);
-- ============================================
-- 2. API 访问日志表(新增)
-- ============================================
CREATE TABLE IF NOT EXISTS api_access_logs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
-- 请求信息
endpoint TEXT NOT NULL,
method TEXT NOT NULL,
path TEXT,
query_params JSONB,
-- 客户端信息
client_ip TEXT,
user_agent TEXT,
session_id TEXT,
-- 性能指标
response_time_ms INTEGER,
status_code INTEGER,
-- 附加信息
metadata JSONB
);
-- 索引优化
CREATE INDEX IF NOT EXISTS idx_api_logs_timestamp ON api_access_logs(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_api_logs_endpoint ON api_access_logs(endpoint);
CREATE INDEX IF NOT EXISTS idx_api_logs_session_id ON api_access_logs(session_id);
CREATE INDEX IF NOT EXISTS idx_api_logs_status_code ON api_access_logs(status_code);
-- 分区(按月)- 可选,大数据量时使用
-- CREATE TABLE api_access_logs_y2025m01 PARTITION OF api_access_logs
-- FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');
-- ============================================
-- 3. 错误日志表(新增)
-- ============================================
CREATE TABLE IF NOT EXISTS error_logs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
-- 错误信息
error_type TEXT NOT NULL, -- 'validation', 'model_load', 'api_error', etc.
error_message TEXT NOT NULL,
error_stack TEXT,
-- 上下文
endpoint TEXT,
session_id TEXT,
user_input TEXT,
-- 请求详情
request_data JSONB,
-- 元数据
metadata JSONB
);
CREATE INDEX IF NOT EXISTS idx_error_logs_timestamp ON error_logs(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_error_logs_type ON error_logs(error_type);
CREATE INDEX IF NOT EXISTS idx_error_logs_session_id ON error_logs(session_id);
-- ============================================
-- 4. 模型性能日志表(新增)
-- ============================================
CREATE TABLE IF NOT EXISTS model_performance_logs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
-- 模型信息
model_name TEXT NOT NULL,
model_type TEXT NOT NULL, -- 'sbert', 'sentiment', 'compliance', 'llm'
-- 性能指标
load_time_ms INTEGER,
inference_time_ms INTEGER,
total_time_ms INTEGER,
-- 输入输出
input_text TEXT,
output_summary TEXT,
-- 附加信息
metadata JSONB
);
CREATE INDEX IF NOT EXISTS idx_model_perf_timestamp ON model_performance_logs(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_model_perf_model_name ON model_performance_logs(model_name);
CREATE INDEX IF NOT EXISTS idx_model_perf_type ON model_performance_logs(model_type);
-- ============================================
-- 5. 调试日志表(新增)- 用于开发调试
-- ============================================
CREATE TABLE IF NOT EXISTS debug_logs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
-- 日志信息
level TEXT NOT NULL, -- 'DEBUG', 'INFO', 'WARNING', 'ERROR'
logger TEXT NOT NULL, -- 模块名称,如 'intelligence_analyzer'
message TEXT NOT NULL,
-- 上下文
session_id TEXT,
function_name TEXT,
line_number INTEGER,
-- 结构化数据
data JSONB,
-- 附加信息
metadata JSONB
);
CREATE INDEX IF NOT EXISTS idx_debug_logs_timestamp ON debug_logs(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_debug_logs_level ON debug_logs(level);
CREATE INDEX IF NOT EXISTS idx_debug_logs_logger ON debug_logs(logger);
CREATE INDEX IF NOT EXISTS idx_debug_logs_session_id ON debug_logs(session_id);
-- ============================================
-- 6. 用户行为分析表(新增)
-- ============================================
CREATE TABLE IF NOT EXISTS user_behavior_logs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
-- 用户标识
session_id TEXT NOT NULL,
user_id TEXT, -- 可选,如果有多用户系统
-- 行为类型
action_type TEXT NOT NULL, -- 'chat', 'evaluate', 'config_check', etc.
action_detail TEXT,
-- 内容
input_text TEXT,
intent_detected TEXT,
scenario_detected TEXT,
-- 结果
success BOOLEAN,
error_message TEXT,
-- 元数据
metadata JSONB
);
CREATE INDEX IF NOT EXISTS idx_user_behavior_timestamp ON user_behavior_logs(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_user_behavior_session_id ON user_behavior_logs(session_id);
CREATE INDEX IF NOT EXISTS idx_user_behavior_action_type ON user_behavior_logs(action_type);
-- ============================================
-- 启用行级安全性 (RLS)
-- ============================================
ALTER TABLE api_access_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE error_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE model_performance_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE debug_logs ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_behavior_logs ENABLE ROW LEVEL SECURITY;
-- 允许所有操作(演示环境)
CREATE POLICY "Enable all access for api_access_logs" ON api_access_logs FOR ALL USING (true);
CREATE POLICY "Enable all access for error_logs" ON error_logs FOR ALL USING (true);
CREATE POLICY "Enable all access for model_performance_logs" ON model_performance_logs FOR ALL USING (true);
CREATE POLICY "Enable all access for debug_logs" ON debug_logs FOR ALL USING (true);
CREATE POLICY "Enable all access for user_behavior_logs" ON user_behavior_logs FOR ALL USING (true);
-- ============================================
-- 实用函数
-- ============================================
-- 清理旧日志(保留最近 N 天)
CREATE OR REPLACE FUNCTION cleanup_old_logs(days_to_keep INTEGER DEFAULT 30)
RETURNS TABLE (
api_logs_deleted BIGINT,
error_logs_deleted BIGINT,
debug_logs_deleted BIGINT,
model_perf_logs_deleted BIGINT
)
LANGUAGE plpgsql
AS $$
DECLARE
api_count BIGINT;
error_count BIGINT;
debug_count BIGINT;
model_count BIGINT;
BEGIN
-- 清理 API 日志
DELETE FROM api_access_logs
WHERE timestamp < NOW() - (days_to_keep || ' days')::INTERVAL;
GET DIAGNOSTICS api_count = ROW_COUNT;
-- 清理错误日志(保留更久)
DELETE FROM error_logs
WHERE timestamp < NOW() - ((days_to_keep * 2) || ' days')::INTERVAL;
GET DIAGNOSTICS error_count = ROW_COUNT;
-- 清理调试日志(保留更短时间)
DELETE FROM debug_logs
WHERE timestamp < NOW() - ((days_to_keep / 2) || ' days')::INTERVAL;
GET DIAGNOSTICS debug_count = ROW_COUNT;
-- 清理模型性能日志
DELETE FROM model_performance_logs
WHERE timestamp < NOW() - (days_to_keep || ' days')::INTERVAL;
GET DIAGNOSTICS model_count = ROW_COUNT;
RETURN QUERY SELECT api_count, error_count, debug_count, model_count;
END;
$$;
-- 获取 API 统计
CREATE OR REPLACE FUNCTION get_api_statistics(hours_ago INTEGER DEFAULT 24)
RETURNS TABLE (
endpoint TEXT,
request_count BIGINT,
avg_response_time NUMERIC,
error_rate NUMERIC,
p95_response_time NUMERIC
)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT
endpoint,
COUNT(*) as request_count,
AVG(response_time_ms) as avg_response_time,
COUNT(*) FILTER (WHERE status_code >= 400) * 100.0 / COUNT(*) as error_rate,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY response_time_ms) as p95_response_time
FROM api_access_logs
WHERE timestamp >= NOW() - (hours_ago || ' hours')::INTERVAL
GROUP BY endpoint
ORDER BY request_count DESC;
END;
$$;
-- 获取错误统计
CREATE OR REPLACE FUNCTION get_error_summary(hours_ago INTEGER DEFAULT 24)
RETURNS TABLE (
error_type TEXT,
error_count BIGINT,
most_common_message TEXT
)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT
error_type,
COUNT(*) as error_count,
mode() WITHIN GROUP (ORDER BY error_message) as most_common_message
FROM error_logs
WHERE timestamp >= NOW() - (hours_ago || ' hours')::INTERVAL
GROUP BY error_type
ORDER BY error_count DESC;
END;
$$;
-- 搜索日志
CREATE OR REPLACE FUNCTION search_logs(
search_term TEXT,
log_type TEXT DEFAULT 'all', -- 'api', 'error', 'debug', 'all'
hours_ago INTEGER DEFAULT 24,
limit_count INTEGER DEFAULT 100
)
RETURNS TABLE (
log_type TEXT,
log_id UUID,
timestamp TIMESTAMP WITH TIME ZONE,
summary TEXT
)
LANGUAGE plpgsql
AS $$
BEGIN
-- API 日志
IF log_type = 'api' OR log_type = 'all' THEN
RETURN QUERY
SELECT
'api'::TEXT as log_type,
id as log_id,
timestamp,
endpoint || ' - ' || status_code::TEXT as summary
FROM api_access_logs
WHERE (
search_term ILIKE '%' || search_term || '%'
OR endpoint ILIKE '%' || search_term || '%'
OR path ILIKE '%' || search_term || '%'
)
AND timestamp >= NOW() - (hours_ago || ' hours')::INTERVAL
LIMIT limit_count;
END IF;
-- 错误日志
IF log_type = 'error' OR log_type = 'all' THEN
RETURN QUERY
SELECT
'error'::TEXT as log_type,
id as log_id,
timestamp,
error_type || ' - ' || LEFT(error_message, 50) as summary
FROM error_logs
WHERE error_message ILIKE '%' || search_term || '%'
AND timestamp >= NOW() - (hours_ago || ' hours')::INTERVAL
LIMIT limit_count;
END IF;
-- 调试日志
IF log_type = 'debug' OR log_type = 'all' THEN
RETURN QUERY
SELECT
'debug'::TEXT as log_type,
id as log_id,
timestamp,
level || ' - ' || logger || ' - ' || LEFT(message, 50) as summary
FROM debug_logs
WHERE message ILIKE '%' || search_term || '%'
AND timestamp >= NOW() - (hours_ago || ' hours')::INTERVAL
LIMIT limit_count;
END IF;
END;
$$;
-- ============================================
-- 定时清理任务(可选)
-- ============================================
-- 创建一个函数来定期清理日志
CREATE OR REPLACE FUNCTION auto_cleanup_logs()
RETURNS VOID
LANGUAGE plpgsql
AS $$
BEGIN
-- 清理 7 天前的调试日志
DELETE FROM debug_logs
WHERE timestamp < NOW() - INTERVAL '7 days';
-- 清理 30 天前的 API 日志
DELETE FROM api_access_logs
WHERE timestamp < NOW() - INTERVAL '30 days';
-- 清理 90 天前的模型性能日志
DELETE FROM model_performance_logs
WHERE timestamp < NOW() - INTERVAL '90 days';
-- 错误日志保留 180 天
DELETE FROM error_logs
WHERE timestamp < NOW() - INTERVAL '180 days';
END;
$$;
-- 在 Supabase Dashboard 中设置 cron job 来调用这个函数
-- 或者使用 pg_cron 扩展(如果可用)
-- SELECT cron.schedule('cleanup-logs', '0 2 * * *', 'SELECT auto_cleanup_logs()');
-- ============================================
-- 视图 - 方便查询
-- ============================================
-- 综合日志视图
CREATE OR REPLACE VIEW v_recent_logs AS
SELECT
'api' as log_type,
timestamp,
endpoint as title,
status_code::TEXT as detail,
session_id
FROM api_access_logs
WHERE timestamp >= NOW() - INTERVAL '24 hours'
UNION ALL
SELECT
'error' as log_type,
timestamp,
error_type as title,
LEFT(error_message, 50) as detail,
session_id
FROM error_logs
WHERE timestamp >= NOW() - INTERVAL '24 hours'
UNION ALL
SELECT
'debug' as log_type,
timestamp,
logger as title,
level || ' - ' || LEFT(message, 30) as detail,
session_id
FROM debug_logs
WHERE timestamp >= NOW() - INTERVAL '24 hours'
ORDER BY timestamp DESC
LIMIT 100;
-- ============================================
-- 注释
-- ============================================
COMMENT ON TABLE api_access_logs IS 'API 访问日志';
COMMENT ON TABLE error_logs IS '错误日志';
COMMENT ON TABLE model_performance_logs IS '模型性能日志';
COMMENT ON TABLE debug_logs IS '调试日志';
COMMENT ON TABLE user_behavior_logs IS '用户行为日志';
COMMENT ON FUNCTION cleanup_old_logs IS '清理旧日志,默认保留 30 天';
COMMENT ON FUNCTION get_api_statistics IS '获取 API 统计信息';
COMMENT ON FUNCTION get_error_summary IS '获取错误摘要';
COMMENT ON FUNCTION search_logs IS '搜索日志内容';
COMMENT ON FUNCTION auto_cleanup_logs IS '自动清理日志';
COMMENT ON VIEW v_recent_logs IS '最近 24 小时的综合日志视图';
|