@dx-do/cli 5.2.49 → 6.0.1

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.
Files changed (185) hide show
  1. package/README.md +24 -6
  2. package/dist-node/01-discover-vertices.tas-pwngv2fz.md +31 -0
  3. package/dist-node/01-discover-vertices.tas.data-store-svjfrm1f.json5 +29 -0
  4. package/dist-node/01-discover-vertices.tas.data-store-tmd-w650nfzt.json +4 -0
  5. package/dist-node/02-discover-services.tas-867m0m88.md +30 -0
  6. package/dist-node/02-discover-services.tas.data-store-jz0gx5vn.json5 +40 -0
  7. package/dist-node/02-discover-services.tas.data-store-tmd-eq264m6y.json +4 -0
  8. package/dist-node/03-discover-sources.nassql-4tgp9jvv.md +34 -0
  9. package/dist-node/03-discover-sources.nassql.data-store-by6sqk23.json5 +63 -0
  10. package/dist-node/03-discover-sources.nassql.data-store-tmd-n3gy57wm.json +4 -0
  11. package/dist-node/04-discover-metadata-columns.nassql-vhzb0mrq.md +26 -0
  12. package/dist-node/04-discover-metadata-columns.nassql.data-store-c9zr7p0q.json5 +35 -0
  13. package/dist-node/04-discover-metadata-columns.nassql.data-store-tmd-4ygrjvty.json +4 -0
  14. package/dist-node/10-filter-attribute-matches.tas-tafqmtw1.md +33 -0
  15. package/dist-node/10-filter-attribute-matches.tas.data-store-tmd-m2sendv0.json +4 -0
  16. package/dist-node/10-filter-attribute-matches.tas.data-store-whdc6vbc.json5 +35 -0
  17. package/dist-node/11-filter-and-compose.tas-m8856738.md +29 -0
  18. package/dist-node/11-filter-and-compose.tas.data-store-dh5meyk8.json5 +56 -0
  19. package/dist-node/11-filter-and-compose.tas.data-store-tmd-mfn8a16f.json +4 -0
  20. package/dist-node/12-filter-or-not.tas-21zab96s.md +35 -0
  21. package/dist-node/12-filter-or-not.tas.data-store-7vjr4fnd.json5 +83 -0
  22. package/dist-node/12-filter-or-not.tas.data-store-tmd-am9smwe5.json +4 -0
  23. package/dist-node/13-filter-layer.tas-r1ff5anv.md +29 -0
  24. package/dist-node/13-filter-layer.tas.data-store-5mneyz77.json5 +30 -0
  25. package/dist-node/13-filter-layer.tas.data-store-tmd-9qmhyfzr.json +4 -0
  26. package/dist-node/14-filter-traverse.tas-da9jene0.md +38 -0
  27. package/dist-node/14-filter-traverse.tas.data-store-p0vxtfvj.json5 +63 -0
  28. package/dist-node/14-filter-traverse.tas.data-store-tmd-5hepg5wf.json +4 -0
  29. package/dist-node/15-filter-take-vertices-edges.tas-m160qc7z.md +35 -0
  30. package/dist-node/15-filter-take-vertices-edges.tas.data-store-drmcme43.json5 +46 -0
  31. package/dist-node/15-filter-take-vertices-edges.tas.data-store-tmd-8fewsp5s.json +4 -0
  32. package/dist-node/16-filter-projection.tas-dh39mcx8.md +31 -0
  33. package/dist-node/16-filter-projection.tas.data-store-tmd-3r8anggx.json +4 -0
  34. package/dist-node/16-filter-projection.tas.data-store-xjbdry1x.json5 +36 -0
  35. package/dist-node/17-filter-lucene.tas-gyvtzwaa.md +29 -0
  36. package/dist-node/17-filter-lucene.tas.data-store-1knw6srt.json5 +39 -0
  37. package/dist-node/17-filter-lucene.tas.data-store-tmd-5cf3tygg.json +5 -0
  38. package/dist-node/18-filter-variable-reuse.tas-89fq0y6x.md +46 -0
  39. package/dist-node/18-filter-variable-reuse.tas.data-store-by35113t.json5 +55 -0
  40. package/dist-node/18-filter-variable-reuse.tas.data-store-tmd-ak7aprgk.json +4 -0
  41. package/dist-node/19-filter-order-statefilter.tas-hm3z71qj.md +36 -0
  42. package/dist-node/19-filter-order-statefilter.tas.data-store-ra9hj1rz.json5 +51 -0
  43. package/dist-node/19-filter-order-statefilter.tas.data-store-tmd-wqer9xy2.json +4 -0
  44. package/dist-node/20-nassql-from-metadata-basic.nassql-szr2xax1.md +28 -0
  45. package/dist-node/20-nassql-from-metadata-basic.nassql.data-store-tmd-c7drxs1m.json +4 -0
  46. package/dist-node/20-nassql-from-metadata-basic.nassql.data-store-zdf1gp1v.json5 +42 -0
  47. package/dist-node/21-nassql-from-metadata-regex.nassql-78jnsn3e.md +30 -0
  48. package/dist-node/21-nassql-from-metadata-regex.nassql.data-store-ckzsv7h1.json5 +53 -0
  49. package/dist-node/21-nassql-from-metadata-regex.nassql.data-store-tmd-zgr6r9my.json +4 -0
  50. package/dist-node/22-nassql-from-topology.nassql-a71qw9r0.md +42 -0
  51. package/dist-node/22-nassql-from-topology.nassql.data-store-81m23nge.json5 +58 -0
  52. package/dist-node/22-nassql-from-topology.nassql.data-store-tmd-vhpjy6c7.json +4 -0
  53. package/dist-node/23-nassql-join-topology-metadata.nassql-hywxhcg2.md +35 -0
  54. package/dist-node/23-nassql-join-topology-metadata.nassql.data-store-da7q90n2.json5 +76 -0
  55. package/dist-node/23-nassql-join-topology-metadata.nassql.data-store-tmd-rr8wt9qa.json +4 -0
  56. package/dist-node/24-nassql-from-data-window-mean.nassql-q6qsgdxw.md +33 -0
  57. package/dist-node/24-nassql-from-data-window-mean.nassql.data-store-j7xmg7fc.json5 +81 -0
  58. package/dist-node/24-nassql-from-data-window-mean.nassql.data-store-tmd-qgzz2f7v.json +4 -0
  59. package/dist-node/25-nassql-group-order-top.nassql-awgnwn3r.md +30 -0
  60. package/dist-node/25-nassql-group-order-top.nassql.data-store-cmrn300b.json5 +48 -0
  61. package/dist-node/25-nassql-group-order-top.nassql.data-store-tmd-7xpqeh7c.json +4 -0
  62. package/dist-node/26-nassql-filter-predicate.nassql-2t27h5ev.md +41 -0
  63. package/dist-node/26-nassql-filter-predicate.nassql.data-store-k2rgp609.json5 +59 -0
  64. package/dist-node/26-nassql-filter-predicate.nassql.data-store-tmd-m4dddgwm.json +4 -0
  65. package/dist-node/27-nassql-distinct-keep.nassql-6z55dvk3.md +24 -0
  66. package/dist-node/27-nassql-distinct-keep.nassql.data-store-mrx00ys5.json5 +52 -0
  67. package/dist-node/27-nassql-distinct-keep.nassql.data-store-tmd-0p9hy42g.json +4 -0
  68. package/dist-node/28-nassql-format-time.nassql-6wraqgdk.md +30 -0
  69. package/dist-node/28-nassql-format-time.nassql.data-store-tmd-bbbqhz1x.json +4 -0
  70. package/dist-node/28-nassql-format-time.nassql.data-store-tvy8y2cs.json5 +59 -0
  71. package/dist-node/29-nassql-describe-log.nassql-t9vnxeb0.md +31 -0
  72. package/dist-node/29-nassql-describe-log.nassql.data-store-tmd-q4mtczy8.json +4 -0
  73. package/dist-node/29-nassql-describe-log.nassql.data-store-x16y4crx.json5 +51 -0
  74. package/dist-node/30-nassql-map-string.nassql-f2tdknzs.md +30 -0
  75. package/dist-node/30-nassql-map-string.nassql.data-store-t8ahcabn.json5 +53 -0
  76. package/dist-node/30-nassql-map-string.nassql.data-store-tmd-a6xq0bdx.json +4 -0
  77. package/dist-node/31-nassql-join-data-sum.nassql-p16y3xk6.md +26 -0
  78. package/dist-node/31-nassql-join-data-sum.nassql.data-store-dje7wm6v.json5 +64 -0
  79. package/dist-node/31-nassql-join-data-sum.nassql.data-store-tmd-c1pyx1qw.json +4 -0
  80. package/dist-node/32-nassql-bottom-aggregation.nassql-hpgfn77p.md +26 -0
  81. package/dist-node/32-nassql-bottom-aggregation.nassql.data-store-tmd-p0ssj1vc.json +4 -0
  82. package/dist-node/32-nassql-bottom-aggregation.nassql.data-store-v9580caa.json5 +43 -0
  83. package/dist-node/33-nassql-cross-domain-pipeline.nassql-fm0ynphf.md +45 -0
  84. package/dist-node/33-nassql-cross-domain-pipeline.nassql.data-store-tmd-18881drs.json +4 -0
  85. package/dist-node/33-nassql-cross-domain-pipeline.nassql.data-store-vqs9hkx4.json5 +79 -0
  86. package/dist-node/3rdpartylicenses-hx59bakt.txt +885 -0
  87. package/dist-node/50-discover-custom-layers.tas-2hvvpkzw.md +66 -0
  88. package/dist-node/50-discover-custom-layers.tas.data-store-h85zgna9.json5 +36 -0
  89. package/dist-node/50-discover-custom-layers.tas.data-store-tmd-hagn9eak.json +4 -0
  90. package/dist-node/51-collect-counts-everything.tas-nz0ksgdc.md +46 -0
  91. package/dist-node/51-collect-counts-everything.tas.data-store-eypcjah8.json5 +48 -0
  92. package/dist-node/51-collect-counts-everything.tas.data-store-tmd-4pcj94s9.json +4 -0
  93. package/dist-node/52-collect-counts-bulk.tas-eerw4z8s.md +54 -0
  94. package/dist-node/52-collect-counts-bulk.tas.data-store-scedtw1m.json5 +65 -0
  95. package/dist-node/52-collect-counts-bulk.tas.data-store-tmd-csyzj189.json +4 -0
  96. package/dist-node/53-collect-attributes-by-type.tas-cw0285hx.md +71 -0
  97. package/dist-node/53-collect-attributes-by-type.tas.data-store-fvjge4yr.json5 +65 -0
  98. package/dist-node/53-collect-attributes-by-type.tas.data-store-tmd-274qrd8f.json +4 -0
  99. package/dist-node/README-ghxecaz0.md +84 -0
  100. package/dist-node/SKILL-1xn7r9nt.md +104 -0
  101. package/dist-node/agent-25q752kd.md +55 -0
  102. package/dist-node/agent_connection_and_status-0dq7zkpc.md +62 -0
  103. package/dist-node/agent_source_collector-6s06n3rs.md +40 -0
  104. package/dist-node/agentic-mcp-rycd2gh8.md +140 -0
  105. package/dist-node/application-dfva8tz0.md +48 -0
  106. package/dist-node/application-m0q2vaxj.md +74 -0
  107. package/dist-node/attribute_resource_metric_name-pxrceab5.md +56 -0
  108. package/dist-node/browseragent-snippet.template-9megjp8a.html +12 -0
  109. package/dist-node/bulkvertexpatch-1a4qy5vb.md +78 -0
  110. package/dist-node/bundle.pbd-38r15kyd.template +13 -0
  111. package/dist-node/bundle.profile-1wpzpt3d.template +2 -0
  112. package/dist-node/business_transaction-mbqz5ex9.md +61 -0
  113. package/dist-node/chunk-4I3HBO6U-2ebgf7kh.js +127 -0
  114. package/dist-node/chunk-4PMCLJMS-0mqvr4m4.js +1 -0
  115. package/dist-node/chunk-5VSFINOX-ewzpx7wh.js +5 -0
  116. package/dist-node/chunk-72HYG3XZ-kf7hy4vs.js +3625 -0
  117. package/dist-node/chunk-JRM4BLOM-rg32z8w4.js +1 -0
  118. package/dist-node/chunk-Q2JA73UH-akkb8bh3.js +14 -0
  119. package/dist-node/chunk-RNMHSXZF-pdwasrg7.js +1358 -0
  120. package/dist-node/chunk-VV2FJEMA-3rvtkmga.js +321 -0
  121. package/dist-node/chunk-YVD3UK5I-9pxr1jka.js +695 -0
  122. package/dist-node/configuration-1vczsdex.md +104 -0
  123. package/dist-node/dashboards-x0xddksy.md +17 -0
  124. package/dist-node/database_or_inferred-8vqf5gyr.md +75 -0
  125. package/dist-node/default-licensing-config-0p879qpb.template +122 -0
  126. package/dist-node/dependency-3b0neg5x.md +40 -0
  127. package/dist-node/description.md-qwc2bj9r.template +30 -0
  128. package/dist-node/discovery-flow-fw79kbx4.md +116 -0
  129. package/dist-node/dxi_service-13prnpd5.md +59 -0
  130. package/dist-node/entity-relationships-cevz61kj.md +142 -0
  131. package/dist-node/gotchas-8ab64kcd.md +389 -0
  132. package/dist-node/host-es6fxtgx.md +46 -0
  133. package/dist-node/host-j3qqrm5f.md +55 -0
  134. package/dist-node/index-104hyb1m.html +13 -0
  135. package/dist-node/index-7fp2dfas.json +178 -0
  136. package/dist-node/index-g3hh5wez.json +403 -0
  137. package/dist-node/index-mbzg9rhc.json +270 -0
  138. package/dist-node/index-qffdhwgm.json +2479 -0
  139. package/dist-node/inferred-w998vfq1.md +41 -0
  140. package/dist-node/installInstructions.md-k9ghf3dr.template +21 -0
  141. package/dist-node/inventorize-xc9h9bjr.md +34 -0
  142. package/dist-node/investigation-planning-6kcm01h9.md +149 -0
  143. package/dist-node/investigator-flow-jc2s0n46.md +186 -0
  144. package/dist-node/k8s_deployment_and_namespace-69c29152.md +88 -0
  145. package/dist-node/k8s_pod_and_container-9h4v6cmj.md +64 -0
  146. package/dist-node/main-SGLYO5YX-ht69eb0y.js +13 -0
  147. package/dist-node/main.js +397415 -0
  148. package/dist-node/marketplace-srdmzxkj.json +15 -0
  149. package/dist-node/metric-source-names-6cbczyks.md +75 -0
  150. package/dist-node/metrics-grounding-2h4kkbe3.md +130 -0
  151. package/dist-node/mm-cookbook-23jpw721.md +231 -0
  152. package/dist-node/mm-quickstart-x2adfc16.md +106 -0
  153. package/dist-node/nassql-cookbook-n8kc0mff.md +812 -0
  154. package/dist-node/nassql-quickstart-090e0yex.md +149 -0
  155. package/dist-node/plugin-c3bavxvf.json +18 -0
  156. package/dist-node/polyfills-A7ZF72EO-mp884a0b.js +2 -0
  157. package/dist-node/prerendered-routes-523d8gat.json +3 -0
  158. package/dist-node/primeicons-4GST5W3O-jac3wxrf.woff2 +0 -0
  159. package/dist-node/primeicons-DHQU4SEP-760n99pp.svg +345 -0
  160. package/dist-node/primeicons-GEFHGEHP-rc4kaa3b.ttf +0 -0
  161. package/dist-node/primeicons-P53SE5CV-4saz3d5j.woff +0 -0
  162. package/dist-node/primeicons-RSSEDYLY-4d4vbd67.eot +0 -0
  163. package/dist-node/query-vs-analysis-separation-sag1ezcq.md +97 -0
  164. package/dist-node/run-query-vs-run-partial-6138pc94.md +80 -0
  165. package/dist-node/service-5pz5nhzf.md +133 -0
  166. package/dist-node/service-hierarchies-87a4ynpj.md +178 -0
  167. package/dist-node/service-k4f5mkbq.md +51 -0
  168. package/dist-node/servlet_or_frontend-1kjcb7ar.md +76 -0
  169. package/dist-node/src-apm-mfnsq6vw.svg +4 -0
  170. package/dist-node/src-axa-nn28yqmj.svg +4 -0
  171. package/dist-node/src-dxim-fv7ne4qa.svg +4 -0
  172. package/dist-node/styles-23VUPSCU-9ehggc1f.css +1 -0
  173. package/dist-node/tas-cookbook-0y4826rp.md +693 -0
  174. package/dist-node/tas-quickstart-wgcvwffc.md +138 -0
  175. package/dist-node/time-format-0595g01j.md +41 -0
  176. package/dist-node/toggles.pbd-9wscbmng.template +2 -0
  177. package/dist-node/type-host-agbhmn6v.svg +6 -0
  178. package/dist-node/type-metric-p9b90bpx.svg +4 -0
  179. package/dist-node/type-service-k7f1x71k.svg +4 -0
  180. package/dist-node/ui-0b5grqrg.md +113 -0
  181. package/dist-node/universe-b9nhf325.md +47 -0
  182. package/dist-node/universe-fzpwzvxr.md +91 -0
  183. package/dist-node/universes-and-scopes-1cb9pfk7.md +105 -0
  184. package/dist-node/vertex_entity_node-mm3yp9d0.md +31 -0
  185. package/package.json +1 -1
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "dx-do",
3
+ "owner": {
4
+ "name": "Ki Alam",
5
+ "url": "https://github.com/zoobroker"
6
+ },
7
+ "description": "DXO2 plugins for Claude Code — one per activity (investigate, operate, admin, …). All share the dx-do-query MCP server and the @dx-do/catalog grounding content.",
8
+ "plugins": [
9
+ {
10
+ "name": "investigate",
11
+ "source": "./investigate",
12
+ "description": "Investigate a DXO2 tenant — guided discovery, query authoring, and UI/analyzer handoff."
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,75 @@
1
+ ---
2
+ id: metric-source-names
3
+ title: Metric source naming convention — the `<domain>|<host>|<bus>|<role>` shape
4
+ applies_to: nassql
5
+ tags: [reference, naming, gotcha]
6
+ related: [nassql-quickstart, mm-quickstart, gotchas, discovery-flow]
7
+ ---
8
+
9
+ # Metric source naming
10
+
11
+ `metric.source` values are **pipe-delimited multi-segment strings** that identify the producer of a metric datapoint. Getting the regex shape wrong is the single most common reason an otherwise-correct NASSQL FROM pipeline returns zero rows. This cookbook covers the canonical shapes and the empirical-discovery move you should reach for when an unfamiliar tenant doesn't match what you expect.
12
+
13
+ ## The general shape
14
+
15
+ ```
16
+ <domain>|<host-or-agent-id>|<bus>|<role>[|<extra-segments>...]
17
+ ```
18
+
19
+ - **`<domain>`** — the source family. The most common value is `SuperDomain` (the default for Infrastructure-agent metrics). Other domains seen in the wild: `SystemEdge`, custom enterprise domains. **This is the segment most agents forget about** — they jump straight to the host name and write `.*<host>.*`, which doesn't match anything because every source starts with a domain prefix.
20
+ - **`<host-or-agent-id>`** — usually the host name, sometimes a synthetic agent identifier. May be a bare hostname (`host-001`) or fully-qualified (`host-001.us-west1-b.c.example.internal`). The form depends on how the agent was registered.
21
+ - **`<bus>`** — the metric bus / category (`Infrastructure`, `TopProcess`, `BusinessTransaction`, etc.).
22
+ - **`<role>`** — the producer role within that bus (`Agent`, `TopNProcessByCPU`, etc.). For Infrastructure agents this is literally `Agent`.
23
+
24
+ ## Canonical examples
25
+
26
+ | Source string | Shape |
27
+ |---|---|
28
+ | `SuperDomain\|host-001\|Infrastructure\|Agent` | 4-segment Infrastructure-agent (the most common shape). |
29
+ | `SystemEdge\|host-001.us-west1-b.c.example.internal\|TopProcess\|TopNProcessByCPU\|3:Parent PID Number` | 5-segment SystemEdge probe with a sub-category. |
30
+
31
+ ## Regex authoring rules
32
+
33
+ When you write a `metric.source` REGEX in a `sourceNameSpecifier`:
34
+
35
+ 1. **`|` is a regex meta-character.** Always escape it as `\|` in the pattern. A bare `|` will match anything (it's regex-OR).
36
+ 2. **Don't omit the leading segment.** A pattern like `.*host-001.*` is a common reflex — but it implicitly requires the host name to appear *somewhere*, which means it ALSO has to match the leading `<domain>|` prefix, which it does NOT (because there's no `.*` consuming the domain part). Either anchor with the domain (`^SuperDomain\|host-001\|...`) or use a wildcard explicitly between segments.
37
+ 3. **Anchor or don't — be deliberate.** Anchored (`^...$`) is faster and unambiguous. Unanchored (`.*...`) is forgiving but may pull in unintended sources from other buses.
38
+ 4. **Wildcards across segments use `.`, not `\|`.** `.*host-001.Infrastructure.Agent` (with bare `.` between segments) is a valid loose pattern — works because `.` matches the literal `|` along with anything else. Slightly wasteful but readable.
39
+
40
+ ## The empirical-discovery move
41
+
42
+ When you don't know the source-name shape on a tenant — **do not guess from host names**. Run a FROM_METADATA probe and inspect actual source values:
43
+
44
+ ```json
45
+ {
46
+ "query": [
47
+ {"op": "FROM_METADATA",
48
+ "querySpecifier": {"op": "SPEC",
49
+ "sourceNameSpecifier": {"op": "REGEX", "pattern": ".*<host-or-id-fragment>.*"},
50
+ "attributeNameSpecifier": {"op": "REGEX", "pattern": ".*"}}},
51
+ {"op": "KEEP", "columns": ["metric.source", "metric.path"]}
52
+ ],
53
+ "limit": 20
54
+ }
55
+ ```
56
+
57
+ Use `run_partial_query` with `upToStep: 0` for the cheapest possible probe (just the FROM_METADATA call, no transforms). Read the actual `metric.source` values back, then write your real query against the discovered shape.
58
+
59
+ This is also the fastest way to figure out which **`<domain>`** values exist on a tenant — especially when an enterprise customer has provisioned non-`SuperDomain` agents.
60
+
61
+ ## Common mistakes (from the foray)
62
+
63
+ | What the agent tried | Why it returned empty | The fix |
64
+ |---|---|---|
65
+ | `.*host-001.*` against `metric.source` | No `SuperDomain\|` prefix consumed; pattern doesn't span the literal `|` separators correctly. | `^SuperDomain\|host-001\|.*` or `.*host-001.Infrastructure.Agent` |
66
+ | `.*<bare-host>.*` with `\|` in pattern as `|` (unescaped) | The `|` parses as regex-OR, blowing up the intended structure. | Escape as `\|` or use bare `.`. |
67
+ | Probing source names with `run_query` (full execute) instead of a partial | Wastes a full pipeline run for what's actually a one-step inspection. | `run_partial_query` with `upToStep: 0`. |
68
+
69
+ ## See also
70
+
71
+ - `nassql-quickstart` — the FROM / FROM_METADATA / FROM_DATA decision (this cookbook covers the source-pattern shape that those ops consume).
72
+ - `mm-quickstart` — Metrics Metadata specifiers (the `sourceNameSpecifier` field is the same shape).
73
+ - `gotchas` — promotes the empty-payload trap + auto-numbered shortName + this cookbook's source-pattern trap to the top.
74
+ - `discovery-flow` — the broader discovery hierarchy.
75
+ - `entities/agent` — the entity that *produces* these source names.
@@ -0,0 +1,130 @@
1
+ ---
2
+ id: metrics-grounding
3
+ title: Metrics grounding — the semantic layer beyond MM mechanics
4
+ applies_to: metadata
5
+ tags: [reference, authoring]
6
+ related: [metric-source-names, mm-cookbook, mm-quickstart, entity-relationships, investigation-planning]
7
+ ---
8
+
9
+ # Metrics grounding
10
+
11
+ `mm-quickstart` and `mm-cookbook` cover the *mechanics* of authoring metric-metadata queries. This cookbook covers the **semantics** — what a metric *means* in DXO2's entity model, how to navigate from a metric back to the producing agent (or accept that no entity exists), and how to handle the most common surprise: metrics for resources that have no topology vertex.
12
+
13
+ ## Metric identity, four ways
14
+
15
+ The same metric is referred to by different names depending on which surface you're on:
16
+
17
+ | Name | Where you see it |
18
+ |---|---|
19
+ | `metric.source` + `metric.path` | NASSQL `FROM_METADATA` columns |
20
+ | MM `SourceNameSpecifier` + `AttributeNameSpecifier` | Metrics-Metadata query input |
21
+ | `<resource>:<metric>` | User shorthand — the `metric.path` ending after the last `:` is the metric name; the prefix is the "resource" |
22
+ | `metric.attribute` (older) | Older API field — alias for the path's leaf segment |
23
+
24
+ Concretely, a metric like `Beans|Nass Reactive Client|Store|Flush|Unregistered Queue:Concurrent Invocations` carries:
25
+
26
+ - `metric.source` = `SuperDomain|host-001|Custom Metric Process|Custom Metric Agent` (the producer).
27
+ - `metric.path` = the pipe-delimited folder breadcrumb ending with `:Concurrent Invocations`.
28
+ - User shorthand: `Unregistered Queue:Concurrent Invocations` (resource = breadcrumb tail; metric name = post-`:`).
29
+
30
+ For the field-level rules see `lexicon/attribute_resource_metric_name`.
31
+
32
+ ## The agent ↔ metric bridge
33
+
34
+ Most metrics tie back to an **AGENT vertex** via a known path. The bridge:
35
+
36
+ 1. From a topology vertex (HOST, BUSINESSTRANSACTION, k8s_POD), TRAVERSE `agent-monitors` (incoming) → AGENT vertex.
37
+ 2. From the AGENT, the `agentName` attribute (or part of `metric.source`) connects to MM.
38
+ 3. Query MM by `metric.source` matching a regex of the agent's identity, or use `discovery_metrics_for_entity` (which builds the canonical metric query body for a vertex).
39
+
40
+ The AGENT is the *producer*; metrics flow from it. If you only have a metric and you want to find its agent: split `metric.source` on `|`, look at the second-to-last segment (often the `agent` identity), and search AGENT vertices.
41
+
42
+ ## Orphaned-by-design metrics
43
+
44
+ **Not every metric has a topology vertex.** This is the single biggest grounding gap a query agent runs into. The canonical example: **JMX metrics**.
45
+
46
+ A JMX-instrumented JVM exposes hundreds of MBeans — connection pools, thread pools, cache regions, queue stats, GC details. The platform's JMX agent forwards these as metrics under the JVM's source. But:
47
+
48
+ - There is usually **one** `JMX_SYSTEM` vertex per monitored JVM, not one vertex per pool.
49
+ - There is **no `JDBC_CONNECTION_POOL` vertex type** by default.
50
+ - The pool, queue, or cache identity exists *only in the metric path*.
51
+
52
+ If a user asks "how are the database connection pools for application X doing", the wrong move is "search for `type=JDBC_CONNECTION_POOL`" — that returns nothing. The right move is:
53
+
54
+ 1. Find the application X (DXO2 service / k8s_DEPLOYMENT / `applicationName` — see `cookbooks/investigation-planning`).
55
+ 2. Find the agents producing metrics for X — typically a Java APM agent and a JMX agent.
56
+ 3. Query MM under those agents for paths matching pool-flavored regex: `.*JDBC.*Pool.*` or `.*Connection Pool.*` or similar.
57
+ 4. Group/aggregate by the pool segment of the path to get per-pool numbers.
58
+
59
+ The metric *value* is sometimes the only place identity lives — e.g. a `queue_name` metric that's a string `queue://host-2/orders`. In that case, NASSQL `FROM_DATA` to extract values, then group/filter on the value.
60
+
61
+ When this pattern repeats for the same customer / same kind of resource, **inventorize** materializes a vertex per resource so future queries can use vertex traversal. See `lexicon/inventorize`.
62
+
63
+ ## Metric `type` is opaque (for now)
64
+
65
+ Every metric carries a numeric `type` field with values like `0`, `1`, `2`, `3`. The numeric ID indicates the metric's data shape (gauge, counter, rate, etc.) and informs how it should be aggregated and displayed.
66
+
67
+ **The numeric → semantic mapping is not yet documented in the corpus.** Treat `metric.type` as opaque: when you need to aggregate or order, prefer empirical inspection of values via `run_partial_query` rather than assuming a particular type means a particular aggregation. A future grounding pass will close this gap.
68
+
69
+ ## Pattern recognition: deciding when to inventorize
70
+
71
+ If you see all three of these for the same resource pattern, inventorizing is probably right:
72
+
73
+ 1. The user keeps asking about the resource by name — it's part of their vocabulary.
74
+ 2. The metrics for the resource are reliable and stable (same source, same path shape, same regular intervals).
75
+ 3. There's no existing vertex type that matches.
76
+
77
+ In that case, an **inventorize rule** (`inventory create-inventorize-rule`) materializes a vertex per match. The vertex gets a `CUSTOM_INVENTORIZE_<N>` type by default; you can give it a more specific name. After the rule runs, future queries can use the new type as a first-class anchor.
78
+
79
+ ## Practical authoring patterns
80
+
81
+ ### Pattern 1 — find metrics for a known vertex
82
+
83
+ ```
84
+ discovery_metrics_for_entity(vertexId="<id>")
85
+ ```
86
+
87
+ Returns the canonical metric query body the platform's mapping configuration says applies. Use this when you have the vertex.
88
+
89
+ ### Pattern 2 — find metrics matching a name pattern
90
+
91
+ ```js
92
+ // MM query
93
+ {
94
+ "querySpecifier": {
95
+ "op": "AND",
96
+ "input": [
97
+ { "op": "ATTRIBUTE_NAME", "values": [".*Connection Pool.*"], "queryType": "REGEX" }
98
+ ]
99
+ },
100
+ "limit": 200
101
+ }
102
+ ```
103
+
104
+ Use this for orphaned metrics. Adjust the regex to taste.
105
+
106
+ ### Pattern 3 — find which agent produced a metric
107
+
108
+ ```js
109
+ // NASSQL
110
+ { "query": [
111
+ { "op": "FROM_METADATA", "querySpecifier": { ... }, "alias": "m" },
112
+ { "op": "GROUP", "columns": ["metric.source"] },
113
+ { "op": "COUNT", "as": "n" }
114
+ ], "limit": 50 }
115
+ ```
116
+
117
+ Group by source to see the producer distribution. Then look up each source as an AGENT.
118
+
119
+ ### Pattern 4 — compare multiple agents reporting the "same" metric
120
+
121
+ A backend or BT may show up under multiple agents. To compare, NASSQL `FROM_DATA` joined to `FROM_TOPOLOGY` (or grouped by `metric.source`) gives per-agent slices. Sum/average for the unified view.
122
+
123
+ ## See also
124
+
125
+ - `cookbooks/metric-source-names` — pipe-delimited source name anatomy.
126
+ - `cookbooks/mm-cookbook` — full specifier vocabulary.
127
+ - `cookbooks/investigation-planning` — when to reach for metric-first vs entity-first.
128
+ - `lexicon/attribute_resource_metric_name` — the four-name terminology.
129
+ - `lexicon/inventorize` — promoting metric patterns into vertices.
130
+ - `entities/jmx_system` — the canonical orphaned-metrics case.
@@ -0,0 +1,231 @@
1
+ ---
2
+ id: mm-cookbook
3
+ title: Metrics Metadata cookbook — specifier reference and recipe catalog
4
+ applies_to: metadata
5
+ tags: [reference, recipes, authoring]
6
+ related: [mm-quickstart, nassql-cookbook, gotchas]
7
+ ---
8
+
9
+ # Metrics Metadata cookbook
10
+
11
+ Full specifier-vocabulary reference for Metrics Metadata
12
+ (`/metadata/queryMetric`) authoring, plus a recipe catalog. The same
13
+ `QuerySpecifier` vocabulary documented here is also embedded inside NASSQL
14
+ `FROM_METADATA` and `JOIN_METADATA` ops — so this cookbook is required
15
+ reading for NASSQL authors too.
16
+
17
+ Use after `mm-quickstart.md` when you need the full sub-specifier
18
+ breakdown or a concrete pattern to start from.
19
+
20
+ ## Specifier mental model
21
+
22
+ A `QuerySpecifier` describes a **set of metric metadata records**. It is a
23
+ discriminated union on `op`. The richest op is `SPEC`, which has three
24
+ sub-specifier slots:
25
+
26
+ ```mermaid
27
+ flowchart TB
28
+ spec["QuerySpecifier (op-discriminated)"] --> simple["leaves: ALL / NONE / ID / GROUP / SERVICE / ATTRIBUTE"]
29
+ spec --> compose["composers: AND / OR / NOT"]
30
+ spec --> structured["SPEC { sourceNameSpecifier, folderNameSpecifier, attributeNameSpecifier }"]
31
+ structured --> sourceSpec["SourceNameSpecifier (ALL / EXACT / REGEX / PART / AND / OR / NOT)"]
32
+ structured --> attrSpec["AttributeNameSpecifier (ALL / EXACT / REGEX / FOLDER / CHILDREN / TYPE / OPERATOR / NUMERIC / ATTRIBUTE / AND / OR / NOT)"]
33
+ ```
34
+
35
+ Why three: a metric is keyed by `<source>` + `<folder/path>` + `<attribute>`,
36
+ so each component has its own specifier sub-language with its own ops.
37
+
38
+ ## Top-level envelope
39
+
40
+ | Field | Type | Purpose |
41
+ |-------|------|---------|
42
+ | `specifier` | `QuerySpecifier` | What metrics to match; omit = `ALL` |
43
+ | `clamp` | number | Cap on result count. **Default new queries to ≤ 500.** Large tenants return MB without this. |
44
+ | `time` | number | Reference time (epoch ms); default = now |
45
+ | `range` | number | Time range in ms around `time` to include recently-inactive metrics |
46
+ | `includeLive` | boolean | Include currently-active live metrics not yet persisted |
47
+ | `includeProfile` | boolean | Include profiling info per metric descriptor |
48
+ | `profileLevel` | string | Granularity of profiling when `includeProfile=true` |
49
+ | `authorizationView` | string | Auth-view restriction |
50
+ | `queryHints` | `QueryHint[]` | `{ "hint": "ForceRange" }` forces time-range search even without an explicit `queryRange` |
51
+
52
+ ## Top-level `QuerySpecifier` ops
53
+
54
+ | Op | Shape | Purpose |
55
+ |----|-------|---------|
56
+ | `ALL` | `{ op: "ALL", includeFolders?, includeMetrics? }` | Every metric |
57
+ | `NONE` | `{ op: "NONE" }` | Empty set |
58
+ | `AND` | `{ op: "AND", specifiers: [...] }` | Intersection |
59
+ | `OR` | `{ op: "OR", specifiers: [...] }` | Union |
60
+ | `NOT` | `{ op: "NOT", specifier: ... }` | Complement |
61
+ | `SPEC` | `{ op: "SPEC", sourceNameSpecifier?, folderNameSpecifier?, attributeNameSpecifier? }` | Structured match (the workhorse) |
62
+ | `ID` | `{ op: "ID", ids: ["m-id-1", ...] }` | By metric id |
63
+ | `ATTRIBUTE` | `{ op: "ATTRIBUTE", expressions: [...] }` | By metric-attribute expression |
64
+ | `GROUP` | `{ op: "GROUP", id?, managementModuleId? }` | By management module / group |
65
+ | `SERVICE` | `{ op: "SERVICE", values: [...] }` | By named service |
66
+
67
+ Note: `AND`/`OR` use `specifiers` (array), `NOT` uses `specifier` (single).
68
+ **Do not** confuse with NASSQL `FILTER` predicates which use `spec`.
69
+
70
+ ## SourceNameSpecifier ops
71
+
72
+ Used inside `SPEC.sourceNameSpecifier`.
73
+
74
+ | Op | Shape | Purpose |
75
+ |----|-------|---------|
76
+ | `ALL` | `{ op: "ALL" }` | Any source |
77
+ | `NONE` | `{ op: "NONE" }` | No source |
78
+ | `EXACT` | `{ op: "EXACT", names: [...], ignoreCase? }` | Exact source-name match |
79
+ | `REGEX` | `{ op: "REGEX", pattern, ignoreCase? }` | Regex match |
80
+ | `PART` | `{ op: "PART", part, partValue?, operator? }` | Match a specific dot-separated segment (0-indexed) |
81
+ | `AND` / `OR` | `{ op, specifiers: [...] }` | Boolean composition |
82
+ | `NOT` | `{ op: "NOT", specifier: ... }` | Complement |
83
+
84
+ `PART.operator`: `EQ | NE | GE | GT | LE | LT`.
85
+
86
+ See `metric-source-names.md` for the canonical `<domain>|<host>|<bus>|<role>`
87
+ shape that source strings follow, and the regex-authoring rules that
88
+ prevent zero-row results.
89
+
90
+ ## AttributeNameSpecifier ops
91
+
92
+ Used inside `SPEC.attributeNameSpecifier`. Richer than the source side
93
+ because metric attribute names form a hierarchy:
94
+
95
+ | Op | Shape | Purpose |
96
+ |----|-------|---------|
97
+ | `ALL` / `NONE` | `{ op }` | Any / no attribute |
98
+ | `EXACT` | `{ op: "EXACT", names: [...], type?, ignoreCase? }` | Exact attribute name |
99
+ | `REGEX` | `{ op: "REGEX", pattern, ignoreCase? }` | Regex match |
100
+ | `FOLDER` | `{ op: "FOLDER", specifier: FolderNameSpecifier }` | Match by folder |
101
+ | `CHILDREN` | `{ op: "CHILDREN", prefix?, recursive? }` | Match attribute children of prefix |
102
+ | `TYPE` | `{ op: "TYPE", specifier?, bitMask?, bitMatch?, operator? }` | Match by type bits |
103
+ | `OPERATOR` | `{ op: "OPERATOR", name?, fullPath?, operator? }` | Match by operator |
104
+ | `NUMERIC` | `{ op: "NUMERIC" }` | Match any numeric attribute |
105
+ | `ATTRIBUTE` | `{ op: "ATTRIBUTE", expressions: [...] }` | Match by metric-attribute expression |
106
+ | `AND` / `OR` | `{ op, specifiers: [...] }` | Boolean composition |
107
+ | `NOT` | `{ op: "NOT", specifier: ... }` | Complement |
108
+
109
+ The simplest combinators are `EXACT` and `REGEX`, which cover the majority
110
+ of real queries.
111
+
112
+ ## FolderNameSpecifier
113
+
114
+ A sub-language for folder paths, used inside an
115
+ `AttributeNameSpecifier` of op `FOLDER`.
116
+
117
+ | Op | Shape | Purpose |
118
+ |----|-------|---------|
119
+ | `ALL` / `NONE` | `{ op }` | Any / no folder |
120
+ | `EXACT` | `{ op: "EXACT", names: [...], ignoreCase? }` | Exact folder name |
121
+ | `REGEX` | `{ op: "REGEX", pattern, ignoreCase? }` | Regex match |
122
+ | `CHILDREN` | `{ op: "CHILDREN", prefix?, recursive? }` | Children of prefix path |
123
+ | `AND` / `OR` | `{ op, specifiers: [...] }` | Boolean composition |
124
+ | `NOT` | `{ op: "NOT", specifier: ... }` | Complement |
125
+
126
+ Metric attribute names are organized in a virtual folder hierarchy using
127
+ dots as separators. `prefix` is a dot-delimited parent path.
128
+
129
+ ## Recipe catalog
130
+
131
+ ### "All metrics on the tenant (smoke / count)"
132
+
133
+ ```json
134
+ {
135
+ "specifier": { "op": "ALL" },
136
+ "clamp": 10,
137
+ "range": 480000,
138
+ "includeLive": true
139
+ }
140
+ ```
141
+
142
+ ### "Metrics with source matching a regex"
143
+
144
+ ```json
145
+ {
146
+ "specifier": {
147
+ "op": "SPEC",
148
+ "sourceNameSpecifier": { "op": "REGEX", "pattern": ".*Infrastructure.*" }
149
+ },
150
+ "clamp": 100
151
+ }
152
+ ```
153
+
154
+ ### "Metrics with attribute matching a regex"
155
+
156
+ ```json
157
+ {
158
+ "specifier": {
159
+ "op": "SPEC",
160
+ "attributeNameSpecifier": { "op": "REGEX", "pattern": ".*CPU.*Utilization.*" }
161
+ },
162
+ "clamp": 100
163
+ }
164
+ ```
165
+
166
+ ### "Metrics for a specific source name (exact)"
167
+
168
+ ```json
169
+ {
170
+ "specifier": {
171
+ "op": "SPEC",
172
+ "sourceNameSpecifier": { "op": "EXACT", "names": ["Infrastructure|host01|CPU"] }
173
+ },
174
+ "clamp": 50
175
+ }
176
+ ```
177
+
178
+ ### "Cross-product: source regex AND attribute regex"
179
+
180
+ ```json
181
+ {
182
+ "specifier": {
183
+ "op": "SPEC",
184
+ "sourceNameSpecifier": { "op": "REGEX", "pattern": ".*Infrastructure.*" },
185
+ "attributeNameSpecifier": { "op": "REGEX", "pattern": ".*CPU.*" }
186
+ },
187
+ "clamp": 200
188
+ }
189
+ ```
190
+
191
+ ### "Either of two sources, but exclude a noisy attribute"
192
+
193
+ ```json
194
+ {
195
+ "specifier": {
196
+ "op": "AND",
197
+ "specifiers": [
198
+ { "op": "SPEC",
199
+ "sourceNameSpecifier": { "op": "OR", "specifiers": [
200
+ { "op": "REGEX", "pattern": ".*Infrastructure.*" },
201
+ { "op": "REGEX", "pattern": ".*APM.*" } ] } },
202
+ { "op": "NOT",
203
+ "specifier": { "op": "SPEC",
204
+ "attributeNameSpecifier": { "op": "REGEX", "pattern": ".*Heap.*" } } }
205
+ ]
206
+ },
207
+ "clamp": 100
208
+ }
209
+ ```
210
+
211
+ ### "Metrics by id"
212
+
213
+ ```json
214
+ { "specifier": { "op": "ID", "ids": ["m-id-1", "m-id-2"] } }
215
+ ```
216
+
217
+ ## Authoring tips
218
+
219
+ - For NASSQL embedding, **always wrap REGEX in `SPEC`**. A bare
220
+ `{ op: "REGEX", ... }` is not a valid `QuerySpecifier`. See `gotchas.md`.
221
+ - Use `AND` / `OR` / `NOT` at the **`QuerySpecifier`** level for
222
+ whole-spec composition, not inside the sub-specifiers.
223
+ - The sub-specifiers (`SourceNameSpecifier`, `AttributeNameSpecifier`)
224
+ have their **own** `AND` / `OR` / `NOT` ops scoped to that
225
+ sub-language — useful for "source = (X regex OR Y regex)".
226
+ - `clamp` caps the result count at the metadata service; use it in
227
+ addition to (or instead of) any pagination on the calling code.
228
+ - When the metric-source vocabulary is unknown, run the `FROM_METADATA` +
229
+ `GROUP source` + `COUNT` discovery NASSQL query first
230
+ (`corpus_get("queries", "03-discover-sources")`) to learn real source
231
+ names. See `metric-source-names.md` for the source-string shape.
@@ -0,0 +1,106 @@
1
+ ---
2
+ id: mm-quickstart
3
+ title: Metrics Metadata quickstart — author a metric specifier
4
+ applies_to: metadata
5
+ tags: [getting-started, authoring]
6
+ related: [nassql-quickstart, gotchas]
7
+ ---
8
+
9
+ # Metrics Metadata quickstart
10
+
11
+ MM = metric metadata queries. Returns `{ metrics, folders }` arrays of
12
+ descriptors. The query body is a single recursive **specifier tree**.
13
+
14
+ ## The envelope
15
+
16
+ ```json
17
+ {
18
+ "specifier": { "op": "ALL", "includeMetrics": true },
19
+ "clamp": 500, // strongly recommended — see Gotcha below
20
+ "time": 1700000000000,
21
+ "range": 86400000,
22
+ "includeLive": false,
23
+ "includeProfile": false,
24
+ "profileLevel": null,
25
+ "authorizationView": null
26
+ }
27
+ ```
28
+
29
+ ## Gotcha — set `clamp`
30
+
31
+ Without a `clamp`, the server returns ALL matching metrics. On a real
32
+ tenant that's tens of thousands of descriptors / multiple MB. **Default
33
+ `clamp: 500`** for new MM queries, raise only when needed.
34
+
35
+ ## Top-level specifier ops (10)
36
+
37
+ | Op | Purpose |
38
+ |---|---|
39
+ | `ALL` | Match everything. Use `includeFolders` / `includeMetrics`. |
40
+ | `NONE` | Match nothing. |
41
+ | `AND` / `OR` | Compose specifiers. **Cannot be empty.** |
42
+ | `NOT` | Negate. |
43
+ | `SPEC` | Compose three sub-specifiers (source-name + folder-name + attribute-name). |
44
+ | `ID` | Match specific metric IDs. **`ids` cannot be empty.** |
45
+ | `ATTRIBUTE` | Match by attribute expressions. |
46
+ | `GROUP` | Match a metric group / module. |
47
+ | `SERVICE` | Restrict by service name(s). |
48
+
49
+ ## SPEC — composing the three sub-specifier trees
50
+
51
+ `SPEC` is the powerful pattern. It combines:
52
+
53
+ - `sourceNameSpecifier` — match the source layer name
54
+ - `folderNameSpecifier` — match the folder hierarchy
55
+ - `attributeNameSpecifier` — match the attribute name
56
+
57
+ Each is its own recursive tree with AND/OR/NOT/EXACT/REGEX. AttributeName
58
+ also has CHILDREN, FOLDER, TYPE, OPERATOR, NUMERIC, ATTRIBUTE.
59
+
60
+ Example — APM-sourced CPU metrics in a specific folder:
61
+
62
+ ```json
63
+ {
64
+ "specifier": {
65
+ "op": "SPEC",
66
+ "sourceNameSpecifier": { "op": "EXACT", "names": ["APM"] },
67
+ "folderNameSpecifier": { "op": "CHILDREN", "prefix": "Hosts", "recursive": true },
68
+ "attributeNameSpecifier": { "op": "REGEX", "pattern": "^cpu\\..*" }
69
+ },
70
+ "clamp": 500
71
+ }
72
+ ```
73
+
74
+ ## ID — pinpoint specific metrics
75
+
76
+ ```json
77
+ {
78
+ "specifier": {
79
+ "op": "ID",
80
+ "ids": ["NOB-BE-qP-n5EevJ0B", "ABC-12-..."]
81
+ },
82
+ "clamp": 100
83
+ }
84
+ ```
85
+
86
+ `ids` is required-non-empty. Reading metric IDs from a previous MM query's
87
+ result table (the leftmost column of the metric results) is the typical
88
+ pattern.
89
+
90
+ ## Iteration
91
+
92
+ MM has no partial-run primitive (single specifier — no obvious slice
93
+ point). Run the full query, narrow the specifier, run again.
94
+
95
+ ## Discovery
96
+
97
+ `discovery_metrics` returns up to 1000 metric attribute names known on
98
+ the tenant. Useful to validate `ATTRIBUTE` expression names before
99
+ running.
100
+
101
+ ## See also
102
+
103
+ - `mm-cookbook.md` — full specifier reference, recipe catalog, sub-specifier composition
104
+ - `gotchas.md` — `ID.ids` empty-array surprise (now caught by .min(1))
105
+ - `nassql-quickstart.md` — for embedding MM specifiers in NASSQL FROM_METADATA / JOIN_METADATA
106
+ - Live examples: `corpus_list("queries", {type: "metadata"})` — fetch full payloads with `corpus_get("queries", "<id>")`.