86 lines
2.8 KiB
TypeScript
86 lines
2.8 KiB
TypeScript
|
|
import db from '../config/database';
|
||
|
|
import { logger } from '../utils/logger';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* [CORE_LOG_02] 全局操作流水线追踪后端 (Trace Tracking Backend)
|
||
|
|
* @description 提供跨模块的 Pipeline 与 Audit 日志聚合查询
|
||
|
|
*/
|
||
|
|
export class TraceService {
|
||
|
|
private static readonly INSTANCE_TABLE = 'cf_pipeline_instances';
|
||
|
|
private static readonly STEP_TABLE = 'cf_pipeline_steps';
|
||
|
|
private static readonly AUDIT_TABLE = 'cf_audit_log'; // 假设异步处理后的表名
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 根据 Trace ID 获取关联的流水线实例
|
||
|
|
*/
|
||
|
|
static async getPipelineByTraceId(traceId: string, tenantId: string) {
|
||
|
|
try {
|
||
|
|
const instance = await db(this.INSTANCE_TABLE)
|
||
|
|
.where({ trace_id: traceId, tenant_id: tenantId })
|
||
|
|
.first();
|
||
|
|
|
||
|
|
if (!instance) return null;
|
||
|
|
|
||
|
|
const steps = await db(this.STEP_TABLE)
|
||
|
|
.where({ instance_id: instance.id })
|
||
|
|
.orderBy('created_at', 'asc');
|
||
|
|
|
||
|
|
return {
|
||
|
|
...instance,
|
||
|
|
steps: steps.map(s => ({
|
||
|
|
...s,
|
||
|
|
config: s.config ? JSON.parse(s.config) : null,
|
||
|
|
output: s.output ? JSON.parse(s.output) : null,
|
||
|
|
error: s.error ? JSON.parse(s.error) : null
|
||
|
|
}))
|
||
|
|
};
|
||
|
|
} catch (err: any) {
|
||
|
|
logger.error(`[TraceService] Failed to get pipeline by trace: ${err.message}`);
|
||
|
|
throw err;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 获取租户最近的自治活动流
|
||
|
|
*/
|
||
|
|
static async getRecentActivities(tenantId: string, limit = 20) {
|
||
|
|
try {
|
||
|
|
return await db(this.INSTANCE_TABLE)
|
||
|
|
.where({ tenant_id: tenantId })
|
||
|
|
.orderBy('created_at', 'desc')
|
||
|
|
.limit(limit);
|
||
|
|
} catch (err: any) {
|
||
|
|
logger.error(`[TraceService] Failed to get recent activities: ${err.message}`);
|
||
|
|
throw err;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* [CORE_TELE_01] 获取 AI 自愈遥测数据
|
||
|
|
* @description 筛选出包含自愈行为 (Self-Healing) 的步骤
|
||
|
|
*/
|
||
|
|
static async getSelfHealingTelemetry(tenantId: string, limit = 50) {
|
||
|
|
try {
|
||
|
|
// 假设自愈日志记录在 metadata 或特定的自愈字段中
|
||
|
|
// 这里从步骤表中筛选出包含 retry 或 healing 标记的记录
|
||
|
|
return await db(this.STEP_TABLE)
|
||
|
|
.join(this.INSTANCE_TABLE, `${this.STEP_TABLE}.instance_id`, `${this.INSTANCE_TABLE}.id`)
|
||
|
|
.where(`${this.INSTANCE_TABLE}.tenant_id`, tenantId)
|
||
|
|
.whereNotNull(`${this.STEP_TABLE}.error`)
|
||
|
|
.orderBy(`${this.STEP_TABLE}.updated_at`, 'desc')
|
||
|
|
.limit(limit)
|
||
|
|
.select(
|
||
|
|
`${this.STEP_TABLE}.id`,
|
||
|
|
`${this.STEP_TABLE}.instance_id`,
|
||
|
|
`${this.STEP_TABLE}.type`,
|
||
|
|
`${this.STEP_TABLE}.status`,
|
||
|
|
`${this.STEP_TABLE}.error`,
|
||
|
|
`${this.STEP_TABLE}.updated_at as timestamp`
|
||
|
|
);
|
||
|
|
} catch (err: any) {
|
||
|
|
logger.error(`[TraceService] Failed to get telemetry: ${err.message}`);
|
||
|
|
throw err;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|