feat: 初始化项目结构并添加核心功能模块

- 新增文档模板和导航结构
- 实现服务器基础API路由和控制器
- 添加扩展插件配置和前端框架
- 引入多租户和权限管理模块
- 集成日志和数据库配置
- 添加核心业务模型和类型定义
This commit is contained in:
2026-03-17 22:07:19 +08:00
parent c0870dce50
commit 136c2fa579
728 changed files with 107690 additions and 5614 deletions

View File

@@ -0,0 +1,169 @@
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../../core/governance/FeatureGovernanceService';
import { RedisService } from '../../utils/RedisService';
import db from '../../config/database';
import os from 'os';
export interface HealthPrediction {
metric: string;
currentValue: number;
predictedValue: number;
threshold: number;
probabilityOfFailure: number; // 0-1
estimatedTimeUntilBreach: number; // minutes
suggestedAction: string;
}
/**
* [CORE_TELE_02] 预测性系统健康度看板 (Predictive Health)
* @description 利用 AI 预测未来 24h 潜在瓶颈如数据库连接耗尽、Redis 内存溢出、API 延迟激增)。
* 遵循 V30.0 Zero-Mock 规范,基于真实遥测数据进行趋势分析。
*/
export class PredictiveHealthService {
private static readonly PREDICTION_TABLE = 'cf_telemetry_predictions';
/**
* 初始化数据库表
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.PREDICTION_TABLE);
if (!hasTable) {
logger.info(`📦 Creating ${this.PREDICTION_TABLE} table...`);
await db.schema.createTable(this.PREDICTION_TABLE, (table) => {
table.increments('id').primary();
table.string('metric', 64).notNullable();
table.float('current_value').notNullable();
table.float('predicted_value').notNullable();
table.float('threshold').notNullable();
table.float('probability_of_failure').notNullable();
table.integer('estimated_time_until_breach').notNullable();
table.text('suggested_action').notNullable();
table.timestamp('created_at').defaultTo(db.fn.now());
table.index(['metric', 'created_at']);
});
logger.info(`✅ Table ${this.PREDICTION_TABLE} created`);
}
}
/**
* 获取系统健康度预测结果
*/
static async getHealthPredictions(tenantId?: string): Promise<HealthPrediction[]> {
// Feature Flag Check
if (!(await FeatureGovernanceService.isEnabled('CORE_TELE_PREDICTIVE_HEALTH', tenantId))) {
return [];
}
logger.info('[PredictiveHealth] Analyzing real-time system metrics for future bottlenecks...');
const predictions: HealthPrediction[] = [];
try {
// 1. 数据库连接池分析
const dbPool = (db.client as any).pool;
const usedConns = dbPool?.used?.length || 0;
const maxConns = dbPool?.max || 10;
const dbUsage = (usedConns / maxConns) * 100;
// 简单线性外推预测 (基于历史 1 小时趋势)
const dbTrend = await this.calculateTrend('DB_CONNECTION_POOL');
const predictedDbUsage = Math.min(100, dbUsage + (dbTrend * 24)); // 预测 24h 后
predictions.push({
metric: 'DB_CONNECTION_POOL',
currentValue: Number(dbUsage.toFixed(2)),
predictedValue: Number(predictedDbUsage.toFixed(2)),
threshold: 90,
probabilityOfFailure: predictedDbUsage > 90 ? 0.8 : 0.1,
estimatedTimeUntilBreach: dbTrend > 0 ? Math.round((90 - dbUsage) / dbTrend) : -1,
suggestedAction: predictedDbUsage > 90 ? 'Increase DB Pool Size or optimize long transactions.' : 'Healthy'
});
// 2. Redis 内存分析
const redis = RedisService.getClient();
const info = await redis.info('memory');
const usedMemoryMatch = info.match(/used_memory:(\d+)/);
const maxMemoryMatch = info.match(/maxmemory:(\d+)/);
const usedMem = usedMemoryMatch ? parseInt(usedMemoryMatch[1]) / 1024 / 1024 : 0; // MB
const maxMem = maxMemoryMatch && parseInt(maxMemoryMatch[1]) > 0
? parseInt(maxMemoryMatch[1]) / 1024 / 1024
: (os.totalmem() / 1024 / 1024) * 0.1; // 默认取系统内存 10%
const memUsage = (usedMem / maxMem) * 100;
const memTrend = await this.calculateTrend('REDIS_MEMORY_USAGE');
const predictedMemUsage = Math.min(100, memUsage + (memTrend * 24));
predictions.push({
metric: 'REDIS_MEMORY_USAGE',
currentValue: Number(memUsage.toFixed(2)),
predictedValue: Number(predictedMemUsage.toFixed(2)),
threshold: 85,
probabilityOfFailure: predictedMemUsage > 85 ? 0.7 : 0.05,
estimatedTimeUntilBreach: memTrend > 0 ? Math.round((85 - memUsage) / memTrend) : -1,
suggestedAction: predictedMemUsage > 85 ? 'Enable Redis key eviction or upgrade memory quota.' : 'Healthy'
});
// 3. 系统负载分析
const load = os.loadavg()[0];
const cpuCores = os.cpus().length;
const loadUsage = (load / cpuCores) * 100;
const loadTrend = await this.calculateTrend('SYSTEM_LOAD');
const predictedLoad = loadUsage + (loadTrend * 24);
predictions.push({
metric: 'SYSTEM_LOAD',
currentValue: Number(loadUsage.toFixed(2)),
predictedValue: Number(predictedLoad.toFixed(2)),
threshold: 80,
probabilityOfFailure: predictedLoad > 80 ? 0.6 : 0.1,
estimatedTimeUntilBreach: loadTrend > 0 ? Math.round((80 - loadUsage) / loadTrend) : -1,
suggestedAction: predictedLoad > 80 ? 'Scale out application nodes or check for CPU-intensive tasks.' : 'Healthy'
});
// 持久化预测结果 (Zero-Mock 落地)
for (const p of predictions) {
await this.logPrediction(p);
}
} catch (err: any) {
logger.error(`[PredictiveHealth] Metric analysis failed: ${err.message}`);
}
return predictions;
}
/**
* 基于历史数据计算指标变化趋势 (每小时变化率)
*/
private static async calculateTrend(metric: string): Promise<number> {
const history = await db(this.PREDICTION_TABLE)
.where({ metric })
.orderBy('created_at', 'desc')
.limit(10);
if (history.length < 2) return 0;
const latest = history[0].current_value;
const oldest = history[history.length - 1].current_value;
const timeDiff = (new Date(history[0].created_at).getTime() - new Date(history[history.length - 1].created_at).getTime()) / 3600000; // hours
return timeDiff > 0 ? (latest - oldest) / timeDiff : 0;
}
/**
* 记录预测结果用于回溯
*/
static async logPrediction(prediction: HealthPrediction) {
await db(this.PREDICTION_TABLE).insert({
metric: prediction.metric,
current_value: prediction.currentValue,
predicted_value: prediction.predictedValue,
threshold: prediction.threshold,
probability_of_failure: prediction.probabilityOfFailure,
estimated_time_until_breach: prediction.estimatedTimeUntilBreach,
suggested_action: prediction.suggestedAction,
created_at: new Date()
});
}
}