@obsunified/collector 2.3.0 → 2.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.d.ts +2 -1
- package/dist/index.d.ts +264 -62
- package/dist/index.js +850 -61
- package/dist/index.js.map +1 -1
- package/dist/{ingest-auth-BmP5-f96.d.ts → ingest-auth-BTowieER.d.ts} +66 -2
- package/package.json +2 -2
- package/src/framework/env.ts +9 -1
- package/src/index.ts +14 -0
- package/src/lib/alert-email.ts +104 -0
- package/src/lib/alerts-store.test.ts +116 -2
- package/src/lib/alerts-store.ts +421 -57
- package/src/lib/metric-alerts.test.ts +769 -0
- package/src/lib/metric-alerts.ts +640 -0
- package/src/lib/metrics-store.ts +9 -2
- package/src/lib/sql-db-postgres.integration.test.ts +247 -0
- package/src/lib/store/trace-queries.ts +1 -1
- package/src/migrations/054_alert_rules_pending_secs.sql +11 -0
- package/src/migrations/055_alert_state_pending_since.sql +12 -0
- package/src/migrations/056_metric_point_series_received.sql +9 -0
- package/src/migrations/057_alert_evaluations_outcome.sql +11 -0
- package/src/migrations/058_alert_state_pending_seen_at.sql +12 -0
- package/src/migrations/059_alert_evaluations_error.sql +11 -0
- package/src/migrations-postgres/054_alert_rules_pending_secs.sql +7 -0
- package/src/migrations-postgres/055_alert_state_pending_since.sql +6 -0
- package/src/migrations-postgres/056_metric_point_series_received.sql +7 -0
- package/src/migrations-postgres/057_alert_evaluations_outcome.sql +6 -0
- package/src/migrations-postgres/058_alert_state_pending_seen_at.sql +6 -0
- package/src/migrations-postgres/059_alert_evaluations_error.sql +6 -0
- package/src/migrations-postgres/README.md +13 -0
- package/src/plugins/alerts-evaluator-pending.test.ts +322 -0
- package/src/plugins/alerts-evaluator-retention.test.ts +2 -0
- package/src/plugins/alerts-evaluator.test.ts +10 -2
- package/src/plugins/alerts-evaluator.ts +239 -40
- package/src/plugins/alerts-routes.ts +17 -2
package/dist/auth.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import * as hono from 'hono';
|
|
|
2
2
|
import { MiddlewareHandler, Hono, Context } from 'hono';
|
|
3
3
|
import * as hono_types from 'hono/types';
|
|
4
4
|
import * as _obsunified_types from '@obsunified/types';
|
|
5
|
-
import { StoredSpan, TelemetryOverviewOptions, TelemetryOverviewResponse, TelemetryTraceDetailResponse, TelemetryInstrumentationGapsResponse, TelemetryIssueOptions, TelemetryIssueOverviewResponse, TelemetryIssueDetailResponse, UsageEventRecord, UsageOverviewOptions, UsageOverviewResponse, UsageSessionDetailResponse, UsageSessionSummary, AlertRuleInput, AlertRule, AlertStateRow, AlertState, AlertEvaluationsListResponse, AlertComparison, ChangeBlastRadiusResult, ContentionCandidate, ChangeEvent, ChangeEventInput, InvestigationFinding, InvestigationFindingInput, OntologyNode, OntologyEdge, CanonicalNodeIdentity, OntologyGraphResponse, RelationshipCertainty, CausalTriple, IncidentInvestigation, RemediationProposal, EvidenceEntityKind, RemediationProposalInput, JsonValue, EvidenceReference, EvidenceReferenceContract, Project, IngestKey, IngestKeyWithPlaintext } from '@obsunified/types';
|
|
6
|
-
import {
|
|
7
|
-
export { C as COLLECTOR_HOST_MANAGED_ENV_KEYS,
|
|
5
|
+
import { StoredSpan, TelemetryOverviewOptions, TelemetryOverviewResponse, TelemetryTraceDetailResponse, TelemetryInstrumentationGapsResponse, TelemetryIssueOptions, TelemetryIssueOverviewResponse, TelemetryIssueDetailResponse, UsageEventRecord, UsageOverviewOptions, UsageOverviewResponse, UsageSessionDetailResponse, UsageSessionSummary, AlertRuleInput, AlertRule, AlertStateRow, AlertState, AlertEvaluationOutcome, AlertEvaluationsListResponse, AlertComparison, ChangeBlastRadiusResult, ContentionCandidate, ChangeEvent, ChangeEventInput, InvestigationFinding, InvestigationFindingInput, OntologyNode, OntologyEdge, CanonicalNodeIdentity, OntologyGraphResponse, RelationshipCertainty, CausalTriple, IncidentInvestigation, RemediationProposal, EvidenceEntityKind, RemediationProposalInput, JsonValue, EvidenceReference, EvidenceReferenceContract, AlertQueryMetrics, AlertMetricAggregation, AlertMetricField, Project, IngestKey, IngestKeyWithPlaintext } from '@obsunified/types';
|
|
6
|
+
import { g as CollectorEnv, L as Logger, e as ChildSpanRunner, l as CollectorRouteContext, a as AlertEmailTransport } from './ingest-auth-BTowieER.js';
|
|
7
|
+
export { A as AlertEmailMessage, b as AlertNotificationPayload, C as COLLECTOR_HOST_MANAGED_ENV_KEYS, c as COLLECTOR_OPTIONAL_STRING_ENV_KEYS, d as COLLECTOR_STRING_ENV_MANIFEST, f as CollectorApp, h as CollectorHostManagedEnvKey, i as CollectorManifestStringEnvKey, j as CollectorObjectBindingKey, k as CollectorOptionalStringEnvKey, m as CollectorStringEnvKey, n as assertCollectorEnvManifestCompleteness, o as consoleLogger, p as createIngestAuth, q as formatAlertEmail, r as isValidEmailAddress } from './ingest-auth-BTowieER.js';
|
|
8
8
|
import { ActionConfidence } from '@obsunified/types/constants';
|
|
9
9
|
import { Pool } from 'pg';
|
|
10
10
|
|
|
@@ -488,15 +488,178 @@ declare const aiReceiverPlugin: CollectorPlugin;
|
|
|
488
488
|
|
|
489
489
|
declare const aiSpanPayloadsProcessorPlugin: CollectorPlugin;
|
|
490
490
|
|
|
491
|
+
/** A rule's value, and whether a metrics rule found no fresh data. */
|
|
492
|
+
interface AlertRuleEvaluation {
|
|
493
|
+
value: number;
|
|
494
|
+
noData: boolean;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
interface AlertsStoreOptions {
|
|
498
|
+
/** Permit webhook targets on loopback / private / link-local hosts. */
|
|
499
|
+
allowPrivateWebhookTargets?: boolean;
|
|
500
|
+
/**
|
|
501
|
+
* Whether this collector can send email (a transport is bound as
|
|
502
|
+
* `env.ALERT_EMAIL`). Rules with an email channel are refused otherwise.
|
|
503
|
+
*/
|
|
504
|
+
emailDeliveryAvailable?: boolean;
|
|
505
|
+
}
|
|
506
|
+
declare function compareValue(value: number, threshold: number, comparison: AlertComparison): boolean;
|
|
507
|
+
declare class AlertsStore {
|
|
508
|
+
private readonly db;
|
|
509
|
+
private readonly options;
|
|
510
|
+
constructor(db: SqlDb, options?: AlertsStoreOptions);
|
|
511
|
+
validateInput(input: AlertRuleInput): void;
|
|
512
|
+
listRules(projectId: string): Promise<AlertRule[]>;
|
|
513
|
+
/**
|
|
514
|
+
* The newest evaluation of every rule in the project, one query. Falls
|
|
515
|
+
* back to the pre-057/059 column set on older databases.
|
|
516
|
+
*/
|
|
517
|
+
private lastEvaluations;
|
|
518
|
+
getRule(id: string, projectId: string): Promise<AlertRule | null>;
|
|
519
|
+
createRule(projectId: string, input: AlertRuleInput): Promise<AlertRule>;
|
|
520
|
+
updateRule(id: string, projectId: string, patch: Partial<AlertRuleInput>): Promise<AlertRule | null>;
|
|
521
|
+
/**
|
|
522
|
+
* Clears a rule's pending period. Tolerates databases that have not
|
|
523
|
+
* applied 055/058 (there is nothing to clear on them).
|
|
524
|
+
*/
|
|
525
|
+
resetPending(ruleId: string, projectId: string): Promise<void>;
|
|
526
|
+
/**
|
|
527
|
+
* Runs `current`; on a database that has not applied migration 054 (no
|
|
528
|
+
* `alert_rules.pending_secs`) a rule without a pending duration is
|
|
529
|
+
* written with the legacy statement so rolling deploys keep working. A
|
|
530
|
+
* rule that needs the column is refused with a clear message instead of
|
|
531
|
+
* silently losing its pending duration.
|
|
532
|
+
*/
|
|
533
|
+
private withPendingColumnFallback;
|
|
534
|
+
deleteRule(id: string, projectId: string): Promise<boolean>;
|
|
535
|
+
listEnabledRules(): Promise<AlertRule[]>;
|
|
536
|
+
getState(ruleId: string, projectId: string): Promise<AlertStateRow | null>;
|
|
537
|
+
/**
|
|
538
|
+
* Record a state transition with its notification still outstanding
|
|
539
|
+
* (`notified = 0`); `markNotified` flips it once a channel accepts the
|
|
540
|
+
* alert. On a database that has not applied migration 049 the column is
|
|
541
|
+
* missing: the transition is still written (legacy statement) so alerting
|
|
542
|
+
* keeps working through a rolling deploy, and the evaluator treats a row
|
|
543
|
+
* without the column as delivered.
|
|
544
|
+
*/
|
|
545
|
+
transitionState(ruleId: string, projectId: string, newState: AlertState, now: string): Promise<void>;
|
|
546
|
+
/**
|
|
547
|
+
* Mark the transition `(state, lastStateChange)` as delivered. Scoped to
|
|
548
|
+
* the exact transition the caller notified for: if the rule changed state
|
|
549
|
+
* again while the webhook was in flight, the newer transition keeps its
|
|
550
|
+
* own outstanding flag. Returns false when nothing matched (stale or
|
|
551
|
+
* already marked). On a pre-049 schema there is nothing to mark.
|
|
552
|
+
*/
|
|
553
|
+
markNotified(ruleId: string, projectId: string, state: AlertState, lastStateChange: string): Promise<boolean>;
|
|
554
|
+
/**
|
|
555
|
+
* Record (`{ since, seenAt }`) or clear (`null`) the pending period of a
|
|
556
|
+
* rule that has a pending duration (migrations 055, 058): when the
|
|
557
|
+
* condition started holding, and the last evaluation that saw it hold.
|
|
558
|
+
* A rule without a state row gets one in state `ok` since its creation,
|
|
559
|
+
* already delivered (nothing is owed for a rule that never changed
|
|
560
|
+
* state).
|
|
561
|
+
*/
|
|
562
|
+
setPending(ruleId: string, projectId: string, pending: {
|
|
563
|
+
since: string;
|
|
564
|
+
seenAt: string;
|
|
565
|
+
} | null, ruleCreatedAt: string): Promise<void>;
|
|
566
|
+
recordEvaluation(ruleId: string, projectId: string, value: number, state: AlertState, notified: boolean, outcome?: AlertEvaluationOutcome, errorMessage?: string): Promise<void>;
|
|
567
|
+
listEvaluations(params: {
|
|
568
|
+
ruleId: string;
|
|
569
|
+
projectId?: string;
|
|
570
|
+
hours: number;
|
|
571
|
+
limit?: number;
|
|
572
|
+
}): Promise<AlertEvaluationsListResponse>;
|
|
573
|
+
evaluateRule(rule: AlertRule, now?: Date): Promise<number>;
|
|
574
|
+
/** Like `evaluateRule`, plus whether a metrics rule found no fresh data. */
|
|
575
|
+
evaluateRuleWithStatus(rule: AlertRule, now?: Date): Promise<AlertRuleEvaluation>;
|
|
576
|
+
private evaluateCountRule;
|
|
577
|
+
/**
|
|
578
|
+
* Stage 6 — fetch the latest narrative associated with this rule's
|
|
579
|
+
* bound analysis. Used by the evaluator when firing an analysis-bound
|
|
580
|
+
* alert so the webhook payload includes the human-readable
|
|
581
|
+
* narrative, not just a threshold crossing.
|
|
582
|
+
*/
|
|
583
|
+
getAnalysisNarrative(projectId: string, analysisId: string): Promise<{
|
|
584
|
+
narrative: string | null;
|
|
585
|
+
status: string | null;
|
|
586
|
+
} | null>;
|
|
587
|
+
private evaluateSpanRule;
|
|
588
|
+
private evaluateLogRule;
|
|
589
|
+
private evaluateUsageRule;
|
|
590
|
+
private evaluateAIRule;
|
|
591
|
+
}
|
|
592
|
+
|
|
491
593
|
/** Resolve a hostname to its addresses (e.g. `dns.lookup(host, { all: true })`). */
|
|
492
594
|
type HostLookup = (hostname: string) => Promise<string[]>;
|
|
493
595
|
|
|
596
|
+
interface AlertEvaluatorStore {
|
|
597
|
+
listEnabledRules(): Promise<AlertRule[]>;
|
|
598
|
+
evaluateRule(rule: AlertRule): Promise<number>;
|
|
599
|
+
/** Preferred when present: also says whether a metrics rule had no data. */
|
|
600
|
+
evaluateRuleWithStatus?(rule: AlertRule): Promise<AlertRuleEvaluation>;
|
|
601
|
+
getState(ruleId: string, projectId: string): Promise<{
|
|
602
|
+
current_state: AlertState;
|
|
603
|
+
last_state_change: string;
|
|
604
|
+
/** 0 while the transition's notification is owed; absent pre-049 (= delivered). */
|
|
605
|
+
notified?: number;
|
|
606
|
+
/** Start of the current pending period (migration 055); null/absent when not pending. */
|
|
607
|
+
pending_since?: string | null;
|
|
608
|
+
/** Last evaluation that saw the pending condition hold (migration 058). */
|
|
609
|
+
pending_seen_at?: string | null;
|
|
610
|
+
} | null>;
|
|
611
|
+
/** Record (`{ since, seenAt }`) or clear (null) the rule's pending period. */
|
|
612
|
+
setPending(ruleId: string, projectId: string, pending: {
|
|
613
|
+
since: string;
|
|
614
|
+
seenAt: string;
|
|
615
|
+
} | null, ruleCreatedAt: string): Promise<void>;
|
|
616
|
+
/** Flip the exact transition `(state, lastStateChange)` to delivered. */
|
|
617
|
+
markNotified(ruleId: string, projectId: string, state: AlertState, lastStateChange: string): Promise<boolean>;
|
|
618
|
+
getAnalysisNarrative(projectId: string, analysisId: string): Promise<{
|
|
619
|
+
narrative: string | null;
|
|
620
|
+
status: string | null;
|
|
621
|
+
} | null>;
|
|
622
|
+
transitionState(ruleId: string, projectId: string, newState: AlertState, now: string): Promise<void>;
|
|
623
|
+
recordEvaluation(ruleId: string, projectId: string, value: number, state: AlertState, notified: boolean, outcome?: AlertEvaluationOutcome,
|
|
624
|
+
/** With outcome `error`: why (the store sanitizes it). */
|
|
625
|
+
errorMessage?: string): Promise<void>;
|
|
626
|
+
}
|
|
627
|
+
declare function evaluateRuleBatch(store: AlertEvaluatorStore, rules: AlertRule[], options?: {
|
|
628
|
+
logger?: Logger;
|
|
629
|
+
tracer?: ChildSpanRunner;
|
|
630
|
+
concurrency?: number;
|
|
631
|
+
ruleTimeoutMs?: number;
|
|
632
|
+
allowPrivateWebhookTargets?: boolean;
|
|
633
|
+
hostLookup?: HostLookup;
|
|
634
|
+
email?: AlertEmailTransport;
|
|
635
|
+
onAlertFiring?: (rule: AlertRule) => Promise<void>;
|
|
636
|
+
/**
|
|
637
|
+
* Longest gap between two evaluations that still continues a pending
|
|
638
|
+
* hold. Default `DEFAULT_MAX_EVALUATION_GAP_MS` (two 5-minute ticks);
|
|
639
|
+
* pass twice the host's evaluation interval.
|
|
640
|
+
*/
|
|
641
|
+
maxEvaluationGapMs?: number;
|
|
642
|
+
/**
|
|
643
|
+
* ISO start of this collector process. A hold last seen before it
|
|
644
|
+
* starts over, as Prometheus resets `for` on restart. Unset on hosts
|
|
645
|
+
* without a long-lived process (Workers), where the gap rule applies.
|
|
646
|
+
*/
|
|
647
|
+
holdStartedAt?: string;
|
|
648
|
+
}): Promise<{
|
|
649
|
+
evaluated: number;
|
|
650
|
+
fired: number;
|
|
651
|
+
resolved: number;
|
|
652
|
+
/** Notifications for an earlier transition that were delivered on this tick. */
|
|
653
|
+
redelivered: number;
|
|
654
|
+
}>;
|
|
494
655
|
declare function evaluateAllRules(env: CollectorEnv, options?: {
|
|
495
656
|
logger?: Logger;
|
|
496
657
|
tracer?: ChildSpanRunner;
|
|
497
658
|
concurrency?: number;
|
|
498
659
|
ruleTimeoutMs?: number;
|
|
499
660
|
hostLookup?: HostLookup;
|
|
661
|
+
maxEvaluationGapMs?: number;
|
|
662
|
+
holdStartedAt?: string;
|
|
500
663
|
}): Promise<{
|
|
501
664
|
evaluated: number;
|
|
502
665
|
fired: number;
|
|
@@ -1024,64 +1187,6 @@ declare class ActionStore {
|
|
|
1024
1187
|
listArtifactsByAction(projectId: string, actionId: string, limit?: number): Promise<ArtifactRef[]>;
|
|
1025
1188
|
}
|
|
1026
1189
|
|
|
1027
|
-
interface AlertsStoreOptions {
|
|
1028
|
-
/** Permit webhook targets on loopback / private / link-local hosts. */
|
|
1029
|
-
allowPrivateWebhookTargets?: boolean;
|
|
1030
|
-
}
|
|
1031
|
-
declare function compareValue(value: number, threshold: number, comparison: AlertComparison): boolean;
|
|
1032
|
-
declare class AlertsStore {
|
|
1033
|
-
private readonly db;
|
|
1034
|
-
private readonly options;
|
|
1035
|
-
constructor(db: SqlDb, options?: AlertsStoreOptions);
|
|
1036
|
-
validateInput(input: AlertRuleInput): void;
|
|
1037
|
-
listRules(projectId: string): Promise<AlertRule[]>;
|
|
1038
|
-
getRule(id: string, projectId: string): Promise<AlertRule | null>;
|
|
1039
|
-
createRule(projectId: string, input: AlertRuleInput): Promise<AlertRule>;
|
|
1040
|
-
updateRule(id: string, projectId: string, patch: Partial<AlertRuleInput>): Promise<AlertRule | null>;
|
|
1041
|
-
deleteRule(id: string, projectId: string): Promise<boolean>;
|
|
1042
|
-
listEnabledRules(): Promise<AlertRule[]>;
|
|
1043
|
-
getState(ruleId: string, projectId: string): Promise<AlertStateRow | null>;
|
|
1044
|
-
/**
|
|
1045
|
-
* Record a state transition with its notification still outstanding
|
|
1046
|
-
* (`notified = 0`); `markNotified` flips it once a channel accepts the
|
|
1047
|
-
* alert. On a database that has not applied migration 049 the column is
|
|
1048
|
-
* missing: the transition is still written (legacy statement) so alerting
|
|
1049
|
-
* keeps working through a rolling deploy, and the evaluator treats a row
|
|
1050
|
-
* without the column as delivered.
|
|
1051
|
-
*/
|
|
1052
|
-
transitionState(ruleId: string, projectId: string, newState: AlertState, now: string): Promise<void>;
|
|
1053
|
-
/**
|
|
1054
|
-
* Mark the transition `(state, lastStateChange)` as delivered. Scoped to
|
|
1055
|
-
* the exact transition the caller notified for: if the rule changed state
|
|
1056
|
-
* again while the webhook was in flight, the newer transition keeps its
|
|
1057
|
-
* own outstanding flag. Returns false when nothing matched (stale or
|
|
1058
|
-
* already marked). On a pre-049 schema there is nothing to mark.
|
|
1059
|
-
*/
|
|
1060
|
-
markNotified(ruleId: string, projectId: string, state: AlertState, lastStateChange: string): Promise<boolean>;
|
|
1061
|
-
recordEvaluation(ruleId: string, projectId: string, value: number, state: AlertState, notified: boolean): Promise<void>;
|
|
1062
|
-
listEvaluations(params: {
|
|
1063
|
-
ruleId: string;
|
|
1064
|
-
projectId?: string;
|
|
1065
|
-
hours: number;
|
|
1066
|
-
limit?: number;
|
|
1067
|
-
}): Promise<AlertEvaluationsListResponse>;
|
|
1068
|
-
evaluateRule(rule: AlertRule): Promise<number>;
|
|
1069
|
-
/**
|
|
1070
|
-
* Stage 6 — fetch the latest narrative associated with this rule's
|
|
1071
|
-
* bound analysis. Used by the evaluator when firing an analysis-bound
|
|
1072
|
-
* alert so the webhook payload includes the human-readable
|
|
1073
|
-
* narrative, not just a threshold crossing.
|
|
1074
|
-
*/
|
|
1075
|
-
getAnalysisNarrative(projectId: string, analysisId: string): Promise<{
|
|
1076
|
-
narrative: string | null;
|
|
1077
|
-
status: string | null;
|
|
1078
|
-
} | null>;
|
|
1079
|
-
private evaluateSpanRule;
|
|
1080
|
-
private evaluateLogRule;
|
|
1081
|
-
private evaluateUsageRule;
|
|
1082
|
-
private evaluateAIRule;
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
1190
|
declare function recordChangeEvent(db: SqlDb, projectId: string, input: ChangeEventInput): Promise<ChangeEvent>;
|
|
1086
1191
|
declare function listChangeEvents(db: SqlDb, options: {
|
|
1087
1192
|
projectId: string;
|
|
@@ -1698,6 +1803,103 @@ declare class EvalCasesStore {
|
|
|
1698
1803
|
private buildMetadata;
|
|
1699
1804
|
}
|
|
1700
1805
|
|
|
1806
|
+
/**
|
|
1807
|
+
* `metrics` alert signal: validation and evaluation of an
|
|
1808
|
+
* `AlertQueryMetrics` against `metric_series` / `metric_point`.
|
|
1809
|
+
*
|
|
1810
|
+
* Evaluation, per selector (numerator, then the optional denominator):
|
|
1811
|
+
*
|
|
1812
|
+
* 1. Series: `metric_series` rows of the project whose name is one of the
|
|
1813
|
+
* selector's names (and whose `service_name` matches, when given), kept
|
|
1814
|
+
* when every listed data-point / resource attribute equals the rule's
|
|
1815
|
+
* value. Attribute values are compared as strings, so `200` matches a
|
|
1816
|
+
* stored `"200"` and vice versa.
|
|
1817
|
+
* 2. Points: the series' points whose `received_at` (the collector's clock,
|
|
1818
|
+
* as for every other alert signal) is inside the rule window, ordered by
|
|
1819
|
+
* producer time (`ts_ns`). The number read is `field` (`value`, or a
|
|
1820
|
+
* histogram/summary `count` / `sum`); points without it are skipped.
|
|
1821
|
+
* 3. Staleness: for `last`, `min`, `max`, `avg` and `sum` a series takes
|
|
1822
|
+
* part only when its newest point is at most `staleSecs` (default 300)
|
|
1823
|
+
* old, so a series that stopped reporting (a renamed host, a replaced
|
|
1824
|
+
* pod) no longer adds its last value. `increase` / `rate` keep every
|
|
1825
|
+
* series with points in the window: growth that happened is real even
|
|
1826
|
+
* if the series stopped afterwards.
|
|
1827
|
+
* 4. Each series is reduced on its own (`reduceSeries`), and the per-series
|
|
1828
|
+
* results are summed. A series with no usable point adds nothing.
|
|
1829
|
+
*
|
|
1830
|
+
* When no series takes part (in the numerator or the denominator) the
|
|
1831
|
+
* result is "no data": the value is 0 and `noData` is true. The rule's
|
|
1832
|
+
* `noData` policy decides what that means (`zero`: evaluate 0 as usual;
|
|
1833
|
+
* `keep`: leave the alert state as it is).
|
|
1834
|
+
*
|
|
1835
|
+
* `age_seconds` ignores the window: it is the seconds since the newest
|
|
1836
|
+
* `received_at` of any matching series. When no matching series has any
|
|
1837
|
+
* stored point (never reported, or everything aged out of retention) it is
|
|
1838
|
+
* the seconds since the rule was created, a finite number that grows until
|
|
1839
|
+
* the threshold is crossed, so "never reported" fires after the same grace
|
|
1840
|
+
* period as "stopped reporting".
|
|
1841
|
+
*
|
|
1842
|
+
* `age_seconds` is never "no data".
|
|
1843
|
+
*
|
|
1844
|
+
* Ratio: with a `denominator`, value = numerator / denominator when the
|
|
1845
|
+
* denominator is > 0 and >= minDenominator (default 0), else 0.
|
|
1846
|
+
*
|
|
1847
|
+
* Cost bounds: at most `MAX_MATCHED_SERIES` series and `MAX_LOADED_POINTS`
|
|
1848
|
+
* points per selector; past either the evaluation fails with an error (the
|
|
1849
|
+
* evaluator records it as an `error` evaluation) rather than returning a
|
|
1850
|
+
* value computed from part of the data. Metric rule windows are at most
|
|
1851
|
+
* `MAX_METRIC_WINDOW_MINS`.
|
|
1852
|
+
*/
|
|
1853
|
+
|
|
1854
|
+
/** Throws an Error with a user-facing message when `query` is malformed. */
|
|
1855
|
+
declare function validateMetricQuery(query: unknown): void;
|
|
1856
|
+
interface MetricPointSample {
|
|
1857
|
+
tsNs: string;
|
|
1858
|
+
startTsNs: string | null;
|
|
1859
|
+
value: number | null;
|
|
1860
|
+
count: number | null;
|
|
1861
|
+
sum: number | null;
|
|
1862
|
+
receivedAt: string;
|
|
1863
|
+
}
|
|
1864
|
+
interface SeriesReduceOptions {
|
|
1865
|
+
/**
|
|
1866
|
+
* The series has no history before the window (its `metric_series` row
|
|
1867
|
+
* was created inside it): a cumulative counter's first point then counts
|
|
1868
|
+
* as growth from 0 instead of being the baseline.
|
|
1869
|
+
*/
|
|
1870
|
+
bornInWindow?: boolean;
|
|
1871
|
+
aggregation: Exclude<AlertMetricAggregation, "age_seconds">;
|
|
1872
|
+
field: AlertMetricField;
|
|
1873
|
+
/** `metric_series.temporality`: 1 delta, 2 cumulative, null for gauges. */
|
|
1874
|
+
temporality: number | null;
|
|
1875
|
+
/** Start of the window in Unix nanoseconds. */
|
|
1876
|
+
windowStartNs: bigint;
|
|
1877
|
+
windowSecs: number;
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Reduces one series' window points to a number, or null when the series
|
|
1881
|
+
* has no point carrying `field` in the window.
|
|
1882
|
+
*/
|
|
1883
|
+
declare function reduceSeries(points: MetricPointSample[], opts: SeriesReduceOptions): number | null;
|
|
1884
|
+
interface MetricEvalContext {
|
|
1885
|
+
projectId: string;
|
|
1886
|
+
windowMins: number;
|
|
1887
|
+
/** The rule's `createdAt`; the reference for "never reported". */
|
|
1888
|
+
ruleCreatedAt: string;
|
|
1889
|
+
now: Date;
|
|
1890
|
+
/** Staleness bound for gauge-style aggregations; default 300. */
|
|
1891
|
+
staleSecs?: number;
|
|
1892
|
+
/** Point cap per selector; default MAX_LOADED_POINTS (tests lower it). */
|
|
1893
|
+
maxLoadedPoints?: number;
|
|
1894
|
+
}
|
|
1895
|
+
interface MetricEvaluation {
|
|
1896
|
+
value: number;
|
|
1897
|
+
/** No series took part; see the module comment. Never true for age_seconds. */
|
|
1898
|
+
noData: boolean;
|
|
1899
|
+
}
|
|
1900
|
+
/** Evaluates a validated metrics query to a finite number. */
|
|
1901
|
+
declare function evaluateMetricQuery(db: SqlDb, query: AlertQueryMetrics, ctx: MetricEvalContext): Promise<MetricEvaluation>;
|
|
1902
|
+
|
|
1701
1903
|
type MetricType = "gauge" | "sum" | "histogram" | "exp_histogram" | "summary";
|
|
1702
1904
|
/**
|
|
1703
1905
|
* A metric data point normalized for storage. Series-identifying fields
|
|
@@ -1855,4 +2057,4 @@ declare const _default: hono.Hono<{
|
|
|
1855
2057
|
Bindings: CollectorEnv;
|
|
1856
2058
|
}, hono_types.BlankSchema, "/">;
|
|
1857
2059
|
|
|
1858
|
-
export { type ActionGraphPurgeSummary, type ActionGraphRetentionOptions, type ActionRecord, ActionStore, type AgentRunRecord, AlertsStore, type AnalysesRunSummary, type ArtifactRecord, type BlobListOptions, type BlobListResult, type BlobObject, type BlobPutOptions, type BlobStore, BlobStoreToR2Adapter, type CollectorAuthConfig, type CollectorConfig, CollectorEnv, type CollectorPlugin, CollectorRouteContext, CollectorRuntime, CounterfactualVerificationError, D1Adapter, type DashboardAuthConfig, type EvalCase, type EvalCaseInput, type EvalCaseListOptions, type EvalCaseSourceLinks, EvalCaseSourceNotFoundError, type EvalCaseSourceType, EvalCasesStore, type EvalResultRecord, type EvalRun, type EvalRunCandidate, type EvalRunInput, type EvalRunSourceCase, type EvalRunStatus, type EvalRunsListOptions, type HostLookup, Logger, MetricsStore, PostgresAdapter, type PostgresAdapterOptions, type PostgresTypeParserRegistry, ProjectsStore, R2BlobStore, RemediationGateError, type RetentionCleanupSummary, type RetrievalEventRecord, S3BlobStore, type S3BlobStoreOptions, type ScheduledTaskHandler, type SpanProcessorPlugin, type SqlDb, type SqlDbFactory, type SqlStatement, type TailEvent, TailHub, type TailKind, type ToolCallRecord, type UsageEventProcessorPlugin, type WatchdogEvaluationSummary, acquireIncidentLease, actionRetentionCutoff, actionRoutesPlugin, aiReceiverPlugin, aiSpanPayloadsProcessorPlugin, alertsRoutesPlugin, allPlugins, analysesRoutesPlugin, approveRemediationProposal, askRoutesPlugin, autosreRoutesPlugin, botFilterPlugin, claimRemediationGrant, compareValue, completeRemediationProposal, computeChangeBlastRadius, computeTarjanScc, configurePostgresTypeParsers, connectedRoutesPlugin, createAlertEvaluatorHandler, createAnalysesRunHandler, createDashboardAuth, createDefaultCollectorApp, createRetentionCleanupHandler, createTelemetryCollectorApp, dashboardRoutesPlugin, _default as default, defaultSpanEnrichmentPlugin, dispatchIncidentWebhook, evalCasesRoutesPlugin, evaluateAllRules, evaluateRemediationWatchdogs, evidenceRetrievalRoutesPlugin, extractSpanLineageAndTopology, failRemediationProposal, findCrossTraceContention, genAiNormalizerPlugin, getChangeEvent, getIncidentInvestigation, getInvestigationFinding, getOntologyGraph, getRemediationProposal, identityReceiverPlugin, isEvalCaseSourceType, isEvalRunStatus, issueEnrichmentPlugin, issueInsightsPlugin, listChangeEvents, listIncidentInvestigations, listRemediationProposals, loadTraceFaultLocusFromDb, localizeTraceFaultLocus, logsReceiverPlugin, metricsReceiverPlugin, onboardingRoutesPlugin, openOrDeduplicateIncident, otlpReceiverPlugin, platformRoutesPlugin, profileRoutesPlugin, projectsRoutesPlugin, proposeRemediationAction, purgeExpiredActionGraph, queryRoutesPlugin, recordChangeEvent, recordInvestigationFinding, redactionProcessorPlugin, rejectRemediationProposal, replayQueryRoutesPlugin, replayReceiverPlugin, searchInvestigationFindings, tailRoutesPlugin, timelineRoutesPlugin, uaEnrichmentPlugin, upsertOntologyFromSpans, usageNormalizationPlugin, usagePrivacyPlugin, usageQueryRoutesPlugin, usageReceiverPlugin, usersQueryRoutesPlugin, utmEnrichmentPlugin, verifyPairedCounterfactualProof };
|
|
2060
|
+
export { type ActionGraphPurgeSummary, type ActionGraphRetentionOptions, type ActionRecord, ActionStore, type AgentRunRecord, AlertEmailTransport, AlertsStore, type AnalysesRunSummary, type ArtifactRecord, type BlobListOptions, type BlobListResult, type BlobObject, type BlobPutOptions, type BlobStore, BlobStoreToR2Adapter, type CollectorAuthConfig, type CollectorConfig, CollectorEnv, type CollectorPlugin, CollectorRouteContext, CollectorRuntime, CounterfactualVerificationError, D1Adapter, type DashboardAuthConfig, type EvalCase, type EvalCaseInput, type EvalCaseListOptions, type EvalCaseSourceLinks, EvalCaseSourceNotFoundError, type EvalCaseSourceType, EvalCasesStore, type EvalResultRecord, type EvalRun, type EvalRunCandidate, type EvalRunInput, type EvalRunSourceCase, type EvalRunStatus, type EvalRunsListOptions, type HostLookup, Logger, MetricsStore, PostgresAdapter, type PostgresAdapterOptions, type PostgresTypeParserRegistry, ProjectsStore, R2BlobStore, RemediationGateError, type RetentionCleanupSummary, type RetrievalEventRecord, S3BlobStore, type S3BlobStoreOptions, type ScheduledTaskHandler, type SpanProcessorPlugin, type SqlDb, type SqlDbFactory, type SqlStatement, type TailEvent, TailHub, type TailKind, type ToolCallRecord, type UsageEventProcessorPlugin, type WatchdogEvaluationSummary, acquireIncidentLease, actionRetentionCutoff, actionRoutesPlugin, aiReceiverPlugin, aiSpanPayloadsProcessorPlugin, alertsRoutesPlugin, allPlugins, analysesRoutesPlugin, approveRemediationProposal, askRoutesPlugin, autosreRoutesPlugin, botFilterPlugin, claimRemediationGrant, compareValue, completeRemediationProposal, computeChangeBlastRadius, computeTarjanScc, configurePostgresTypeParsers, connectedRoutesPlugin, createAlertEvaluatorHandler, createAnalysesRunHandler, createDashboardAuth, createDefaultCollectorApp, createRetentionCleanupHandler, createTelemetryCollectorApp, dashboardRoutesPlugin, _default as default, defaultSpanEnrichmentPlugin, dispatchIncidentWebhook, evalCasesRoutesPlugin, evaluateAllRules, evaluateMetricQuery, evaluateRemediationWatchdogs, evaluateRuleBatch, evidenceRetrievalRoutesPlugin, extractSpanLineageAndTopology, failRemediationProposal, findCrossTraceContention, genAiNormalizerPlugin, getChangeEvent, getIncidentInvestigation, getInvestigationFinding, getOntologyGraph, getRemediationProposal, identityReceiverPlugin, isEvalCaseSourceType, isEvalRunStatus, issueEnrichmentPlugin, issueInsightsPlugin, listChangeEvents, listIncidentInvestigations, listRemediationProposals, loadTraceFaultLocusFromDb, localizeTraceFaultLocus, logsReceiverPlugin, metricsReceiverPlugin, onboardingRoutesPlugin, openOrDeduplicateIncident, otlpReceiverPlugin, platformRoutesPlugin, profileRoutesPlugin, projectsRoutesPlugin, proposeRemediationAction, purgeExpiredActionGraph, queryRoutesPlugin, recordChangeEvent, recordInvestigationFinding, redactionProcessorPlugin, reduceSeries, rejectRemediationProposal, replayQueryRoutesPlugin, replayReceiverPlugin, searchInvestigationFindings, tailRoutesPlugin, timelineRoutesPlugin, uaEnrichmentPlugin, upsertOntologyFromSpans, usageNormalizationPlugin, usagePrivacyPlugin, usageQueryRoutesPlugin, usageReceiverPlugin, usersQueryRoutesPlugin, utmEnrichmentPlugin, validateMetricQuery, verifyPairedCounterfactualProof };
|