diff --git a/src/app/(dashboard)/page.tsx b/src/app/(dashboard)/page.tsx index 8496147..a9b58a2 100644 --- a/src/app/(dashboard)/page.tsx +++ b/src/app/(dashboard)/page.tsx @@ -382,7 +382,7 @@ export default function DashboardPage() { height={200} /> } data={chartData.data?.pipeline.latency ?? {}} variant="area" diff --git a/src/app/(dashboard)/pipelines/[id]/metrics/page.tsx b/src/app/(dashboard)/pipelines/[id]/metrics/page.tsx index 85e0edb..5836a1a 100644 --- a/src/app/(dashboard)/pipelines/[id]/metrics/page.tsx +++ b/src/app/(dashboard)/pipelines/[id]/metrics/page.tsx @@ -118,7 +118,7 @@ export default function PipelineMetricsPage() { - Component Latency + Pipeline Latency diff --git a/src/components/pipeline/metrics-chart.tsx b/src/components/pipeline/metrics-chart.tsx index e659256..b35a8cf 100644 --- a/src/components/pipeline/metrics-chart.tsx +++ b/src/components/pipeline/metrics-chart.tsx @@ -168,7 +168,7 @@ export function PipelineMetricsChart({ pipelineId, hours = 24 }: PipelineMetrics {/* Latency chart */}
-

Component Latency

+

Pipeline Latency

diff --git a/src/server/services/alert-evaluator.ts b/src/server/services/alert-evaluator.ts index 6d55027..a05c8db 100644 --- a/src/server/services/alert-evaluator.ts +++ b/src/server/services/alert-evaluator.ts @@ -226,12 +226,15 @@ export async function evaluateAlerts( if (!node) return []; - // Load all enabled rules for this environment + // Load all enabled rules for this environment (include pipeline name for messages) const rules = await prisma.alertRule.findMany({ where: { environmentId, enabled: true, }, + include: { + pipeline: { select: { name: true } }, + }, }); const results: FiredAlertEvent[] = []; @@ -281,7 +284,7 @@ export async function evaluateAlerts( if (!existingEvent) { // Create a new firing event - const message = buildMessage(rule, value); + const message = buildMessage(rule, value, rule.pipeline?.name); const event = await prisma.alertEvent.create({ data: { alertRuleId: rule.id, @@ -354,11 +357,34 @@ const CONDITION_LABELS: Record = { eq: "=", }; -function buildMessage(rule: AlertRule, value: number): string { +/** Metrics where the value is binary (0/1) and the numeric details are noise. */ +const BINARY_METRICS = new Set([ + "pipeline_crashed", + "node_unreachable", +]); + +function buildMessage( + rule: AlertRule, + value: number, + pipelineName?: string | null, +): string { const metricLabel = METRIC_LABELS[rule.metric] ?? rule.metric; + if (!rule.condition || rule.threshold == null) { - return `${metricLabel} event fired`; + return pipelineName + ? `${metricLabel}: ${pipelineName}` + : `${metricLabel}`; } + + // Binary metrics: just state what happened, with the pipeline name if available + if (BINARY_METRICS.has(rule.metric)) { + return pipelineName + ? `${metricLabel}: ${pipelineName}` + : `${metricLabel}`; + } + + // Numeric metrics: include value and threshold for context const condLabel = CONDITION_LABELS[rule.condition] ?? rule.condition; - return `${metricLabel} is ${value.toFixed(2)} (threshold: ${condLabel} ${rule.threshold})`; + const prefix = pipelineName ? `${pipelineName} — ` : ""; + return `${prefix}${metricLabel} at ${value.toFixed(2)} (threshold: ${condLabel} ${rule.threshold})`; } diff --git a/src/server/services/metric-store.ts b/src/server/services/metric-store.ts index e7d8907..1ef2d1c 100644 --- a/src/server/services/metric-store.ts +++ b/src/server/services/metric-store.ts @@ -7,7 +7,7 @@ export interface MetricSample { errorCount: number; errorsRate: number; discardedRate: number; - latencyMeanMs: number | null; // mean component latency in ms + latencyMeanMs: number | null; // mean pipeline latency in ms } interface PrevTotals {