@miragon/pulse-analytics-client 0.0.0-bootstrap.0 → 0.21.0
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/LICENSE +21 -0
- package/README.md +83 -3
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/metric-names.d.ts +43 -0
- package/dist/metric-names.d.ts.map +1 -0
- package/dist/metric-names.js +53 -0
- package/dist/metric-names.js.map +1 -0
- package/dist/metrics-contract-labels.test.d.ts +2 -0
- package/dist/metrics-contract-labels.test.d.ts.map +1 -0
- package/dist/metrics-contract-labels.test.js +169 -0
- package/dist/metrics-contract-labels.test.js.map +1 -0
- package/dist/metrics-contract.test.d.ts +2 -0
- package/dist/metrics-contract.test.d.ts.map +1 -0
- package/dist/metrics-contract.test.js +247 -0
- package/dist/metrics-contract.test.js.map +1 -0
- package/dist/prometheus-client.test.d.ts +2 -0
- package/dist/prometheus-client.test.d.ts.map +1 -0
- package/dist/prometheus-client.test.js +265 -0
- package/dist/prometheus-client.test.js.map +1 -0
- package/dist/prometheus.d.ts +100 -0
- package/dist/prometheus.d.ts.map +1 -0
- package/dist/prometheus.js +295 -0
- package/dist/prometheus.js.map +1 -0
- package/dist/prometheus.test.d.ts +2 -0
- package/dist/prometheus.test.d.ts.map +1 -0
- package/dist/prometheus.test.js +54 -0
- package/dist/prometheus.test.js.map +1 -0
- package/dist/promql-labels.test-support.d.ts +53 -0
- package/dist/promql-labels.test-support.d.ts.map +1 -0
- package/dist/promql-labels.test-support.js +237 -0
- package/dist/promql-labels.test-support.js.map +1 -0
- package/dist/promql-labels.test.d.ts +2 -0
- package/dist/promql-labels.test.d.ts.map +1 -0
- package/dist/promql-labels.test.js +190 -0
- package/dist/promql-labels.test.js.map +1 -0
- package/dist/promql-parse.test-support.d.ts +57 -0
- package/dist/promql-parse.test-support.d.ts.map +1 -0
- package/dist/promql-parse.test-support.js +284 -0
- package/dist/promql-parse.test-support.js.map +1 -0
- package/dist/promql-reading-rules.test-support.d.ts +29 -0
- package/dist/promql-reading-rules.test-support.d.ts.map +1 -0
- package/dist/promql-reading-rules.test-support.js +79 -0
- package/dist/promql-reading-rules.test-support.js.map +1 -0
- package/dist/promql-reading-rules.test.d.ts +2 -0
- package/dist/promql-reading-rules.test.d.ts.map +1 -0
- package/dist/promql-reading-rules.test.js +61 -0
- package/dist/promql-reading-rules.test.js.map +1 -0
- package/dist/promql-sources.test-support.d.ts +29 -0
- package/dist/promql-sources.test-support.d.ts.map +1 -0
- package/dist/promql-sources.test-support.js +112 -0
- package/dist/promql-sources.test-support.js.map +1 -0
- package/dist/promql-sources.test.d.ts +2 -0
- package/dist/promql-sources.test.d.ts.map +1 -0
- package/dist/promql-sources.test.js +93 -0
- package/dist/promql-sources.test.js.map +1 -0
- package/dist/queries/as-of.test.d.ts +2 -0
- package/dist/queries/as-of.test.d.ts.map +1 -0
- package/dist/queries/as-of.test.js +80 -0
- package/dist/queries/as-of.test.js.map +1 -0
- package/dist/queries/cluster-compare.d.ts +62 -0
- package/dist/queries/cluster-compare.d.ts.map +1 -0
- package/dist/queries/cluster-compare.js +70 -0
- package/dist/queries/cluster-compare.js.map +1 -0
- package/dist/queries/cluster-compare.test.d.ts +2 -0
- package/dist/queries/cluster-compare.test.d.ts.map +1 -0
- package/dist/queries/cluster-compare.test.js +81 -0
- package/dist/queries/cluster-compare.test.js.map +1 -0
- package/dist/queries/dashboard.d.ts +60 -0
- package/dist/queries/dashboard.d.ts.map +1 -0
- package/dist/queries/dashboard.js +292 -0
- package/dist/queries/dashboard.js.map +1 -0
- package/dist/queries/dashboard.test.d.ts +2 -0
- package/dist/queries/dashboard.test.d.ts.map +1 -0
- package/dist/queries/dashboard.test.js +423 -0
- package/dist/queries/dashboard.test.js.map +1 -0
- package/dist/queries/element.d.ts +68 -0
- package/dist/queries/element.d.ts.map +1 -0
- package/dist/queries/element.js +98 -0
- package/dist/queries/element.js.map +1 -0
- package/dist/queries/element.test.d.ts +2 -0
- package/dist/queries/element.test.d.ts.map +1 -0
- package/dist/queries/element.test.js +105 -0
- package/dist/queries/element.test.js.map +1 -0
- package/dist/queries/engine-compare.d.ts +52 -0
- package/dist/queries/engine-compare.d.ts.map +1 -0
- package/dist/queries/engine-compare.js +57 -0
- package/dist/queries/engine-compare.js.map +1 -0
- package/dist/queries/engine-compare.test.d.ts +2 -0
- package/dist/queries/engine-compare.test.d.ts.map +1 -0
- package/dist/queries/engine-compare.test.js +159 -0
- package/dist/queries/engine-compare.test.js.map +1 -0
- package/dist/queries/engine-landscape.d.ts +92 -0
- package/dist/queries/engine-landscape.d.ts.map +1 -0
- package/dist/queries/engine-landscape.js +183 -0
- package/dist/queries/engine-landscape.js.map +1 -0
- package/dist/queries/engine-landscape.test.d.ts +2 -0
- package/dist/queries/engine-landscape.test.d.ts.map +1 -0
- package/dist/queries/engine-landscape.test.js +171 -0
- package/dist/queries/engine-landscape.test.js.map +1 -0
- package/dist/queries/failures.d.ts +33 -0
- package/dist/queries/failures.d.ts.map +1 -0
- package/dist/queries/failures.js +31 -0
- package/dist/queries/failures.js.map +1 -0
- package/dist/queries/health.d.ts +77 -0
- package/dist/queries/health.d.ts.map +1 -0
- package/dist/queries/health.js +126 -0
- package/dist/queries/health.js.map +1 -0
- package/dist/queries/health.test.d.ts +2 -0
- package/dist/queries/health.test.d.ts.map +1 -0
- package/dist/queries/health.test.js +187 -0
- package/dist/queries/health.test.js.map +1 -0
- package/dist/queries/helpers.d.ts +184 -0
- package/dist/queries/helpers.d.ts.map +1 -0
- package/dist/queries/helpers.js +219 -0
- package/dist/queries/helpers.js.map +1 -0
- package/dist/queries/helpers.test.d.ts +2 -0
- package/dist/queries/helpers.test.d.ts.map +1 -0
- package/dist/queries/helpers.test.js +53 -0
- package/dist/queries/helpers.test.js.map +1 -0
- package/dist/queries/index.d.ts +19 -0
- package/dist/queries/index.d.ts.map +1 -0
- package/dist/queries/index.js +10 -0
- package/dist/queries/index.js.map +1 -0
- package/dist/queries/performance.d.ts +103 -0
- package/dist/queries/performance.d.ts.map +1 -0
- package/dist/queries/performance.js +173 -0
- package/dist/queries/performance.js.map +1 -0
- package/dist/queries/performance.test.d.ts +2 -0
- package/dist/queries/performance.test.d.ts.map +1 -0
- package/dist/queries/performance.test.js +265 -0
- package/dist/queries/performance.test.js.map +1 -0
- package/dist/queries/version-compare.d.ts +41 -0
- package/dist/queries/version-compare.d.ts.map +1 -0
- package/dist/queries/version-compare.js +44 -0
- package/dist/queries/version-compare.js.map +1 -0
- package/dist/queries/version-compare.test.d.ts +2 -0
- package/dist/queries/version-compare.test.d.ts.map +1 -0
- package/dist/queries/version-compare.test.js +162 -0
- package/dist/queries/version-compare.test.js.map +1 -0
- package/dist/queries/windows.d.ts +40 -0
- package/dist/queries/windows.d.ts.map +1 -0
- package/dist/queries/windows.js +56 -0
- package/dist/queries/windows.js.map +1 -0
- package/dist/query-honesty.test.d.ts +2 -0
- package/dist/query-honesty.test.d.ts.map +1 -0
- package/dist/query-honesty.test.js +294 -0
- package/dist/query-honesty.test.js.map +1 -0
- package/dist/query-scenarios.test-support.d.ts +49 -0
- package/dist/query-scenarios.test-support.d.ts.map +1 -0
- package/dist/query-scenarios.test-support.js +146 -0
- package/dist/query-scenarios.test-support.js.map +1 -0
- package/dist/schemas/cluster-compare.d.ts +11 -0
- package/dist/schemas/cluster-compare.d.ts.map +1 -0
- package/dist/schemas/cluster-compare.js +35 -0
- package/dist/schemas/cluster-compare.js.map +1 -0
- package/dist/schemas/engine-compare.d.ts +10 -0
- package/dist/schemas/engine-compare.d.ts.map +1 -0
- package/dist/schemas/engine-compare.js +27 -0
- package/dist/schemas/engine-compare.js.map +1 -0
- package/dist/schemas/engine-landscape.d.ts +5 -0
- package/dist/schemas/engine-landscape.d.ts.map +1 -0
- package/dist/schemas/engine-landscape.js +8 -0
- package/dist/schemas/engine-landscape.js.map +1 -0
- package/dist/schemas/failures.d.ts +8 -0
- package/dist/schemas/failures.d.ts.map +1 -0
- package/dist/schemas/failures.js +9 -0
- package/dist/schemas/failures.js.map +1 -0
- package/dist/schemas/health.d.ts +5 -0
- package/dist/schemas/health.d.ts.map +1 -0
- package/dist/schemas/health.js +6 -0
- package/dist/schemas/health.js.map +1 -0
- package/dist/schemas/index.d.ts +10 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +10 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/path.d.ts +15 -0
- package/dist/schemas/path.d.ts.map +1 -0
- package/dist/schemas/path.js +21 -0
- package/dist/schemas/path.js.map +1 -0
- package/dist/schemas/performance.d.ts +23 -0
- package/dist/schemas/performance.d.ts.map +1 -0
- package/dist/schemas/performance.js +21 -0
- package/dist/schemas/performance.js.map +1 -0
- package/dist/schemas/shared.d.ts +34 -0
- package/dist/schemas/shared.d.ts.map +1 -0
- package/dist/schemas/shared.js +34 -0
- package/dist/schemas/shared.js.map +1 -0
- package/dist/schemas/version-compare.d.ts +10 -0
- package/dist/schemas/version-compare.d.ts.map +1 -0
- package/dist/schemas/version-compare.js +25 -0
- package/dist/schemas/version-compare.js.map +1 -0
- package/dist/widgets.d.ts +138 -0
- package/dist/widgets.d.ts.map +1 -0
- package/dist/widgets.js +2 -0
- package/dist/widgets.js.map +1 -0
- package/metrics-contract.json +174 -0
- package/package.json +72 -5
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { engineIdsOf, engineMatcher, selector, } from "../prometheus.js";
|
|
2
|
+
import { METRIC_NAMES as M } from "../metric-names.js";
|
|
3
|
+
import { engineState, reportingEnginesQuery } from "./helpers.js";
|
|
4
|
+
/**
|
|
5
|
+
* Name pattern (RE2) of the alert rules this module ships
|
|
6
|
+
* (`playground/docker/prometheus/alerts.yml`). An alert WITHOUT an
|
|
7
|
+
* `engine_id` label — a pipeline-level rule such as `CibSevenEngineNoMetrics`
|
|
8
|
+
* — only counts when it matches this pattern: in a shared Prometheus every
|
|
9
|
+
* other engine-less alert belongs to somebody else.
|
|
10
|
+
*/
|
|
11
|
+
export const ENGINE_ALERT_NAME_PATTERN = "CibSeven.+";
|
|
12
|
+
/**
|
|
13
|
+
* How {@link engineHealth} decides `status`, in words — carried in every
|
|
14
|
+
* result (`statusRule`) and the tool description, so no reader mistakes this
|
|
15
|
+
* alert-based verdict for camunda7_show_engine_health's incident-count one:
|
|
16
|
+
* the two judge different data by different rules and may disagree for the
|
|
17
|
+
* same engine (500 open incidents without a firing critical alert stay
|
|
18
|
+
* "degraded" here).
|
|
19
|
+
*/
|
|
20
|
+
export const ENGINE_HEALTH_STATUS_RULE = "From Prometheus, over the engines in scope: unknown when none of them reports metrics; critical only while a severity=critical alert fires for them (fleet-wide also an engine-less CibSeven* alert); degraded with any such firing alert, dead job, open incident or an engine in scope that reports nothing; else healthy.";
|
|
21
|
+
const first = (s) => (s.length ? Math.round(s[0].value) : 0);
|
|
22
|
+
const total = (s) => Math.round(s.reduce((sum, x) => sum + x.value, 0));
|
|
23
|
+
function counts(samples, label) {
|
|
24
|
+
return samples
|
|
25
|
+
.map((s) => ({ label: s.metric[label] ?? "", count: Math.round(s.value) }))
|
|
26
|
+
.filter((c) => c.count !== 0)
|
|
27
|
+
.sort((a, b) => b.count - a.count);
|
|
28
|
+
}
|
|
29
|
+
function alerts(samples) {
|
|
30
|
+
return samples.map((s) => ({
|
|
31
|
+
name: s.metric.alertname ?? "",
|
|
32
|
+
severity: s.metric.severity ?? "",
|
|
33
|
+
scope: s.metric.process_definition_key ?? s.metric.incident_type ?? s.metric.engine_id ?? "",
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The `ALERTS` selection for one alert state. With an engine scope: the
|
|
38
|
+
* alerts carrying one of its `engine_id`s, plus — only for a fleet-wide
|
|
39
|
+
* verdict — this module's engine-less rules. Without one: this module's
|
|
40
|
+
* rules only.
|
|
41
|
+
*/
|
|
42
|
+
function alertsQuery(state, engine, includeFleetAlerts) {
|
|
43
|
+
const own = `alertname=~"${ENGINE_ALERT_NAME_PATTERN}"`;
|
|
44
|
+
const stateMatcher = `alertstate="${state}"`;
|
|
45
|
+
const engineSel = engineMatcher(engine);
|
|
46
|
+
if (!engineSel)
|
|
47
|
+
return `ALERTS${selector(stateMatcher, own)}`;
|
|
48
|
+
const scoped = `ALERTS${selector(stateMatcher, engineSel)}`;
|
|
49
|
+
return includeFleetAlerts
|
|
50
|
+
? `${scoped} or ALERTS${selector(stateMatcher, own, `engine_id=""`)}`
|
|
51
|
+
: scoped;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Live operational health of the engine(s), from the point-in-time gauges plus
|
|
55
|
+
* Prometheus' own `ALERTS` series. A one-call ops snapshot: running WIP, open
|
|
56
|
+
* incidents, dead jobs, job/task/external-task backlog, and which alert rules
|
|
57
|
+
* are firing/pending.
|
|
58
|
+
*
|
|
59
|
+
* Absence is not health: the engine-only gauges (`jobs_executable`,
|
|
60
|
+
* `external_tasks_open`) double as the presence probe, so an engine that
|
|
61
|
+
* sends nothing — or an id that matches no series — reads `unknown` (none in
|
|
62
|
+
* scope reports) or lands in `silentEngines` (degrading the verdict), never
|
|
63
|
+
* `healthy`. `includeFleetAlerts` (default: exactly when `engine` is
|
|
64
|
+
* omitted) adds the module's engine-less alerts — set it when `engine` lists
|
|
65
|
+
* the whole configured fleet.
|
|
66
|
+
*/
|
|
67
|
+
export async function engineHealth(ch, params) {
|
|
68
|
+
const sel = selector(engineMatcher(params.engine));
|
|
69
|
+
const fleet = params.includeFleetAlerts ?? engineIdsOf(params.engine) === null;
|
|
70
|
+
const [runningByDef, incidentsByType, deadJobs, executableByEngine, suspendedJobs, openTasks, unassignedTasks, externalByEngine, deployedKeys, firing, pending,] = await Promise.all([
|
|
71
|
+
ch.instant(`sum by (process_definition_key)(${engineState(M.processInstancesRunning, sel)})`),
|
|
72
|
+
ch.instant(`sum by (incident_type)(${engineState(M.incidentsOpen, sel)})`),
|
|
73
|
+
ch.instant(`sum(${engineState(M.jobsFailed, sel)})`),
|
|
74
|
+
ch.instant(reportingEnginesQuery(sel)),
|
|
75
|
+
ch.instant(`sum(${engineState(M.jobsSuspended, sel)})`),
|
|
76
|
+
ch.instant(`sum(${engineState(M.userTasksOpen, selector(`status="total"`, engineMatcher(params.engine)))})`),
|
|
77
|
+
ch.instant(`sum(${engineState(M.userTasksOpen, selector(`status="unassigned"`, engineMatcher(params.engine)))})`),
|
|
78
|
+
ch.instant(engineState(M.externalTasksOpen, sel)),
|
|
79
|
+
// Distinct keys, not series: a key deployed on two engines counts once.
|
|
80
|
+
ch.instant(`count(count by (process_definition_key)(${engineState(M.processDefinitionsDeployed, sel)}))`),
|
|
81
|
+
ch.instant(alertsQuery("firing", params.engine, fleet)),
|
|
82
|
+
ch.instant(alertsQuery("pending", params.engine, fleet)),
|
|
83
|
+
]);
|
|
84
|
+
const runningByDefinition = counts(runningByDef, "process_definition_key");
|
|
85
|
+
const openIncidentsByType = counts(incidentsByType, "incident_type");
|
|
86
|
+
const firingAlerts = alerts(firing);
|
|
87
|
+
const pendingAlerts = alerts(pending);
|
|
88
|
+
const openIncidents = openIncidentsByType.reduce((s, c) => s + c.count, 0);
|
|
89
|
+
const runningInstances = runningByDefinition.reduce((s, c) => s + c.count, 0);
|
|
90
|
+
const dead = first(deadJobs);
|
|
91
|
+
const engines = engineIdsOf(params.engine);
|
|
92
|
+
const reportingEngines = [
|
|
93
|
+
...new Set([...executableByEngine, ...externalByEngine]
|
|
94
|
+
.map((s) => s.metric.engine_id)
|
|
95
|
+
.filter((id) => !!id)),
|
|
96
|
+
].sort();
|
|
97
|
+
const silentEngines = (engines ?? []).filter((id) => !reportingEngines.includes(id));
|
|
98
|
+
const status = reportingEngines.length === 0
|
|
99
|
+
? "unknown"
|
|
100
|
+
: firingAlerts.some((a) => a.severity === "critical")
|
|
101
|
+
? "critical"
|
|
102
|
+
: firingAlerts.length > 0 || dead > 0 || openIncidents > 0 || silentEngines.length > 0
|
|
103
|
+
? "degraded"
|
|
104
|
+
: "healthy";
|
|
105
|
+
return {
|
|
106
|
+
status,
|
|
107
|
+
statusRule: ENGINE_HEALTH_STATUS_RULE,
|
|
108
|
+
engines,
|
|
109
|
+
reportingEngines,
|
|
110
|
+
silentEngines,
|
|
111
|
+
runningInstances,
|
|
112
|
+
runningByDefinition,
|
|
113
|
+
openIncidents,
|
|
114
|
+
openIncidentsByType,
|
|
115
|
+
deadJobs: dead,
|
|
116
|
+
executableJobs: total(executableByEngine),
|
|
117
|
+
suspendedJobs: first(suspendedJobs),
|
|
118
|
+
openUserTasks: first(openTasks),
|
|
119
|
+
unassignedUserTasks: first(unassignedTasks),
|
|
120
|
+
openExternalTasks: total(externalByEngine),
|
|
121
|
+
deployedDefinitionKeys: first(deployedKeys),
|
|
122
|
+
firingAlerts,
|
|
123
|
+
pendingAlerts,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/queries/health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.test.d.ts","sourceRoot":"","sources":["../../src/queries/health.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { ENGINE_HEALTH_STATUS_RULE, engineHealth } from "./health.js";
|
|
3
|
+
const sample = (metric, value) => ({ metric, value });
|
|
4
|
+
/** Answers each gauge by its metric name; ALERTS by its alertstate. */
|
|
5
|
+
function mockClient(fixture = {}) {
|
|
6
|
+
const scalar = (value) => (value === undefined ? [] : [sample({}, value)]);
|
|
7
|
+
const perEngine = (value) => (fixture.reporting ?? ["prod-a"]).map((engine_id) => sample({ engine_id }, value));
|
|
8
|
+
const instant = vi.fn(async (q) => {
|
|
9
|
+
if (q.startsWith("ALERTS")) {
|
|
10
|
+
return (q.includes('"firing"') ? fixture.firing : fixture.pending) ?? [];
|
|
11
|
+
}
|
|
12
|
+
if (q.includes("process_instances_running"))
|
|
13
|
+
return fixture.running ?? [];
|
|
14
|
+
if (q.includes("incidents_open"))
|
|
15
|
+
return fixture.incidents ?? [];
|
|
16
|
+
if (q.includes("jobs_failed"))
|
|
17
|
+
return scalar(fixture.dead);
|
|
18
|
+
if (q.includes("jobs_executable"))
|
|
19
|
+
return perEngine(6.2);
|
|
20
|
+
if (q.includes("jobs_suspended"))
|
|
21
|
+
return scalar(2);
|
|
22
|
+
if (q.includes('status="total"'))
|
|
23
|
+
return scalar(9);
|
|
24
|
+
if (q.includes('status="unassigned"'))
|
|
25
|
+
return scalar(4);
|
|
26
|
+
if (q.includes("external_tasks_open"))
|
|
27
|
+
return perEngine(3.3);
|
|
28
|
+
if (q.includes("process_definitions_deployed"))
|
|
29
|
+
return scalar(3);
|
|
30
|
+
return [];
|
|
31
|
+
});
|
|
32
|
+
const ch = { instant };
|
|
33
|
+
return { ch, instant };
|
|
34
|
+
}
|
|
35
|
+
const alert = (alertname, severity, scope = {}) => sample({ alertname, severity, ...scope }, 1);
|
|
36
|
+
describe("engineHealth snapshot", () => {
|
|
37
|
+
it("reports every gauge, rounded, with breakdowns sorted and zero rows dropped", async () => {
|
|
38
|
+
const { ch } = mockClient({
|
|
39
|
+
reporting: ["prod-a", "prod-b"],
|
|
40
|
+
running: [
|
|
41
|
+
sample({ process_definition_key: "invoice" }, 2),
|
|
42
|
+
sample({ process_definition_key: "order" }, 7.4),
|
|
43
|
+
sample({ process_definition_key: "idle" }, 0.2),
|
|
44
|
+
sample({}, 1),
|
|
45
|
+
],
|
|
46
|
+
incidents: [sample({ incident_type: "failedJob" }, 3)],
|
|
47
|
+
dead: 1.6,
|
|
48
|
+
});
|
|
49
|
+
const result = await engineHealth(ch, {});
|
|
50
|
+
expect(result).toMatchObject({
|
|
51
|
+
engines: null,
|
|
52
|
+
reportingEngines: ["prod-a", "prod-b"],
|
|
53
|
+
silentEngines: [],
|
|
54
|
+
runningInstances: 10,
|
|
55
|
+
runningByDefinition: [
|
|
56
|
+
{ label: "order", count: 7 },
|
|
57
|
+
{ label: "invoice", count: 2 },
|
|
58
|
+
{ label: "", count: 1 },
|
|
59
|
+
],
|
|
60
|
+
openIncidents: 3,
|
|
61
|
+
openIncidentsByType: [{ label: "failedJob", count: 3 }],
|
|
62
|
+
deadJobs: 2,
|
|
63
|
+
// Summed across the reporting engines.
|
|
64
|
+
executableJobs: 12,
|
|
65
|
+
suspendedJobs: 2,
|
|
66
|
+
openUserTasks: 9,
|
|
67
|
+
unassignedUserTasks: 4,
|
|
68
|
+
openExternalTasks: 7,
|
|
69
|
+
deployedDefinitionKeys: 3,
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it("names each alert's scope by process, else incident type, else engine", async () => {
|
|
73
|
+
const { ch } = mockClient({
|
|
74
|
+
firing: [
|
|
75
|
+
alert("A", "warning", { process_definition_key: "order", incident_type: "x" }),
|
|
76
|
+
alert("B", "warning", { incident_type: "failedJob", engine_id: "prod-a" }),
|
|
77
|
+
alert("C", "warning", { engine_id: "prod-a" }),
|
|
78
|
+
sample({}, 1),
|
|
79
|
+
],
|
|
80
|
+
pending: [alert("D", "info")],
|
|
81
|
+
});
|
|
82
|
+
const result = await engineHealth(ch, {});
|
|
83
|
+
expect(result.firingAlerts).toEqual([
|
|
84
|
+
{ name: "A", severity: "warning", scope: "order" },
|
|
85
|
+
{ name: "B", severity: "warning", scope: "failedJob" },
|
|
86
|
+
{ name: "C", severity: "warning", scope: "prod-a" },
|
|
87
|
+
{ name: "", severity: "", scope: "" },
|
|
88
|
+
]);
|
|
89
|
+
expect(result.pendingAlerts).toEqual([{ name: "D", severity: "info", scope: "" }]);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* #340: the verdict is alert-based and says so — the same engine may be
|
|
94
|
+
* "critical" in camunda7_show_engine_health (incident counts) and only
|
|
95
|
+
* "degraded" here. #336: silence is not health.
|
|
96
|
+
*/
|
|
97
|
+
describe("engineHealth verdict", () => {
|
|
98
|
+
it.each([
|
|
99
|
+
["a reporting engine without any signal", {}, "healthy"],
|
|
100
|
+
["one open incident", { incidents: [sample({ incident_type: "failedJob" }, 1)] }, "degraded"],
|
|
101
|
+
["one dead job", { dead: 1 }, "degraded"],
|
|
102
|
+
["a firing warning", { firing: [alert("Slow", "warning")] }, "degraded"],
|
|
103
|
+
["a firing critical alert", { firing: [alert("NoMetrics", "critical")] }, "critical"],
|
|
104
|
+
["a merely PENDING critical alert", { pending: [alert("NoMetrics", "critical")] }, "healthy"],
|
|
105
|
+
[
|
|
106
|
+
"500 open incidents without a critical alert",
|
|
107
|
+
{ incidents: [sample({ incident_type: "failedJob" }, 500)] },
|
|
108
|
+
"degraded",
|
|
109
|
+
],
|
|
110
|
+
["no engine reporting any metric", { reporting: [] }, "unknown"],
|
|
111
|
+
[
|
|
112
|
+
"no engine reporting, even with a critical alert firing",
|
|
113
|
+
{ reporting: [], firing: [alert("CibSevenEngineNoMetrics", "critical")] },
|
|
114
|
+
"unknown",
|
|
115
|
+
],
|
|
116
|
+
])("%s → %s", async (_label, fixture, status) => {
|
|
117
|
+
const result = await engineHealth(mockClient(fixture).ch, {});
|
|
118
|
+
expect(result.status).toBe(status);
|
|
119
|
+
expect(result.statusRule).toBe(ENGINE_HEALTH_STATUS_RULE);
|
|
120
|
+
});
|
|
121
|
+
it("reads an engine that sends nothing — or a mistyped id — as unknown, never healthy (N76)", async () => {
|
|
122
|
+
const { ch } = mockClient({ reporting: [] });
|
|
123
|
+
const result = await engineHealth(ch, { engine: "prod-b" });
|
|
124
|
+
expect(result).toMatchObject({
|
|
125
|
+
status: "unknown",
|
|
126
|
+
engines: ["prod-b"],
|
|
127
|
+
reportingEngines: [],
|
|
128
|
+
silentEngines: ["prod-b"],
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
it("degrades a scope in which one engine is silent", async () => {
|
|
132
|
+
const { ch } = mockClient({ reporting: ["prod-a"] });
|
|
133
|
+
const result = await engineHealth(ch, { engine: ["prod-a", "prod-b"] });
|
|
134
|
+
expect(result).toMatchObject({
|
|
135
|
+
status: "degraded",
|
|
136
|
+
reportingEngines: ["prod-a"],
|
|
137
|
+
silentEngines: ["prod-b"],
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
it("states its rule in words", () => {
|
|
141
|
+
expect(ENGINE_HEALTH_STATUS_RULE).toBe("From Prometheus, over the engines in scope: unknown when none of them reports metrics; critical only while a severity=critical alert fires for them (fleet-wide also an engine-less CibSeven* alert); degraded with any such firing alert, dead job, open incident or an engine in scope that reports nothing; else healthy.");
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe("engineHealth PromQL", () => {
|
|
145
|
+
it("scopes every gauge and the ALERTS series to the engine filter", async () => {
|
|
146
|
+
const { ch, instant } = mockClient();
|
|
147
|
+
await engineHealth(ch, { engine: "prod-a" });
|
|
148
|
+
const sel = '{engine_id="prod-a"}';
|
|
149
|
+
// Every gauge folded over its own labels first: a clustered engine's nodes
|
|
150
|
+
// report the same engine-wide rows.
|
|
151
|
+
const perKey = "max by (process_definition_key, engine_id)";
|
|
152
|
+
expect(instant.mock.calls.map(([q]) => q)).toEqual([
|
|
153
|
+
`sum by (process_definition_key)(${perKey}(camunda_process_instances_running${sel}))`,
|
|
154
|
+
`sum by (incident_type)(max by (process_definition_key, incident_type, engine_id)(camunda_incidents_open${sel}))`,
|
|
155
|
+
`sum(${perKey}(camunda_jobs_failed${sel}))`,
|
|
156
|
+
`max by (engine_id)(camunda_jobs_executable${sel})`,
|
|
157
|
+
`sum(max by (engine_id)(camunda_jobs_suspended${sel}))`,
|
|
158
|
+
`sum(max by (status, engine_id)(camunda_usertasks_open{status="total",engine_id="prod-a"}))`,
|
|
159
|
+
`sum(max by (status, engine_id)(camunda_usertasks_open{status="unassigned",engine_id="prod-a"}))`,
|
|
160
|
+
`max by (engine_id)(camunda_external_tasks_open${sel})`,
|
|
161
|
+
`count(count by (process_definition_key)(${perKey}(camunda_process_definitions_deployed${sel})))`,
|
|
162
|
+
// One engine named: only alerts carrying its engine_id — an unrelated
|
|
163
|
+
// alert in a shared Prometheus cannot turn its verdict critical.
|
|
164
|
+
`ALERTS{alertstate="firing",engine_id="prod-a"}`,
|
|
165
|
+
`ALERTS{alertstate="pending",engine_id="prod-a"}`,
|
|
166
|
+
]);
|
|
167
|
+
});
|
|
168
|
+
it("adds the module's engine-less alerts only for the whole fleet", async () => {
|
|
169
|
+
const { ch, instant } = mockClient();
|
|
170
|
+
await engineHealth(ch, { engine: ["prod-a", "prod-b"], includeFleetAlerts: true });
|
|
171
|
+
const alertQueries = instant.mock.calls.map(([q]) => q).filter((q) => q.startsWith("ALERTS"));
|
|
172
|
+
expect(alertQueries).toEqual([
|
|
173
|
+
'ALERTS{alertstate="firing",engine_id=~"prod-a|prod-b"} or ALERTS{alertstate="firing",alertname=~"CibSeven.+",engine_id=""}',
|
|
174
|
+
'ALERTS{alertstate="pending",engine_id=~"prod-a|prod-b"} or ALERTS{alertstate="pending",alertname=~"CibSeven.+",engine_id=""}',
|
|
175
|
+
]);
|
|
176
|
+
});
|
|
177
|
+
it("reads only the module's own rules when unscoped — never a shared Prometheus' foreign alerts", async () => {
|
|
178
|
+
const { ch, instant } = mockClient();
|
|
179
|
+
await engineHealth(ch, {});
|
|
180
|
+
const alertQueries = instant.mock.calls.map(([q]) => q).filter((q) => q.startsWith("ALERTS"));
|
|
181
|
+
expect(alertQueries).toEqual([
|
|
182
|
+
'ALERTS{alertstate="firing",alertname=~"CibSeven.+"}',
|
|
183
|
+
'ALERTS{alertstate="pending",alertname=~"CibSeven.+"}',
|
|
184
|
+
]);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=health.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.test.js","sourceRoot":"","sources":["../../src/queries/health.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type { PrometheusClient, PromSample } from "../prometheus.js";
|
|
2
|
+
import { type GaugeName } from "../metric-names.js";
|
|
3
|
+
import { type CountWindow } from "./windows.js";
|
|
4
|
+
/** Round to one decimal place (KPI seconds / percentages). */
|
|
5
|
+
export declare const round1: (n: number) => number;
|
|
6
|
+
/** Milliseconds (the duration histograms' unit) as seconds, one decimal. */
|
|
7
|
+
export declare const secondsOf: (ms: number) => number;
|
|
8
|
+
/** {@link secondsOf} that passes `null` (not measured) through. */
|
|
9
|
+
export declare const secondsOrNull: (ms: number | null) => number | null;
|
|
10
|
+
/**
|
|
11
|
+
* What a counter or histogram series recorded inside `w`, per series — the
|
|
12
|
+
* ONE way every query reads a counter (contract rule 2). The plugin creates a
|
|
13
|
+
* series on its first event, and `increase()` never counts a series' first
|
|
14
|
+
* sample: a rare event such as the first incident of a type at an activity
|
|
15
|
+
* would read 0. So a series that existed before the window counts its
|
|
16
|
+
* `increase()`, and a series born inside it counts its whole value.
|
|
17
|
+
* `series` is a metric name plus its selector, e.g. `camunda_x{engine_id="a"}`.
|
|
18
|
+
*
|
|
19
|
+
* The check looks at the hour before the window. Where that hour lies past
|
|
20
|
+
* the retention (the 30-day period), Prometheus has deleted it and every
|
|
21
|
+
* series would pass for new, counting its whole history; there it looks at
|
|
22
|
+
* the window's own first hour instead: a series silent then was born later.
|
|
23
|
+
* Only a window of an hour or less at the retention edge has no hour to look
|
|
24
|
+
* at and reads plain `increase()`, which can miss a series' first sample but
|
|
25
|
+
* never counts what happened before the window.
|
|
26
|
+
*/
|
|
27
|
+
export declare function increaseIn(series: string, w: CountWindow): string;
|
|
28
|
+
/**
|
|
29
|
+
* An engine-state gauge with one row per engine-wide figure (contract rule 3):
|
|
30
|
+
* every node of a clustered engine reports the same rows, so the nodes are
|
|
31
|
+
* folded with `max` over the gauge's contract labels before anything sums them.
|
|
32
|
+
*/
|
|
33
|
+
export declare const engineState: (gauge: GaugeName, sel: string) => string;
|
|
34
|
+
/**
|
|
35
|
+
* Parse an ISO datetime into epoch seconds. Throws a caller-readable error
|
|
36
|
+
* instead of letting a NaN reach PromQL as `[NaNs] @ NaN` (Prometheus would
|
|
37
|
+
* answer with an opaque parse error).
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseIsoSeconds(value: string, field: string): number;
|
|
40
|
+
/**
|
|
41
|
+
* Value of the first sample, or 0 when the query returned no series — for
|
|
42
|
+
* COUNTS (`sum(increase(…))`), where "no series in the window" means nothing
|
|
43
|
+
* happened. Never use it for a duration or a gauge: there a missing series is
|
|
44
|
+
* "not measured", see {@link firstOrNull}.
|
|
45
|
+
*/
|
|
46
|
+
export declare const first: (s: PromSample[]) => number;
|
|
47
|
+
/**
|
|
48
|
+
* Value of the first sample, or `null` when the query returned none — for
|
|
49
|
+
* durations and live gauges. A duration over an empty window is NaN
|
|
50
|
+
* (`0 / 0`, `histogram_quantile` over all-zero buckets), which the client
|
|
51
|
+
* drops, so "nothing ended in the window" lands here as `null`, never as a
|
|
52
|
+
* plausible 0 s. A per-key gauge without a series is 0 while the engines
|
|
53
|
+
* report and "not reported" only while they do not — decide that with
|
|
54
|
+
* {@link reportingEnginesQuery}, never from the gauge's own series.
|
|
55
|
+
*/
|
|
56
|
+
export declare const firstOrNull: (s: PromSample[]) => number | null;
|
|
57
|
+
/**
|
|
58
|
+
* The engine-state presence probe — one series per engine in scope that
|
|
59
|
+
* reports its state gauges. `camunda_jobs_executable` carries `engine_id`
|
|
60
|
+
* only and is registered on every tick, 0 included; the per-key gauges are
|
|
61
|
+
* not: the metrics plugin registers a row only for what exists (no incident
|
|
62
|
+
* open → no `camunda_incidents_open` series at all). So a per-key gauge
|
|
63
|
+
* without a series is a measured 0 while this probe answers, and "not
|
|
64
|
+
* reported" only while it does not. `engineSel` must hold the engine matcher
|
|
65
|
+
* alone — the gauge has no other label to match.
|
|
66
|
+
*/
|
|
67
|
+
export declare const reportingEnginesQuery: (engineSel: string) => string;
|
|
68
|
+
/** The engine ids the {@link reportingEnginesQuery} probe answered for, ascending. */
|
|
69
|
+
export declare const reportingEngineIds: (samples: PromSample[]) => string[];
|
|
70
|
+
/** The as-of stamp of a result: now, as an ISO timestamp (the instant queries evaluate at now). */
|
|
71
|
+
export declare const asOfNow: () => string;
|
|
72
|
+
/**
|
|
73
|
+
* Index sample values by one label, dropping samples that miss the label.
|
|
74
|
+
* The last sample wins on duplicate label values.
|
|
75
|
+
*/
|
|
76
|
+
export declare function byLabel(samples: PromSample[], label: string): Record<string, number>;
|
|
77
|
+
/**
|
|
78
|
+
* `part` per 100 of `base`, one decimal — `null` when `base` is 0 (a rate of
|
|
79
|
+
* nothing is undefined, not 0 %). Incident rates divide incidents by
|
|
80
|
+
* instances; one instance can carry several incidents, so they may exceed 100.
|
|
81
|
+
*/
|
|
82
|
+
export declare function ratePct(part: number, base: number): number | null;
|
|
83
|
+
/**
|
|
84
|
+
* Percentage change from `before` to `after`, rounded to two decimals. `null`
|
|
85
|
+
* when either side is not measured or the baseline is 0 — never a −100 % from
|
|
86
|
+
* a missing value or a division by zero.
|
|
87
|
+
*/
|
|
88
|
+
export declare function pctChange(before: number | null, after: number | null): number | null;
|
|
89
|
+
/** Percentage-point difference of two rates; `null` when either is not measured. */
|
|
90
|
+
export declare function ppDelta(before: number | null, after: number | null): number | null;
|
|
91
|
+
/** Label selectors scoping one KPI partition (a window, an engine, a version …). */
|
|
92
|
+
export interface KpiScope {
|
|
93
|
+
/** Base selector: instance starts, incidents and durations. */
|
|
94
|
+
sel: string;
|
|
95
|
+
/** Base selector additionally matching `state="COMPLETED"` (completed count). */
|
|
96
|
+
completedSel: string;
|
|
97
|
+
/**
|
|
98
|
+
* Selector for the element-scoped incident count — the base selector
|
|
99
|
+
* narrowed to one `activity_id`. Absent: no element scope, no element query.
|
|
100
|
+
*/
|
|
101
|
+
elementIncidentSel?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The shared instance-KPI PromQL block used by the dashboard, performance and
|
|
105
|
+
* compare modules: counts via {@link increaseIn} over the window, durations
|
|
106
|
+
* from the histogram (`histogram_quantile` for p50/p95, sum/count for the
|
|
107
|
+
* mean), in MILLISECONDS — the histogram's unit; callers convert. Callers pick
|
|
108
|
+
* the strings they need.
|
|
109
|
+
*
|
|
110
|
+
* The duration histogram is recorded when an instance ENDS (any end state), so
|
|
111
|
+
* every duration covers the instances that ended inside the window only —
|
|
112
|
+
* still-running long instances are not in it (survivorship), and an empty
|
|
113
|
+
* window yields no value at all.
|
|
114
|
+
*/
|
|
115
|
+
export declare function kpiQueries(scope: KpiScope, w: CountWindow): {
|
|
116
|
+
started: string;
|
|
117
|
+
completed: string;
|
|
118
|
+
incidents: string;
|
|
119
|
+
avgDuration: string;
|
|
120
|
+
medianDuration: string;
|
|
121
|
+
p95Duration: string;
|
|
122
|
+
};
|
|
123
|
+
/** The KPI core every compare module reports per partition. */
|
|
124
|
+
export interface CompareKpis {
|
|
125
|
+
/** Process instances STARTED in the window. */
|
|
126
|
+
instance_count: number;
|
|
127
|
+
/** Instances that ended with state COMPLETED in the window. */
|
|
128
|
+
completed_count: number;
|
|
129
|
+
/** Incidents CREATED in the window (every activity of the scope). */
|
|
130
|
+
incident_count: number;
|
|
131
|
+
/**
|
|
132
|
+
* `incident_count` per 100 started instances — `null` when nothing started.
|
|
133
|
+
* Several incidents per instance are possible, so it may exceed 100.
|
|
134
|
+
*/
|
|
135
|
+
incident_rate_pct: number | null;
|
|
136
|
+
/** Incidents created at the `activityId` element — `null` without one. */
|
|
137
|
+
element_incident_count: number | null;
|
|
138
|
+
/** `element_incident_count` per 100 started instances — `null` without an element or starts. */
|
|
139
|
+
element_incident_rate_pct: number | null;
|
|
140
|
+
/** Mean duration of the instances that ENDED in the window — `null` when none did. */
|
|
141
|
+
avg_duration_sec: number | null;
|
|
142
|
+
/** p95 duration of the instances that ENDED in the window — `null` when none did. */
|
|
143
|
+
p95_duration_sec: number | null;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Runs the KPI block shared by the compare modules (cluster / engine /
|
|
147
|
+
* version) for one partition: five queries, plus the element-scoped incident
|
|
148
|
+
* count when `scope.elementIncidentSel` is set.
|
|
149
|
+
*/
|
|
150
|
+
export declare function queryCompareKpis(ch: PrometheusClient, scope: KpiScope, w: CountWindow): Promise<CompareKpis>;
|
|
151
|
+
/**
|
|
152
|
+
* Deltas of `other` vs `baseline`: percentage points for rates, percent
|
|
153
|
+
* otherwise. Every delta is `null` when either side is not measured or the
|
|
154
|
+
* baseline is 0.
|
|
155
|
+
*/
|
|
156
|
+
export interface CompareKpiDelta {
|
|
157
|
+
/**
|
|
158
|
+
* Change in instances started PER DAY — equal windows make it the plain
|
|
159
|
+
* count change; windows of different length (a clamped post-deploy window)
|
|
160
|
+
* still compare fairly.
|
|
161
|
+
*/
|
|
162
|
+
started_per_day_delta_pct: number | null;
|
|
163
|
+
incident_rate_delta_pp: number | null;
|
|
164
|
+
element_incident_rate_delta_pp: number | null;
|
|
165
|
+
avg_duration_delta_pct: number | null;
|
|
166
|
+
p95_duration_delta_pct: number | null;
|
|
167
|
+
}
|
|
168
|
+
type DeltaInput = Pick<CompareKpis, "instance_count" | "incident_rate_pct" | "element_incident_rate_pct" | "avg_duration_sec" | "p95_duration_sec">;
|
|
169
|
+
/**
|
|
170
|
+
* Shared delta block of the compare modules. `days` are the two windows'
|
|
171
|
+
* actual lengths; the start counts are compared per day.
|
|
172
|
+
*/
|
|
173
|
+
export declare function compareKpiDelta(baseline: DeltaInput, other: DeltaInput, days: {
|
|
174
|
+
baseline: number;
|
|
175
|
+
other: number;
|
|
176
|
+
}): CompareKpiDelta;
|
|
177
|
+
/**
|
|
178
|
+
* Whether a comparison is below the trust threshold: a partition with fewer
|
|
179
|
+
* than `minBucketSize` started instances (the rates' base) OR fewer completed
|
|
180
|
+
* ones (the durations' sample) is noise, not a signal.
|
|
181
|
+
*/
|
|
182
|
+
export declare function belowMinBucket(partitions: ReadonlyArray<Pick<CompareKpis, "instance_count" | "completed_count">>, minBucketSize: number): boolean;
|
|
183
|
+
export {};
|
|
184
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/queries/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACpE,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEpF,OAAO,EAAyC,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAEtF,8DAA8D;AAC9D,eAAO,MAAM,MAAM,GAAI,GAAG,MAAM,WAA4B,CAAA;AAE5D,4EAA4E;AAC5E,eAAO,MAAM,SAAS,GAAI,IAAI,MAAM,WAAsB,CAAA;AAE1D,mEAAmE;AACnE,eAAO,MAAM,aAAa,GAAI,IAAI,MAAM,GAAG,IAAI,kBAAyC,CAAA;AAUxF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,GAAG,MAAM,CAUjE;AAcD;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,SAAS,EAAE,KAAK,MAAM,WACK,CAAA;AAE9D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,UAAU,EAAE,WAAgC,CAAA;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,GAAI,GAAG,UAAU,EAAE,kBAAmC,CAAA;AAE9E;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,WAA6C,CAAA;AAEpG,sFAAsF;AACtF,eAAO,MAAM,kBAAkB,GAAI,SAAS,UAAU,EAAE,KAAG,MAAM,EAC8B,CAAA;AAE/F,mGAAmG;AACnG,eAAO,MAAM,OAAO,QAAO,MAAkC,CAAA;AAE7D;;;GAGG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOpF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAGpF;AAED,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAElF;AAED,oFAAoF;AACpF,MAAM,WAAW,QAAQ;IACvB,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAA;IACX,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW;;;;;;;EAWzD;AAED,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAA;IACtB,+DAA+D;IAC/D,eAAe,EAAE,MAAM,CAAA;IACvB,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,0EAA0E;IAC1E,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,gGAAgG;IAChG,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,sFAAsF;IACtF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,qFAAqF;IACrF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,gBAAgB,EACpB,KAAK,EAAE,QAAQ,EACf,CAAC,EAAE,WAAW,GACb,OAAO,CAAC,WAAW,CAAC,CA0BtB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,8BAA8B,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAA;CACtC;AAED,KAAK,UAAU,GAAG,IAAI,CACpB,WAAW,EACT,gBAAgB,GAChB,mBAAmB,GACnB,2BAA2B,GAC3B,kBAAkB,GAClB,kBAAkB,CACrB,CAAA;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxC,eAAe,CAejB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,EAClF,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT"}
|