@dx-do/cli 6.0.1 → 6.0.4
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/README.md +12 -6
- package/dist-node/{03-discover-sources.nassql.data-store-by6sqk23.json5 → 03-discover-sources.nassql.data-store-d6hb6wf7.json5} +4 -3
- package/dist-node/{20-nassql-from-metadata-basic.nassql.data-store-zdf1gp1v.json5 → 20-nassql-from-metadata-basic.nassql.data-store-mq1hn0qz.json5} +4 -2
- package/dist-node/34-nassql-entity-to-metric-ids.nassql-jn6t8zxs.md +76 -0
- package/dist-node/34-nassql-entity-to-metric-ids.nassql.data-store-t8ecm336.json5 +69 -0
- package/dist-node/34-nassql-entity-to-metric-ids.nassql.data-store-tmd-9vbg6p76.json +4 -0
- package/dist-node/40-metadata-filter-by-typeenum.metadata-kmcc85ac.md +66 -0
- package/dist-node/40-metadata-filter-by-typeenum.metadata.data-store-b4erpx6h.json5 +52 -0
- package/dist-node/40-metadata-filter-by-typeenum.metadata.data-store-tmd-3zg3n0j1.json +4 -0
- package/dist-node/41-metadata-frontend-durations.metadata-n2ba62j7.md +50 -0
- package/dist-node/41-metadata-frontend-durations.metadata.data-store-kpkhaf6c.json5 +48 -0
- package/dist-node/41-metadata-frontend-durations.metadata.data-store-tmd-c685fc9v.json +4 -0
- package/dist-node/42-metadata-metric-id-to-entities.metadata-qg0p7y71.md +67 -0
- package/dist-node/42-metadata-metric-id-to-entities.metadata.data-store-tmd-zd99v6pz.json +4 -0
- package/dist-node/42-metadata-metric-id-to-entities.metadata.data-store-vwv8dq0e.json5 +52 -0
- package/dist-node/{SKILL-1xn7r9nt.md → SKILL-86r2cm61.md} +26 -2
- package/dist-node/{agentic-mcp-rycd2gh8.md → agentic-mcp-9nz7zh8d.md} +2 -1
- package/dist-node/alarms-cookbook-xrwbrdte.md +160 -0
- package/dist-node/alarms-quickstart-fhg59mr2.md +100 -0
- package/dist-node/{chunk-RNMHSXZF-pdwasrg7.js → chunk-4L5DIG2E-9p3rrkp9.js} +1 -1
- package/dist-node/{chunk-VV2FJEMA-3rvtkmga.js → chunk-4Q347M53-e6wyjnpc.js} +2 -2
- package/dist-node/{chunk-Q2JA73UH-akkb8bh3.js → chunk-6TL6OWJA-jrr526kw.js} +1 -1
- package/dist-node/chunk-7G4RSOZU-nnmp25yx.js +3753 -0
- package/dist-node/{chunk-YVD3UK5I-9pxr1jka.js → chunk-JYKZ5EMU-6jq5egbw.js} +3 -3
- package/dist-node/{chunk-5VSFINOX-ewzpx7wh.js → chunk-OV4PNSIK-pqs8y3nm.js} +3 -3
- package/dist-node/{chunk-JRM4BLOM-rg32z8w4.js → chunk-P6TRLBVU-rxz4tacs.js} +1 -1
- package/dist-node/{chunk-4I3HBO6U-2ebgf7kh.js → chunk-TFFMCZCS-rhchxvk7.js} +1 -1
- package/dist-node/{chunk-4PMCLJMS-0mqvr4m4.js → chunk-W5FHICA2-x50sz7wk.js} +1 -1
- package/dist-node/{discovery-flow-fw79kbx4.md → discovery-flow-m0zp07e3.md} +13 -0
- package/dist-node/{gotchas-8ab64kcd.md → gotchas-p696dmam.md} +131 -0
- package/dist-node/{index-104hyb1m.html → index-dfkxebky.html} +1 -1
- package/dist-node/{index-mbzg9rhc.json → index-mf7znaf7.json} +30 -0
- package/dist-node/{index-g3hh5wez.json → index-x07qhy6g.json} +53 -0
- package/dist-node/{investigator-flow-jc2s0n46.md → investigator-flow-dcyk8v51.md} +36 -2
- package/dist-node/main-4VTFKCWX-6x4n4v8m.js +13 -0
- package/dist-node/main.js +26106 -18435
- package/dist-node/{metrics-grounding-2h4kkbe3.md → metrics-grounding-8vhfqya9.md} +59 -4
- package/dist-node/{mm-cookbook-23jpw721.md → mm-cookbook-fdwbt989.md} +1 -1
- package/dist-node/{nassql-cookbook-n8kc0mff.md → nassql-cookbook-kp525xra.md} +41 -1
- package/dist-node/{nassql-quickstart-090e0yex.md → nassql-quickstart-mth22qd3.md} +3 -1
- package/package.json +1 -1
- package/dist-node/chunk-72HYG3XZ-kf7hy4vs.js +0 -3625
- package/dist-node/main-SGLYO5YX-ht69eb0y.js +0 -13
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ bunx @dx-do/cli@<version> <--config=<config-file>> command-group command <parame
|
|
|
47
47
|
#### Output
|
|
48
48
|
|
|
49
49
|
```
|
|
50
|
-
ℹ info dx-do v6.0.
|
|
50
|
+
ℹ info dx-do v6.0.4 on node v24.16.0 on linux-x64 via node (ssl: 3.5.6)
|
|
51
51
|
⚠ warning Not loading configuration
|
|
52
52
|
✖ error Usage: dx-do --option[=value]... <command-group> <command> <command-param>=<value>...
|
|
53
53
|
ℹ info Available command-groups: acc, agent, agentic, alarm, alert, apm-universe, asm, attribute, audit, auth, axa, blob, channel, config, dashboard, diagnose, event, experience, graph, help, inventory, jsextension, log, managementmodule, metrex, metric, metricgrouping, nass, o2-alert, o2-managementmodule, o2-metricgrouping, o2-universe, perspective, service, situation, sql, tas, topographer, trace, ui, vertex
|
|
@@ -208,6 +208,8 @@ bunx @dx-do/cli@<version> <--config=<config-file>> command-group command <parame
|
|
|
208
208
|
⤜ copy-with-metric-grouping.........................: copy an alert with it's metric grouping
|
|
209
209
|
⤜ analyze...........................................: analyzes an alert and it's threshold
|
|
210
210
|
⤜ detail............................................: get alert definition
|
|
211
|
+
⤜ delete............................................: deletes an APM alert (dry-run by default)
|
|
212
|
+
⤜ create............................................: creates a new APM simple alert (dry-run by default)
|
|
211
213
|
```
|
|
212
214
|
#### nass
|
|
213
215
|
```nass
|
|
@@ -420,6 +422,15 @@ bunx @dx-do/cli@<version> <--config=<config-file>> command-group command <parame
|
|
|
420
422
|
⤜ import............................................: imports a management module from json
|
|
421
423
|
⤜ export............................................: exports a management module and its metric groupings, alerts and calculators.
|
|
422
424
|
```
|
|
425
|
+
#### metricgrouping
|
|
426
|
+
```metricgrouping
|
|
427
|
+
⤜ update............................................: updates an existing APM metric grouping (dry-run by default)
|
|
428
|
+
⤜ detail............................................: get full detail of an APM metric grouping
|
|
429
|
+
⤜ delete............................................: deletes an APM metric grouping (dry-run by default)
|
|
430
|
+
⤜ create............................................: creates a new APM metric grouping (dry-run by default)
|
|
431
|
+
⤜ list-by-managementmodule..........................: lists all metric groupings in management modules.
|
|
432
|
+
⤜ list-metrics......................................: lists all live metrics in metric grouping
|
|
433
|
+
```
|
|
423
434
|
#### log
|
|
424
435
|
```log
|
|
425
436
|
⤜ query.............................................: queries DXO2 Log analytics
|
|
@@ -437,11 +448,6 @@ bunx @dx-do/cli@<version> <--config=<config-file>> command-group command <parame
|
|
|
437
448
|
⤜ export............................................: Export Map View Perspective
|
|
438
449
|
⤜ delete............................................: Delete Map View Perspective
|
|
439
450
|
```
|
|
440
|
-
#### metricgrouping
|
|
441
|
-
```metricgrouping
|
|
442
|
-
⤜ list-by-managementmodule..........................: lists all metric groupings in management modules.
|
|
443
|
-
⤜ list-metrics......................................: lists all live metrics in metric grouping
|
|
444
|
-
```
|
|
445
451
|
#### asm
|
|
446
452
|
```asm
|
|
447
453
|
⤜ list-folders......................................: lists asm folders
|
|
@@ -50,9 +50,10 @@
|
|
|
50
50
|
"columns": [{ "column": "metric_count", "sortDescending": true }]
|
|
51
51
|
},
|
|
52
52
|
/*
|
|
53
|
-
* KEEP must be the LAST op
|
|
54
|
-
* HTTP 400 if anything follows KEEP). It's the projection
|
|
55
|
-
*
|
|
53
|
+
* KEEP is optional; if used it must be the LAST op (server returns
|
|
54
|
+
* HTTP 400 if anything follows KEEP). It's the projection step —
|
|
55
|
+
* selects which columns the response includes. Pipelines that end
|
|
56
|
+
* in AGG / COUNT / TOP / BOTTOM / DESCRIBE need no KEEP at all.
|
|
56
57
|
*/
|
|
57
58
|
{
|
|
58
59
|
"op": "KEEP",
|
|
@@ -30,8 +30,10 @@
|
|
|
30
30
|
"as": "total"
|
|
31
31
|
},
|
|
32
32
|
/*
|
|
33
|
-
* KEEP must be the LAST op (server returns
|
|
34
|
-
* follows). Selects which columns appear in
|
|
33
|
+
* KEEP is optional; if used it must be the LAST op (server returns
|
|
34
|
+
* HTTP 400 if anything follows). Selects which columns appear in
|
|
35
|
+
* the response — pipelines ending in AGG / COUNT / TOP / BOTTOM /
|
|
36
|
+
* DESCRIBE need no KEEP at all.
|
|
35
37
|
*/
|
|
36
38
|
{
|
|
37
39
|
"op": "KEEP",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# 34-nassql-entity-to-metric-ids (NASSQL)
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Given a vertex externalId, list every `metric.id` the entity emits. The canonical "what metrics does this entity produce?" pattern — answered as a flat row-per-metric table that downstream queries (or a human) can iterate over.
|
|
6
|
+
|
|
7
|
+
Inverse of `42-metadata-metric-id-to-entities`. The two together form the metricId ↔ entity round-trip.
|
|
8
|
+
|
|
9
|
+
## Query construction
|
|
10
|
+
|
|
11
|
+
Three-step pipeline:
|
|
12
|
+
|
|
13
|
+
1. **`FROM_TOPOLOGY`** with a `VERTEX` filter narrowing to the target externalId(s). The filter takes an array, so multiple vertices can be enumerated in a single call.
|
|
14
|
+
2. **`JOIN_METADATA(ALL)`** joins metric metadata rows for those vertices. The join key is implicit — DataStore correlates each topology vertex with the metric descriptors registered against it (the inverse of the `external_ids` association documented in `42-`).
|
|
15
|
+
3. **`KEEP vertex.externalId, metric.id`** — the round-trip-friendly projection. Two columns, one row per metric.
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"query": [
|
|
20
|
+
{ "op": "FROM_TOPOLOGY",
|
|
21
|
+
"querySpecifier": { "filter": { "op": "VERTEX", "externalId": ["<vertex-id>"] } } },
|
|
22
|
+
{ "op": "JOIN_METADATA", "querySpecifier": { "op": "ALL" } },
|
|
23
|
+
{ "op": "KEEP", "columns": ["vertex.externalId", "metric.id"] }
|
|
24
|
+
],
|
|
25
|
+
"limit": 200
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API surface exercised
|
|
30
|
+
|
|
31
|
+
- **TAS `VERTEX` filter** — narrow `FROM_TOPOLOGY` to specific vertices by their externalId list.
|
|
32
|
+
- **`JOIN_METADATA`** — the cross-domain join from topology rows to metric-metadata rows.
|
|
33
|
+
- **The implicit topology↔metadata join key** — DataStore handles the correlation; you don't supply a `metricIdColumn` (only `JOIN_DATA` needs that).
|
|
34
|
+
|
|
35
|
+
## Sample output
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
[
|
|
39
|
+
["vertex.externalId", "metric.id"],
|
|
40
|
+
["ATC:CTS1A01:GENERICFRONTEND:Apps|...", "WCUZP-EQ-_5Y-fp0YUJ0B"],
|
|
41
|
+
["ATC:CTS1A01:GENERICFRONTEND:Apps|...", "ABC1d-XY-_3Q-rt7uYJ0B"],
|
|
42
|
+
["ATC:CTS1A01:GENERICFRONTEND:Apps|...", "DEFgh-12-_8R-mn5xZK1C"],
|
|
43
|
+
...
|
|
44
|
+
]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
One row per metric the entity emits. For an entity with rich instrumentation (a JVM-monitored servlet, an Infrastructure-agent host) the count can be in the hundreds.
|
|
48
|
+
|
|
49
|
+
## The round-trip
|
|
50
|
+
|
|
51
|
+
| Direction | Query | Field consumed | Field produced |
|
|
52
|
+
|---|---|---|---|
|
|
53
|
+
| entity → metricIds | `34-nassql-entity-to-metric-ids` (this query) | `vertex.externalId` | `metric.id` rows |
|
|
54
|
+
| metricId → entities | `42-metadata-metric-id-to-entities` | `metric.id` | `metric.attributes.external_ids[]` |
|
|
55
|
+
|
|
56
|
+
A common composite flow: start with a metric.id, run `42-` to find its entity associations, then run `34-` against one of those externalIds to enumerate the entity's full metric catalog.
|
|
57
|
+
|
|
58
|
+
## Common variations
|
|
59
|
+
|
|
60
|
+
- **Narrow the joined metrics** — replace `JOIN_METADATA.querySpecifier: { "op": "ALL" }` with a SPEC, an ID list, or a TYPE-bitmask filter (see `40-metadata-filter-by-typeenum`). Useful when you only care about, say, every duration metric the entity emits.
|
|
61
|
+
- **Pivot to data values** — chain `JOIN_DATA` after `JOIN_METADATA` (with `metricIdColumn: "metric.id"`) to attach time-series rows.
|
|
62
|
+
- **Multi-entity** — pass multiple externalIds in the `VERTEX` filter array; rows are per-entity-per-metric.
|
|
63
|
+
|
|
64
|
+
## When this is useful
|
|
65
|
+
|
|
66
|
+
- You have an entity (vertex externalId) from a TAS query, an alert, or a service-membership lookup, and need its metric inventory.
|
|
67
|
+
- Building a tenant-coverage audit ("which entities have zero metrics? which have the most?").
|
|
68
|
+
- Feeding a NASSQL `JOIN_DATA` step that needs an enumerated `metric.id` list scoped to a known entity set.
|
|
69
|
+
|
|
70
|
+
## See also
|
|
71
|
+
|
|
72
|
+
- `42-metadata-metric-id-to-entities` — the inverse direction (metricId → entity list).
|
|
73
|
+
- `23-nassql-join-topology-metadata` — the same join shape, but aggregating to per-entity counts rather than per-metric rows.
|
|
74
|
+
- `40-metadata-filter-by-typeenum` — for narrowing the joined metric set by metric kind (duration / rate / counter / saturation).
|
|
75
|
+
- `cookbooks/metric-source-names.md` — the metric-name terminology, now extended to cover `external_ids` as the entity-association field.
|
|
76
|
+
- `cookbooks/nassql-cookbook.md` — `JOIN_METADATA` reference.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* entity → metricIds: given a vertex externalId, list every metric.id
|
|
3
|
+
* that the entity emits.
|
|
4
|
+
*
|
|
5
|
+
* Shape: NASSQL `FROM_TOPOLOGY` filtered to one (or many) vertices by
|
|
6
|
+
* externalId, then `JOIN_METADATA(ALL)` to pick up the metric metadata
|
|
7
|
+
* rows for those vertices. `KEEP` projects the round-trip-friendly
|
|
8
|
+
* pair `(vertex.externalId, metric.id)`.
|
|
9
|
+
*
|
|
10
|
+
* The externalId values consumed here are exactly what the sister query
|
|
11
|
+
* `42-metadata-metric-id-to-entities` produces from its
|
|
12
|
+
* `metric.attributes.external_ids` field. The two queries form a clean
|
|
13
|
+
* round-trip:
|
|
14
|
+
* externalId → [metric.id, ...] (this query)
|
|
15
|
+
* metricId → external_ids[] (#42)
|
|
16
|
+
*
|
|
17
|
+
* To use this against your tenant: replace the placeholder externalId
|
|
18
|
+
* with a real vertex externalId. You can obtain one by:
|
|
19
|
+
* - running `42-metadata-metric-id-to-entities` and reading
|
|
20
|
+
* `metric.attributes.external_ids` from the response, or
|
|
21
|
+
* - running a TAS query that includes `externalId` in its projection.
|
|
22
|
+
*
|
|
23
|
+
* The shape `<universe-prefix>:<id>:<vertex-type>:<...>` is consistent
|
|
24
|
+
* across tenants. ExternalIds round-trip without reformatting.
|
|
25
|
+
*
|
|
26
|
+
* The placeholder externalId below will return zero rows. That's fine
|
|
27
|
+
* for parse/validate runs — substitute a real externalId before pulling
|
|
28
|
+
* an actual metric.id list.
|
|
29
|
+
*/
|
|
30
|
+
{
|
|
31
|
+
"query": [
|
|
32
|
+
/*
|
|
33
|
+
* Source: load topology rows for the named vertex/vertices. The
|
|
34
|
+
* `VERTEX` filter accepts an array of externalIds and selects every
|
|
35
|
+
* vertex whose externalId is in the list — typically one row per
|
|
36
|
+
* matching vertex.
|
|
37
|
+
*/
|
|
38
|
+
{
|
|
39
|
+
"op": "FROM_TOPOLOGY",
|
|
40
|
+
"querySpecifier": {
|
|
41
|
+
"filter": {
|
|
42
|
+
"op": "VERTEX",
|
|
43
|
+
"externalId": ["REPLACE-WITH-REAL-EXTERNAL-ID"]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"alias": "entities"
|
|
47
|
+
},
|
|
48
|
+
/*
|
|
49
|
+
* Join in metric metadata for those vertices. `op: ALL` includes
|
|
50
|
+
* every metric the entity emits; substitute a SPEC specifier to
|
|
51
|
+
* narrow (e.g. duration metrics only — see `40-metadata-filter-by-typeenum`
|
|
52
|
+
* for the typeEnum bitmask shape).
|
|
53
|
+
*/
|
|
54
|
+
{
|
|
55
|
+
"op": "JOIN_METADATA",
|
|
56
|
+
"querySpecifier": { "op": "ALL" },
|
|
57
|
+
"alias": "entity_metrics"
|
|
58
|
+
},
|
|
59
|
+
/*
|
|
60
|
+
* Project the round-trip pair: externalId on the left, metric.id on
|
|
61
|
+
* the right. Each row is one metric the entity emits.
|
|
62
|
+
*/
|
|
63
|
+
{
|
|
64
|
+
"op": "KEEP",
|
|
65
|
+
"columns": ["vertex.externalId", "metric.id"]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"limit": 200
|
|
69
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# 40-metadata-filter-by-typeenum (Metrics Metadata)
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Return every metric on the tenant whose `type` is a DURATION variant — the natural query for "show me the latency-shaped metrics" investigations (slow / fast analysis, p99 hunting, response-time dashboards).
|
|
6
|
+
|
|
7
|
+
Generalizes to any single-axis filter: any RATE, any COUNTER, any SATURATION, any PERCENTAGE — just change `bitMask` / `bitMatch` to the target axis bit.
|
|
8
|
+
|
|
9
|
+
## Query construction
|
|
10
|
+
|
|
11
|
+
`metric.type` is a 32-bit integer composed by bitwise-OR of named `typeEnum` values. Each semantic class lives in a fixed bit:
|
|
12
|
+
|
|
13
|
+
| Class | Bit | Hex |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| DURATION | 10 | `0x400` |
|
|
16
|
+
| RATE | 9 | `0x200` |
|
|
17
|
+
| COUNTER | 8 | `0x100` |
|
|
18
|
+
| PERCENTAGE | 12 | `0x1000` |
|
|
19
|
+
| INTERVAL_COUNTER | 13 | `0x2000` |
|
|
20
|
+
| SATURATION | 14 | `0x4000` |
|
|
21
|
+
|
|
22
|
+
The `TYPE` AttributeNameSpecifier matches metrics where `((metric.type & bitMask) operator bitMatch)`. To match "any DURATION variant — INT, LONG, or DOUBLE — regardless of whether it carries a TYPE_INFO_* flag", set both `bitMask` and `bitMatch` to the DURATION bit (`0x400`):
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{ "op": "TYPE", "bitMask": 1024, "bitMatch": 1024, "operator": "EQ",
|
|
26
|
+
"specifier": { "op": "ALL" } }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The full table of `typeEnum` names → bit values lives in `cookbooks/metrics-grounding.md`. To compose more complex filters in code, use `composeMetricTypeBits([...names])` from `@dx-do/client`.
|
|
30
|
+
|
|
31
|
+
The same package exposes 6 `ANY_*` axis names (`ANY_DURATION`, `ANY_RATE`, `ANY_COUNTER`, `ANY_PERCENTAGE`, `ANY_INTERVAL_COUNTER`, `ANY_SATURATION`) that resolve to just the semantic-class bit — `composeMetricTypeBits(['ANY_DURATION'])` returns `1024` directly. The chips picker in the visual MM editor groups these under "ANY_* (numeric-info axis)".
|
|
32
|
+
|
|
33
|
+
## API surface exercised
|
|
34
|
+
|
|
35
|
+
- **MM `SPEC`** with all three sub-specifier slots filled — the most common MM compose pattern.
|
|
36
|
+
- **`AttributeNameSpecifier.TYPE`** — bitwise type filter, the only way to scope a query by metric kind on the read side (`/metadata/queryMetric` accepts no `typeEnum` field).
|
|
37
|
+
- **`clamp`** — required for safety on real tenants; without it the server returns every matching metric.
|
|
38
|
+
|
|
39
|
+
## Expected output
|
|
40
|
+
|
|
41
|
+
Hundreds to thousands of `MetricAttribute` descriptors. Sample on a representative tenant:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
{
|
|
45
|
+
"metrics": [
|
|
46
|
+
{ "type": 1025, "attributeName": "...:Average Response Time (ms)", ... },
|
|
47
|
+
{ "type": 1026, "attributeName": "...:Average Response Time (us)", ... },
|
|
48
|
+
{ "type": 1028, "attributeName": "...:Total time (ms)", ... },
|
|
49
|
+
{ "type": 268436481, "attributeName": "...:Average Response Time (ms)", ... }
|
|
50
|
+
],
|
|
51
|
+
...
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Every returned metric will have bit 10 of `type` set. Decode any `type` value back to typeEnum names with `decodeMetricTypeBits(n)` from `@dx-do/client`.
|
|
56
|
+
|
|
57
|
+
## Two empirical gotchas this query side-steps
|
|
58
|
+
|
|
59
|
+
1. The `TYPE` op requires its inner `specifier` field on the wire — the schema marks it optional but the server returns 400 without it. We pass `{ op: "ALL" }` as a no-op inner. Full write-up in `cookbooks/gotchas.md`.
|
|
60
|
+
2. The platform doc lists `MONITOR_INT_DURATION` and `MONITOR_LONG_DURATION` but omits `MONITOR_DOUBLE_DURATION` (`type=1028`), which exists on the wire. The bit-10 filter catches it anyway. Same gotcha file documents the broader pattern.
|
|
61
|
+
|
|
62
|
+
## See also
|
|
63
|
+
|
|
64
|
+
- `cookbooks/metrics-grounding.md` — bit-region layout and the full typeEnum table
|
|
65
|
+
- `cookbooks/mm-cookbook.md` — full AttributeNameSpecifier vocabulary
|
|
66
|
+
- `cookbooks/gotchas.md` — TYPE-op inner-specifier requirement; undocumented `MONITOR_DOUBLE_*` variants
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Filter Metrics Metadata by typeEnum — find every duration metric on the
|
|
3
|
+
* tenant. Useful for "slow / fast" investigations where you only care about
|
|
4
|
+
* latency-shaped metrics.
|
|
5
|
+
*
|
|
6
|
+
* The trick is the bitwise `TYPE` AttributeNameSpecifier: `metric.type` is
|
|
7
|
+
* a bitwise OR of named typeEnum values, and bit 10 (0x400) is set on every
|
|
8
|
+
* DURATION variant — MONITOR_INT_DURATION (1025), MONITOR_LONG_DURATION
|
|
9
|
+
* (1026), and the undocumented-but-real MONITOR_DOUBLE_DURATION (1028).
|
|
10
|
+
* Filtering on bit 10 alone catches all three and ignores TYPE_INFO_*
|
|
11
|
+
* flags (FRONTEND / BACKEND / BUSINESS_TRANSACTION) so frontend-tagged
|
|
12
|
+
* duration metrics are still returned.
|
|
13
|
+
*
|
|
14
|
+
* See `cookbooks/metrics-grounding.md` for the full bit-region layout and
|
|
15
|
+
* the typeEnum value table. To compose a different bitMask programmatically,
|
|
16
|
+
* use `composeMetricTypeBits([...names])` from `@dx-do/client`.
|
|
17
|
+
*
|
|
18
|
+
* Two empirical gotchas this query side-steps (see `cookbooks/gotchas.md`):
|
|
19
|
+
* - The TYPE op's nested `specifier` field is required by the server even
|
|
20
|
+
* though the schema marks it optional. We pass `{ op: "ALL" }` as a
|
|
21
|
+
* no-op inner.
|
|
22
|
+
* - Without `clamp`, MM returns every matching metric on the tenant —
|
|
23
|
+
* routinely tens of thousands. We cap at 200 for safe browsing.
|
|
24
|
+
*/
|
|
25
|
+
{
|
|
26
|
+
"specifier": {
|
|
27
|
+
"op": "SPEC",
|
|
28
|
+
"sourceNameSpecifier": { "op": "ALL" },
|
|
29
|
+
"folderNameSpecifier": { "op": "ALL" },
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* TYPE specifier with bitMask = bitMatch = 0x400 (1024) means:
|
|
33
|
+
* "match every metric where bit 10 of `metric.type` is set,
|
|
34
|
+
* regardless of any other bits." That's the DURATION-axis bit.
|
|
35
|
+
*
|
|
36
|
+
* For an exact-typeEnum filter instead, set bitMask = bitMatch =
|
|
37
|
+
* composeMetricTypeBits(['MONITOR_INT_DURATION']) (= 1025) — that
|
|
38
|
+
* matches only INT_DURATION, not LONG / DOUBLE.
|
|
39
|
+
*
|
|
40
|
+
* For "any rate" use 0x200; "any saturation" use 0x4000;
|
|
41
|
+
* "any percentage" use 0x1000; "any interval counter" use 0x2000.
|
|
42
|
+
*/
|
|
43
|
+
"attributeNameSpecifier": {
|
|
44
|
+
"op": "TYPE",
|
|
45
|
+
"bitMask": 1024,
|
|
46
|
+
"bitMatch": 1024,
|
|
47
|
+
"operator": "EQ",
|
|
48
|
+
"specifier": { "op": "ALL" }
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"clamp": 200
|
|
52
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# 41-metadata-frontend-durations (Metrics Metadata)
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Return every metric that is **both** a duration variant AND tagged as a frontend metric. This is the canonical "slow on the frontend" slice — what an on-call engineer reaches for after a latency alert fires.
|
|
6
|
+
|
|
7
|
+
Sister recipe to `40-metadata-filter-by-typeenum`. Where 40 demonstrates the single-axis filter, this one shows the **multi-chip composition** pattern: combine an `ANY_*` semantic-class axis with a `TYPE_INFO_*` flag.
|
|
8
|
+
|
|
9
|
+
## Query construction
|
|
10
|
+
|
|
11
|
+
The `TYPE` AttributeNameSpecifier matches metrics where `((metric.type & bitMask) == bitMatch)`. To match "any duration that's frontend-tagged", set both fields to the bitwise OR of the DURATION axis bit and the FRONTEND flag bit:
|
|
12
|
+
|
|
13
|
+
| Component | typeEnum name | Bit | Hex |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| Numeric-info axis | `ANY_DURATION` | 10 | `0x00000400` |
|
|
16
|
+
| Metric-type info flag | `TYPE_INFO_FRONTEND` | 28 | `0x10000000` |
|
|
17
|
+
| Combined | — | 10 + 28 | `0x10000400` (= 268436480) |
|
|
18
|
+
|
|
19
|
+
In the visual MM editor, pick both chips from the dropdown — `ANY_DURATION` from the "ANY_* (numeric-info axis)" group and `TYPE_INFO_FRONTEND` from the "TYPE_* (flags)" group. The picker auto-fills `bitMask = bitMatch = 268436480`.
|
|
20
|
+
|
|
21
|
+
To pivot the same shape:
|
|
22
|
+
|
|
23
|
+
- **Backend durations** — swap `TYPE_INFO_FRONTEND` for `TYPE_INFO_BACKEND` (`0x20000000`). Combined mask: `0x20000400` = 536871424.
|
|
24
|
+
- **Business-transaction durations** — `TYPE_INFO_BUSINESS_TRANSACTION` (`0x40000000`). Combined mask: `0x40000400` = 1073742848.
|
|
25
|
+
- **Frontend rates / counters / saturations** — swap `ANY_DURATION` for `ANY_RATE` (`0x200`), `ANY_COUNTER` (`0x100`), `ANY_SATURATION` (`0x4000`), etc.
|
|
26
|
+
|
|
27
|
+
## API surface exercised
|
|
28
|
+
|
|
29
|
+
- **MM `SPEC`** with all three sub-specifier slots filled.
|
|
30
|
+
- **`AttributeNameSpecifier.TYPE`** — bitwise type filter.
|
|
31
|
+
- **Multi-axis bit composition** — DURATION axis OR'd with TYPE_INFO_* flag.
|
|
32
|
+
|
|
33
|
+
## Expected output
|
|
34
|
+
|
|
35
|
+
Hundreds of `MetricAttribute` descriptors, all with bits 10 and 28 set in `type`. Sample shapes on a representative tenant:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
{
|
|
39
|
+
"type": 268436481,
|
|
40
|
+
"attributeName": "By Frontend|Tomcat Manager Application|Health:Average Response Time (ms)"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`decodeMetricTypeBits(268436481)` from `@dx-do/client` returns `{ matched: ['MONITOR_INT_DURATION', 'TYPE_INFO_FRONTEND'], residual: 0 }`.
|
|
45
|
+
|
|
46
|
+
## See also
|
|
47
|
+
|
|
48
|
+
- `40-metadata-filter-by-typeenum` — single-axis (ANY_DURATION) filter, no flag scoping.
|
|
49
|
+
- `cookbooks/metrics-grounding.md` — bit-region layout, full typeEnum table, AND-semantics warning when picking multiple MONITOR_* of the same class.
|
|
50
|
+
- `cookbooks/gotchas.md` — TYPE-op inner-specifier requirement.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Filter Metrics Metadata for FRONTEND-tagged duration metrics — the
|
|
3
|
+
* "slow on the frontend" investigation slice.
|
|
4
|
+
*
|
|
5
|
+
* This is the multi-chip composition pattern: combine an `ANY_*` numeric-info
|
|
6
|
+
* axis (any DURATION, regardless of INT / LONG / DOUBLE underlying type) with
|
|
7
|
+
* a `TYPE_INFO_*` flag (FRONTEND vs BACKEND vs BUSINESS_TRANSACTION). The
|
|
8
|
+
* chips picker's "has all selected bits" semantics produces the right mask:
|
|
9
|
+
*
|
|
10
|
+
* composeMetricTypeBits(['ANY_DURATION', 'TYPE_INFO_FRONTEND'])
|
|
11
|
+
* = 0x400 | 0x10000000
|
|
12
|
+
* = 0x10000400
|
|
13
|
+
* = 268436480
|
|
14
|
+
*
|
|
15
|
+
* The server then matches every metric where bit 10 AND bit 28 are both set
|
|
16
|
+
* — i.e. any duration variant flagged as frontend-source.
|
|
17
|
+
*
|
|
18
|
+
* To pivot the same shape:
|
|
19
|
+
* - Backend durations → swap TYPE_INFO_FRONTEND for TYPE_INFO_BACKEND
|
|
20
|
+
* - Business-transaction → swap for TYPE_INFO_BUSINESS_TRANSACTION
|
|
21
|
+
* - Frontend rates / counters → swap ANY_DURATION for ANY_RATE / ANY_COUNTER
|
|
22
|
+
*
|
|
23
|
+
* See `cookbooks/metrics-grounding.md` for the full bit-region map and the
|
|
24
|
+
* sister example `40-metadata-filter-by-typeenum` for the unscoped axis-only
|
|
25
|
+
* pattern.
|
|
26
|
+
*/
|
|
27
|
+
{
|
|
28
|
+
"specifier": {
|
|
29
|
+
"op": "SPEC",
|
|
30
|
+
"sourceNameSpecifier": { "op": "ALL" },
|
|
31
|
+
"folderNameSpecifier": { "op": "ALL" },
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* bitMask = bitMatch = 0x10000400 means: "match every metric where
|
|
35
|
+
* (type & 0x10000400) == 0x10000400" — i.e. BOTH the DURATION axis
|
|
36
|
+
* bit AND the TYPE_INFO_FRONTEND flag bit are set. Server-internal
|
|
37
|
+
* type-property or counter-info bits are ignored.
|
|
38
|
+
*/
|
|
39
|
+
"attributeNameSpecifier": {
|
|
40
|
+
"op": "TYPE",
|
|
41
|
+
"bitMask": 268436480,
|
|
42
|
+
"bitMatch": 268436480,
|
|
43
|
+
"operator": "EQ",
|
|
44
|
+
"specifier": { "op": "ALL" }
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"clamp": 200
|
|
48
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# 42-metadata-metric-id-to-entities (Metrics Metadata)
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Given a metric id, find the topology vertex (or vertices) that the metric is associated with. The canonical pattern when you have a `metric.id` from somewhere (a query result, an alert payload, a customer ticket) and need to know "what entity does this metric belong to?"
|
|
6
|
+
|
|
7
|
+
The answer is **`metric.attributes.external_ids`** — an array of TAS-compatible vertex externalIds carried on every metric descriptor, populated by the producer-side agent at registration. Those externalIds are directly consumable by `FROM_TOPOLOGY`'s `VERTEX` filter — see the sister query `34-nassql-entity-to-metric-ids` for the inverse direction.
|
|
8
|
+
|
|
9
|
+
## Query construction
|
|
10
|
+
|
|
11
|
+
Two-step author flow:
|
|
12
|
+
|
|
13
|
+
1. Issue an MM `ID` specifier query with the target `metric.id`(s).
|
|
14
|
+
2. Read each returned `MetricAttribute` descriptor's `attributes.external_ids` array.
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{ "specifier": { "op": "ID", "ids": ["<metric-id>"] }, "clamp": 50 }
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## API surface exercised
|
|
21
|
+
|
|
22
|
+
- **MM `ID` op** — pinpoint by metric id; `ids` is required-non-empty.
|
|
23
|
+
- **`MetricAttribute.attributes.external_ids`** — the entity-association field on every descriptor. Always present, sometimes a single externalId, sometimes multiple.
|
|
24
|
+
|
|
25
|
+
## Sample output (one matched metric, abridged)
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"metrics": [{
|
|
30
|
+
"id": "WCUZP-EQ-_5Y-fp0YUJ0B",
|
|
31
|
+
"sourceName": "SuperDomain|host|process|agent",
|
|
32
|
+
"attributeName": "Frontends|Apps|...:Average Response Time (ms)",
|
|
33
|
+
"type": 1028,
|
|
34
|
+
"attributes": {
|
|
35
|
+
"external_ids": [
|
|
36
|
+
"ATC:CTS1A01:GENERICFRONTEND:Apps|...|CTS1A01|SET:source-tail"
|
|
37
|
+
],
|
|
38
|
+
"agent_external_id": "...",
|
|
39
|
+
"internal::serviceNames": "...",
|
|
40
|
+
"metric_name": "Average Response Time (ms)"
|
|
41
|
+
}
|
|
42
|
+
}]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The `external_ids` value is the exact string format `FROM_TOPOLOGY` accepts in its `VERTEX` filter — copy-paste round-trips work without reformatting.
|
|
47
|
+
|
|
48
|
+
## The round-trip
|
|
49
|
+
|
|
50
|
+
| Direction | Query | Field consumed | Field produced |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| metricId → entities | `42-metadata-metric-id-to-entities` (this query) | `metric.id` | `metric.attributes.external_ids[]` |
|
|
53
|
+
| entity → metricIds | `34-nassql-entity-to-metric-ids` | `vertex.externalId` | `metric.id` rows |
|
|
54
|
+
|
|
55
|
+
A common composite flow: pull the `external_ids` from this query's response, feed each into `34-`'s VERTEX filter to enumerate every metric the entity emits (not just the one you started with).
|
|
56
|
+
|
|
57
|
+
## When this is useful
|
|
58
|
+
|
|
59
|
+
- You have a `metric.id` from an alert, a NASSQL pipeline result, or a customer's ticket and need to ground "which entity is producing this?"
|
|
60
|
+
- You need the `external_ids` to feed into a TAS query for entity-context (parents, neighbors, service membership).
|
|
61
|
+
- You're debugging a metric that mysteriously has multiple `external_ids` (multi-entity registration — uncommon but real).
|
|
62
|
+
|
|
63
|
+
## See also
|
|
64
|
+
|
|
65
|
+
- `34-nassql-entity-to-metric-ids` — the inverse direction (entity → metric.id list).
|
|
66
|
+
- `cookbooks/metric-source-names.md` — the four-name terminology, now extended to cover `external_ids` as the fifth name.
|
|
67
|
+
- `cookbooks/mm-cookbook.md` — the `ID` specifier in the full top-level ops table.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* metricId → entity(s): given a metric id, find the topology vertices
|
|
3
|
+
* (entities) it belongs to.
|
|
4
|
+
*
|
|
5
|
+
* Shape: MM `ID` specifier, then read `metric.attributes.external_ids`
|
|
6
|
+
* from each returned descriptor. That field is an array of TAS-compatible
|
|
7
|
+
* vertex externalIds — typically one entry per associated entity (often
|
|
8
|
+
* a single vertex, but multi-entity metrics do exist).
|
|
9
|
+
*
|
|
10
|
+
* The externalId values returned here are exactly what the sister query
|
|
11
|
+
* `34-nassql-entity-to-metric-ids` consumes via FROM_TOPOLOGY's `VERTEX`
|
|
12
|
+
* filter. The two queries form a clean round-trip:
|
|
13
|
+
* metricId → external_ids[] (this query)
|
|
14
|
+
* externalId → [metric.id, ...] (#34)
|
|
15
|
+
*
|
|
16
|
+
* To use this against your tenant: replace the placeholder id with a
|
|
17
|
+
* real metric.id (run any MM or NASSQL query that projects `metric.id`
|
|
18
|
+
* to grab one). Multiple ids are supported — `ids` is required-non-empty
|
|
19
|
+
* and the response keeps order.
|
|
20
|
+
*
|
|
21
|
+
* Sample shape of the relevant fields in a successful response:
|
|
22
|
+
* {
|
|
23
|
+
* "metrics": [{
|
|
24
|
+
* "id": "<metric-id>",
|
|
25
|
+
* "sourceName": "SuperDomain|host|process|agent",
|
|
26
|
+
* "attributeName": "Frontends|Apps|...:Average Response Time (ms)",
|
|
27
|
+
* "type": 1028,
|
|
28
|
+
* "attributes": {
|
|
29
|
+
* "external_ids": [
|
|
30
|
+
* "SuperDomain:host-001:HOST:Hosts|host-001",
|
|
31
|
+
* ...
|
|
32
|
+
* ],
|
|
33
|
+
* ... // many other producer-supplied attributes
|
|
34
|
+
* }
|
|
35
|
+
* }]
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* Notes:
|
|
39
|
+
* - `clamp` here is generous (50) because each ID lookup typically
|
|
40
|
+
* returns at most one descriptor; the headroom is for batched calls
|
|
41
|
+
* with many ids.
|
|
42
|
+
* - The placeholder id below will return zero metrics. That's fine for
|
|
43
|
+
* a parse/validate run — substitute a real id before extracting
|
|
44
|
+
* entity associations.
|
|
45
|
+
*/
|
|
46
|
+
{
|
|
47
|
+
"specifier": {
|
|
48
|
+
"op": "ID",
|
|
49
|
+
"ids": ["REPLACE-WITH-REAL-METRIC-ID"]
|
|
50
|
+
},
|
|
51
|
+
"clamp": 50
|
|
52
|
+
}
|
|
@@ -21,13 +21,15 @@ Always in this order:
|
|
|
21
21
|
|
|
22
22
|
The full version of step 1–6 lives in `corpus_get('cookbooks', 'investigator-flow')`. **Read it on the first investigative turn of any session**, then reference inline.
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## Five load-bearing distinctions
|
|
25
25
|
|
|
26
26
|
These collapse silently into wrong answers. Internalize them:
|
|
27
27
|
|
|
28
28
|
- **Universe ≠ Service ≠ DXI_SERVICE.** Two kinds of universes (APM + O2). Services are the secondary scoping axis (often hierarchical). DXI_SERVICE is APM-internal and rarely what the user means by "service." See `corpus_get('entities', 'universe')`, `'service'`, `'dxi_service'`.
|
|
29
29
|
- **`FROM_METADATA` vs `FROM`.** Metadata = metric *definitions*; FROM = metric *datapoints* over time. Same metric, totally different rows. See `corpus_get('cookbooks', 'nassql-quickstart')` source-op decision table at the top.
|
|
30
30
|
- **Query vs analysis.** Default to producing a query that returns *raw data*, not analysis. Let the user / ui / analyzer threshold. *"1-of-30 datapoints over 90 vs all-of-30 over 70"* — same dataset, different shapes; a thresholded query silently picks one. See `corpus_get('cookbooks', 'query-vs-analysis-separation')`.
|
|
31
|
+
- **metricId ↔ entity round-trips.** A metric carries its entity associations in `metric.attributes.external_ids` (array of TAS-compatible vertex externalIds). The two directions are dedicated worked examples: `corpus_get('queries', '42-metadata-metric-id-to-entities')` (metricId → external_ids[]) and `corpus_get('queries', '34-nassql-entity-to-metric-ids')` (externalId → metric.id rows, via `FROM_TOPOLOGY(VERTEX) → JOIN_METADATA`). Reach for these whenever the user has one identifier and needs the other — common after alert-followup, ticket triage, or when chaining a TAS result into a metric query.
|
|
32
|
+
- **alarm `status` vs `severity` vs open/closed.** `status` is the lifecycle axis — `NEW` / `UPDATED` / `CLOSED`, UPPERCASE on the wire. `severity` is the criticality axis — `critical` / `major` / `minor` / `information` / `unknown`, lowercase. They are independent: a CLOSED alarm can be critical; an open alarm can be info. "Are there any alarms?" almost always means *open* alarms (`status != CLOSED`), not "any with severity > info". `list_alarms` defaults to open-only — preserve that default unless the user explicitly widens. See `corpus_get('cookbooks', 'alarms-quickstart')`.
|
|
31
33
|
|
|
32
34
|
## Schema landmines (memorize)
|
|
33
35
|
|
|
@@ -45,7 +47,14 @@ NASSQL parallels:
|
|
|
45
47
|
- **`TOP` / `BOTTOM` use `n`, not `count`.**
|
|
46
48
|
- **`vertex.attr.<name>` is the FROM_TOPOLOGY column convention.**
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
Metrics-Metadata parallels (read before authoring any "slow / fast / noisy / duration / rate / saturation" filter):
|
|
51
|
+
|
|
52
|
+
- **`metric.type` is a bitmask, not an enum value** — composing or filtering by typeEnum is bitwise. A `type` of 268436481 decodes to `MONITOR_INT_DURATION + TYPE_INFO_FRONTEND`. Full bit-region map + name→value table in `corpus_get('cookbooks', 'metrics-grounding')`.
|
|
53
|
+
- **The `TYPE` AttributeNameSpecifier requires its inner `specifier` field** — schema marks it optional, server returns 400 without it. Pass `{ op: "ALL" }` as a no-op inner.
|
|
54
|
+
- **AND-trap for same-class MONITOR_* names** — picking both `MONITOR_INT_DURATION` and `MONITOR_LONG_DURATION` composes to `bitMask = bitMatch = 0x403`, which requires bits 0 AND 1 simultaneously (mutually exclusive INT/LONG underlying-type bits) → zero results silently. For "any INT or LONG or DOUBLE of this class", use the `ANY_*` axis names instead: `ANY_DURATION` (= `0x400`), `ANY_RATE` (= `0x200`), `ANY_COUNTER` (= `0x100`), `ANY_PERCENTAGE` (= `0x1000`), `ANY_INTERVAL_COUNTER` (= `0x2000`), `ANY_SATURATION` (= `0x4000`).
|
|
55
|
+
- **Worked examples** — `corpus_get('queries', '40-metadata-filter-by-typeenum')` (axis-only, "any duration") and `'41-metadata-frontend-durations'` (multi-chip composition, "any duration AND frontend-flagged").
|
|
56
|
+
|
|
57
|
+
Full list in `corpus_get('cookbooks', 'tas-quickstart')` and `'nassql-quickstart'` (top of each); MM specifics in `corpus_get('cookbooks', 'mm-quickstart')` and `'metrics-grounding'`.
|
|
49
58
|
|
|
50
59
|
## Tool defaults
|
|
51
60
|
|
|
@@ -70,6 +79,18 @@ run_query ← final execution (against
|
|
|
70
79
|
create_query ← save, then hand off
|
|
71
80
|
```
|
|
72
81
|
|
|
82
|
+
When the question is about ALARMS (not topology, not metrics — actual OI alarms: alert breaches, host-down, service-health drops, log conditions, EUM/AXA events):
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
corpus_get('cookbooks', 'alarms-quickstart') ← first turn touching alarms in any session
|
|
86
|
+
list_alarms ← the answer (defaults to open-only, 1h window)
|
|
87
|
+
get_alarm / get_alarm_lifecycle / ← drilldowns
|
|
88
|
+
get_related_alarms
|
|
89
|
+
list_alarm_queues ← when the user names a saved filter
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Alarms are a separate API — `list_alarms`, not `run_query`. Don't try to author a TAS / NASSQL / MM query "for alarms" — there isn't one. The alarms surface returns its own document shape and has its own vocabulary (`status` UPPERCASE, `severity` lowercase, `external_ids[]` round-trips back to TAS, `services_impacted` only on the lifecycle).
|
|
93
|
+
|
|
73
94
|
**Don't** guess attribute names, layer names, service names, or vertex types. Always discover. The cost is one tool call; the reward is correctness.
|
|
74
95
|
|
|
75
96
|
## Handoff phrasing
|
|
@@ -102,3 +123,6 @@ When more clarification is needed before authoring:
|
|
|
102
123
|
- `corpus_get('cookbooks', 'gotchas')` — empirical surprises across all of the above.
|
|
103
124
|
- `corpus_get('cookbooks', 'run-query-vs-run-partial')` — full vs partial execution choice.
|
|
104
125
|
- `corpus_get('cookbooks', 'tas-quickstart')` / `'nassql-quickstart'` / `'mm-quickstart'` — schema-level details when authoring.
|
|
126
|
+
- `corpus_get('cookbooks', 'metrics-grounding')` — `metric.type` bitmask layout, typeEnum table, `ANY_*` axis names; load before authoring any "slow / fast / noisy / duration / rate" MM filter.
|
|
127
|
+
- `corpus_get('cookbooks', 'alarms-quickstart')` — the "are there any alarms?" entry point; `status` vs `severity` axes; recipes for open/closed/severity/host-scoped/queue-scoped lookups.
|
|
128
|
+
- `corpus_get('cookbooks', 'alarms-cookbook')` — full Alarm document shape, the timestamp map (which fields are populated and which are interface-only), alarm-queue semantics, lifecycle-event taxonomy (including where `services_impacted` actually lives).
|