@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,41 @@
1
+ ---
2
+ id: inferred
3
+ title: inferred — the INFERRED_* prefix and what it means
4
+ aliases: [INFERRED]
5
+ category: topology
6
+ related: [inventorize]
7
+ tags: [core]
8
+ ---
9
+
10
+ # inferred (the `INFERRED_*` prefix)
11
+
12
+ A vertex with a type starting `INFERRED_` was **created by a platform-side inference rule** at ingest time, not by an agent emitting it directly.
13
+
14
+ Examples seen on real tenants:
15
+ - `INFERRED_DATABASE` — DB identity unified across multiple agents.
16
+ - `INFERRED_WEBSERVICE` — web service unified across multiple callers.
17
+ - `INFERRED_GENERICBACKEND` — generic backend pattern.
18
+
19
+ ## Why it exists
20
+
21
+ Without inference, the same backing thing can show up as multiple vertices — one per agent observing it. Inference deduplicates. From the user's perspective, an `INFERRED_DATABASE` is a more reliable identity than a per-agent `DATABASE`.
22
+
23
+ ## What it means for queries
24
+
25
+ - The shape (attributes, metrics) of `INFERRED_<TYPE>` is broadly the same as the non-inferred type. Backend-call metrics still live under the producing agents' metric sources, not on the inferred vertex.
26
+ - Don't filter ONLY on `INFERRED_*` — many tenants have agent-side `DATABASE` vertices without the corresponding inference rule firing. To capture all matches, filter on both: `type IN [DATABASE, INFERRED_DATABASE]`.
27
+ - Inferred vertices have an `inferredBackendNode` attribute (the rule's id) where non-inferred vertices have `backendNode` (the agent's id).
28
+
29
+ ## Compared to "inventorize"
30
+
31
+ | Concept | Who creates the vertex | Where rules live |
32
+ |---|---|---|
33
+ | `INFERRED_*` | Platform-side inference rule | Built into DXO2 |
34
+ | Custom inventorize entity | Tenant-side inventorize rule | `inventory create-inventorize-rule` |
35
+
36
+ Both fall under the broader idea of "synthesize a vertex from a pattern of telemetry". The prefix is the marker for which side built it.
37
+
38
+ ## See also
39
+
40
+ - `lexicon/inventorize`.
41
+ - `entities/database_or_inferred` — the canonical example.
@@ -0,0 +1,21 @@
1
+ # ${bundleName} (${bundleVersion})
2
+
3
+ ## Description
4
+
5
+ ${bundleDisplayName}
6
+
7
+ # Installation Instructions
8
+
9
+ deploy to extensions/deploy in the agent directory or add to a package via ACC.
10
+
11
+ ## Prerequisites
12
+
13
+ ## Dependencies
14
+ ${bundleDependencies}
15
+
16
+ ## Configuration
17
+
18
+ # Usage Instructions
19
+
20
+ ## Debugging and Troubleshooting
21
+
@@ -0,0 +1,34 @@
1
+ ---
2
+ id: inventorize
3
+ title: inventorize — the act of creating an entity from a pattern of telemetry
4
+ aliases: [inventorization, inventorizing]
5
+ category: topology
6
+ related: [inferred]
7
+ tags: [core]
8
+ ---
9
+
10
+ # inventorize
11
+
12
+ In DXO2, "inventorize" is the **platform's act of creating a topology entity from a pattern of telemetry** — telling the platform "when you see X happening, materialize a vertex of type Y with these attributes". The configuration object is an **inventorize rule** managed via the `inventory create-inventorize-rule` CLI command (and the corresponding REST API).
13
+
14
+ ## Why it exists
15
+
16
+ Some metrics imply the existence of a resource that doesn't have a first-class vertex. The classic example: a JMX agent reports `JDBC_Pool|<pool>:Active Connections` — there's clearly a pool, but no `JDBC_CONNECTION_POOL` vertex by default. An inventorize rule can pattern-match on the metric path and create a vertex per pool.
17
+
18
+ ## How it relates to `INFERRED_*`
19
+
20
+ `INFERRED_*` types (e.g. `INFERRED_DATABASE`) are typically **the output of platform-side inference rules**, which are a more constrained cousin of inventorize rules. The platform ships several built-in inference rules; tenants add their own inventorize rules on top.
21
+
22
+ - Inferred = platform-shipped rule output.
23
+ - Inventorize = tenant-added rule output (usually under `CUSTOM` layer, often `CUSTOM_INVENTORIZE_<N>` type).
24
+
25
+ ## How a user might phrase it
26
+
27
+ - "Can we see this as an entity?" → yes, with an inventorize rule.
28
+ - "Why is this metric not on a vertex?" → because no inventorize rule matches its pattern yet.
29
+ - "Promote these metrics into an entity" → inventorize.
30
+
31
+ ## See also
32
+
33
+ - `lexicon/inferred`.
34
+ - `cookbooks/metrics-grounding` — when to consider an inventorize rule.
@@ -0,0 +1,149 @@
1
+ ---
2
+ id: investigation-planning
3
+ title: Investigation planning — attack each question with a plan
4
+ applies_to: all
5
+ tags: [getting-started, discovery, authoring]
6
+ related: [discovery-flow, investigator-flow, entity-relationships, metrics-grounding]
7
+ ---
8
+
9
+ # Investigation planning
10
+
11
+ DXO2 has a lot of data structures, a lot of integrations, and a lot of overloaded terminology. Many user questions don't map directly to a single query — there's a missing step *before* authoring: **figure out what the user actually means and where the answer is most likely to live.**
12
+
13
+ This cookbook is the framework for that step. It complements `investigator-flow` (which assumes you already know what to query) and `discovery-flow` (which is about probing tenant capabilities).
14
+
15
+ ## Before authoring a query, run the planning loop
16
+
17
+ ```
18
+ ┌──────────────────────────┐
19
+ │ 1. Disambiguate the │
20
+ │ user's terms │ ← lexicon + name-search
21
+ └────────────┬─────────────┘
22
+
23
+ ┌──────────────────────────┐
24
+ │ 2. Identify candidate │
25
+ │ anchors that match │ ← discovery_search_by_name
26
+ │ the user's phrasing │
27
+ └────────────┬─────────────┘
28
+
29
+ ┌──────────────────────────┐
30
+ │ 3. Pick a strategy │ ← entity-first / service-first /
31
+ │ based on what matched │ universe-first / agent-first /
32
+ │ │ metric-first
33
+ └────────────┬─────────────┘
34
+
35
+ ┌──────────────────────────┐
36
+ │ 4. Author the query. │
37
+ │ If empty / wrong, │
38
+ │ consider inventorize │
39
+ │ or fall back a level. │
40
+ └──────────────────────────┘
41
+ ```
42
+
43
+ Time spent in steps 1-3 saves multiple round-trips of "I asked X, got nothing back, let me reformulate."
44
+
45
+ ## Step 1 — disambiguate the user's terms
46
+
47
+ DXO2 has a small set of words that get used for very different things. Before treating a user's noun as a literal query target, check the lexicon:
48
+
49
+ - **service** — DXO2 service vs DXI_SERVICE vs k8s_SERVICE vs OS service vs business service. (`lexicon/service`)
50
+ - **application** — DXO2 application (service with `type=application`) vs APM `applicationName` vs k8s_DEPLOYMENT vs business application. (`lexicon/application`)
51
+ - **universe** — APM Universe vs O2 Universe. (`lexicon/universe`)
52
+ - **host** — uppercase `HOST` (APM) vs mixed-case `Host` (NetOps). (`lexicon/host`)
53
+ - **agent / source / collector / monitor** — colloquial vs literal. (`lexicon/agent_source_collector`)
54
+
55
+ A 30-second lexicon read prevents a 10-minute query-flailing session.
56
+
57
+ ## Step 2 — identify candidate anchors
58
+
59
+ Once the term is disambiguated, search for entities whose name or label matches the user's phrasing. **Don't assume one shape**. The MCP tool `discovery_search_by_name` runs a name-search across multiple kinds in one call — services, universes, vertex names, and (when present) DXO2 applications.
60
+
61
+ For a phrase like "the X application":
62
+
63
+ | Search | What you get |
64
+ |---|---|
65
+ | Service-with-type=application named X | Modern DXO2 apps |
66
+ | DXO2 service named X | Pre-application-era org structure |
67
+ | k8s_DEPLOYMENT named X | Kubernetes-native shops |
68
+ | Universe named X | Some customers use universes as portfolio markers |
69
+ | Vertex with `applicationName=X` (BTs, SERVLETs) | APM-flavored anchor |
70
+
71
+ If multiple kinds match, surface all candidates to the user before committing.
72
+
73
+ ## Step 3 — pick a strategy based on what matched
74
+
75
+ Different anchors call for different first moves:
76
+
77
+ ### Entity-first (a vertex matches the user's phrasing)
78
+
79
+ The match is a specific topology vertex. Walk from there:
80
+ - TAS query starting from the vertex (`vertex search` → `detail` → TAS TRAVERSE for neighbors).
81
+ - For metrics: `discovery_metrics_for_entity` to get the canonical metric query body.
82
+
83
+ ### Service-first (a DXO2 service matches)
84
+
85
+ - `discovery_service_hierarchy` to see the service's place in the DAG (parents/children).
86
+ - `query-service-inventory` (CLI: `service query-service-inventory`) to enumerate constituent entities.
87
+ - `service-dependency-graph` for the runtime dependency view.
88
+ - For health metrics: `service-overview` and `service-detail-metrics`.
89
+ - **For "what services does this entity belong to"** — read the entity's `serviceNames` attribute (with TAS `includeServices: true`). Don't traverse the hierarchy; the platform pre-populates this index. See `entities/service` for the pattern.
90
+
91
+ ### Universe-first (a universe matches)
92
+
93
+ - Determine APM vs O2 (the two universe kinds have different APIs).
94
+ - Use the universe as a scope filter for a downstream TAS query (member services → member entities).
95
+
96
+ ### Agent-first (the user named an agent / collector / host)
97
+
98
+ - Find the AGENT vertex by name or by host.
99
+ - TRAVERSE `agent-monitors` outgoing edges to enumerate what the agent produces metrics for.
100
+ - Query MM under the agent's metric source for raw data.
101
+
102
+ ### Metric-first (no entity matches but the user described a metric or pattern)
103
+
104
+ This is the **JMX-flavored** case. The thing the user is asking about (a JDBC pool, a queue, a thread-pool, a cache region) very likely **has no vertex** because no integration currently materializes it.
105
+
106
+ - Query MM by `metric.path` regex matching the user's intent.
107
+ - Inspect the producing agent's source to ground identity.
108
+ - Cross-reference `cookbooks/metrics-grounding` for the orphaned-by-design pattern.
109
+
110
+ If the metric pattern is high-value and recurring, **consider an inventorize rule** to materialize the resource as a vertex (`inventory create-inventorize-rule`). See `lexicon/inventorize`.
111
+
112
+ ## Step 4 — author the query, but plan the fallback
113
+
114
+ Empty results don't always mean "no data". They can mean:
115
+
116
+ - The wrong vertex type filter excluded the actual matches (`HOST` vs `Host` is the textbook example).
117
+ - The wrong layer was filtered to.
118
+ - The agent reports the metric but no inventorize rule has materialized the entity yet.
119
+ - The customer's universe scope hides the data behind the active scope.
120
+
121
+ When you get empty results, **don't just retry with broader filters**. Drop one level in the strategy ladder:
122
+
123
+ ```
124
+ entity-first → service-first → universe-first → metric-first → inventorize
125
+ (anchored) (synthesize)
126
+ ```
127
+
128
+ Each step is broader, and each step is a different *kind* of question.
129
+
130
+ ## Things that are universally fine to do early
131
+
132
+ These tools are read-only, cached, and cheap — call them freely as part of step 1 / step 2:
133
+
134
+ - `corpus_list("lexicon")` — overload disambiguation.
135
+ - `corpus_list("entities")` — what kinds of vertices a tenant *can* have.
136
+ - `discovery_layers`, `discovery_universes`, `discovery_services` — what the tenant *does* have.
137
+ - `discovery_search_by_name` — bridge step 1 → step 2.
138
+ - `discovery_vertex_types` — empirical type distribution on this tenant.
139
+ - `discovery_edge_semantics` — what kinds of relationships exist on this tenant.
140
+
141
+ Save expensive moves (`run_query` with a wide projection, full TAS dumps) for after the planning round-trips.
142
+
143
+ ## See also
144
+
145
+ - `cookbooks/investigator-flow` — assumes you've planned, walks through the actual query authoring.
146
+ - `cookbooks/discovery-flow` — what the discovery tools do.
147
+ - `cookbooks/entity-relationships` — the kinds of relationships that exist.
148
+ - `cookbooks/metrics-grounding` — the metric-first strategy in depth.
149
+ - `lexicon/` — every overloaded term.
@@ -0,0 +1,186 @@
1
+ ---
2
+ id: investigator-flow
3
+ title: Investigator flow — handling natural-language DXO2 questions end-to-end
4
+ applies_to: all
5
+ tags: [investigator, getting-started, decision-tree]
6
+ related: [universes-and-scopes, service-hierarchies, query-vs-analysis-separation, discovery-flow, gotchas]
7
+ ---
8
+
9
+ # Investigator flow
10
+
11
+ A typical DXO2 user asks **investigative** questions, not query-shaped ones:
12
+
13
+ > *"Are there any hosts with high CPU right now?"*
14
+ > *"Which services are degraded?"*
15
+ > *"Why did APM-Eastern go red overnight?"*
16
+ > *"Show me the top noisy metric sources."*
17
+
18
+ The user doesn't care about TAS vs NASSQL, layers, or filter ops — they care about *the answer*. The investigator's job is to translate that intent into a query that gets the user close to the answer they're really looking for, then hand off to the ui (for human refinement / dashboarding) or to an analyzer (for thresholding / anomaly detection).
19
+
20
+ This cookbook is the canonical decision tree.
21
+
22
+ ## The investigator loop (in order)
23
+
24
+ ```
25
+ user asks
26
+
27
+ scope-clarification checklist
28
+
29
+ ask 1-2 targeted questions (only the load-bearing ambiguities)
30
+
31
+ pick query type (TAS vs NASSQL, source op)
32
+
33
+ author query + verify with run_partial / run_query
34
+
35
+ save query (create_query)
36
+
37
+ hand off — UI link, or analyzer subagent
38
+ ```
39
+
40
+ Each step below.
41
+
42
+ ## Step 1 — Scope-clarification checklist
43
+
44
+ Before authoring anything, mentally walk this checklist:
45
+
46
+ | Ambiguity | Source of truth | When to ask |
47
+ |---|---|---|
48
+ | **Service** — named? if so, which subservice scope? Direct children only or full descent? | `entities/service` + `discovery_service_hierarchy` (DAG view) | When the user names a service or anything service-shaped. **Check first** — services are the preferred scope axis when populated. |
49
+ | **Universe** — which (or any)? APM vs O2? | `entities/universe` + `discovery_universes` | Always on a multi-universe tenant. Skip on single-universe tenants. |
50
+ | **Time window** — now, last hour, last day, custom? | (whatever the user says) | When the question implies time (most do). Default to "right now" → ~1 hour. |
51
+ | **Threshold** — what does "high" / "low" / "noisy" / "slow" mean? | (whatever the user has in mind) | When the question implies a threshold. Often best to *not* threshold in the query — see step 5. |
52
+ | **Output shape** — list, count, ranking, time series? | (the question's grammar) | "Are there any" → list; "how many" → count; "top" → ranking; "show me the trend" → time series. |
53
+
54
+ The first two are the **load-bearing** ones because they change the query's filter shape entirely. Time/threshold/output usually have safe defaults.
55
+
56
+ ### Scope-axis precedence — services first, then user-created universes
57
+
58
+ DXO2 has two scope axes. They overlap; in practice they answer different questions about the same tenant. The default order:
59
+
60
+ 1. **Services first.** Use `discovery_service_hierarchy` to inventory the service catalog. Look at `totalServices`, `rootCount`, `roots[]`, and `tags`. If services look fully populated (a healthy tree of named, tagged services that obviously map to ownership/technology/functionality boundaries), **prefer service-scoped queries** for any investigative work.
61
+ 2. **Universes second, system-defaults filtered.** Use `discovery_universes`. **Skip `id == 'UNsaasProd'` (APM default) and `id == 'VIEWALL'` (O2 default)** — those are tenant-creation defaults rather than user-modeled scopes; they don't reflect organizational intent. The remaining universes are user-created and meaningful.
62
+ 3. **If services are sparse, lean on user-created universes.** Some tenants haven't fully populated services yet; in that case the universe axis is the better proxy for org shape.
63
+ 4. **Both populated?** Like demo-prod — prefer service-scoped queries. Universes still answer "which slice of data am I allowed to see," but services answer "what is this for."
64
+
65
+ State the org-shape inference back to the user as part of the clarifying question — *"this tenant has ~100 services across 24 root branches plus 6 user-created universes; I'd lean on the service axis…"* — so the user can redirect if their mental model differs.
66
+
67
+ ## Step 2 — Ground the scope empirically
68
+
69
+ Do *not* speak about universes or services abstractly. Run the discovery tools (front-door, all `alwaysLoad`):
70
+
71
+ ```
72
+ corpus_get('entities', 'universe') ← refresh on the conceptual model if needed
73
+ corpus_get('entities', 'service') ← same for services
74
+ discovery_capabilities ← what the bound tenant supports
75
+ discovery_universes ← APM + O2 universes, name-first shape
76
+ discovery_service_hierarchy ← DAG view: roots, children, parents, tags
77
+ ```
78
+
79
+ (`discovery_services` returns just a flat name list — cheaper, but use the hierarchy variant when you need parent/child or want to surface "broaden to siblings?" cleanly.)
80
+
81
+ Cache the counts + roots in your own context — *"on this tenant: 11 user-created APM universes, 6 user-created O2 universes (`VIEWALL` excluded as system default), 106 services across 24 roots"* — so you can surface them in the same sentence as your clarifying question.
82
+
83
+ ## Step 3 — Ask the targeted question
84
+
85
+ Surface what you found and ask only what's load-bearing. **One or two questions, not five.** Example for *"are there any hosts with high CPU right now?"*:
86
+
87
+ > *"Quick scope check — this tenant has 3 APM universes (Prod, Staging, NA-EMEA-Combined), 7 O2 universes, and ~140 services. Did you want all hosts cross-universe, or hosts in a specific universe / service? And for 'high CPU' — do you have a threshold in mind (e.g. >70% sustained, >90% peak), or should I produce a query that returns the raw CPU data and we look at it together?"*
88
+
89
+ Notice:
90
+ - One sentence states what's there. (Surfacing scale is an answer to "where do I even start.")
91
+ - Two questions: scope, then thresholding.
92
+ - The threshold question has a built-in escape hatch (*"or produce raw data"*) — see step 5.
93
+
94
+ ## Step 4 — Pick query type (TAS vs NASSQL, then the source op)
95
+
96
+ Based on the user's confirmed intent:
97
+
98
+ | Question shape | TAS or NASSQL? | If NASSQL, source op |
99
+ |---|---|---|
100
+ | "are there any X" / "list the X" / "which X" | **TAS** (entities) | n/a |
101
+ | "how many X" / "count X" | NASSQL (`FROM_TOPOLOGY`) | `FROM_TOPOLOGY` |
102
+ | "top N X by metric" | NASSQL (mostly) | `FROM_METADATA` if ranking by metric *count*; `FROM` if ranking by metric *values* |
103
+ | "show CPU over time for X" | NASSQL | `FROM` (datapoints) |
104
+ | "what metrics exist for X" | NASSQL | `FROM_METADATA` (definitions, not values) |
105
+ | "trace X to Y" / "what's connected to X" | **TAS** (`TRAVERSE`) | n/a |
106
+
107
+ The metadata-vs-data distinction is the most-confused one — see `cookbooks/discovery-flow` for the full hierarchy and `cookbooks/nassql-quickstart` for source-op details.
108
+
109
+ ## Step 5 — Default: produce the query, not the analysis
110
+
111
+ This is the load-bearing default for investigative work:
112
+
113
+ > **Produce a query that returns the raw data the user cares about. Let the threshold / anomaly / trend analysis happen elsewhere — in the ui where the user can see it, or in an analyzer subagent.**
114
+
115
+ Why: the same data shape can support multiple analyses. *"Hosts with high CPU"* could mean:
116
+
117
+ - 1-of-30 datapoints over 90% (a momentary spike — usually noise)
118
+ - All-of-30 datapoints over 70% (sustained pressure — usually the real story)
119
+ - Peak over 95% in the last 6 hours (an SLO-shaped question)
120
+
121
+ A query that returns just the CPU datapoints for the chosen scope supports all three. A query with `FILTER cpu > 90` baked in supports only the first, and silently. **The pre-filtered query is rarely what the user actually wanted, and it's silently lossy.**
122
+
123
+ When to threshold in the query anyway:
124
+ - The user explicitly stated a threshold (*"hosts with CPU over 90"*).
125
+ - The result set would otherwise be unmanageable (e.g. millions of rows). Then add a sane `limit` first; only add a value-threshold if `limit` isn't enough.
126
+
127
+ See `cookbooks/query-vs-analysis-separation` for the pattern catalog.
128
+
129
+ ## Step 6 — Author + verify
130
+
131
+ Use corpus content as starting points:
132
+
133
+ - `corpus_list('queries', {type: 'tas'})` — TAS examples.
134
+ - `corpus_list('queries', {type: 'nassql'})` — NASSQL examples.
135
+ - `corpus_get('queries', '<id>')` — full payload + per-op descriptions.
136
+
137
+ Read the descriptions — they capture *why* the query is shaped a certain way and what mistake the alternative would be (these are agent-authored notes, exactly the kind of grounding you'd want).
138
+
139
+ **Before authoring an op you don't write daily, call `query_schema` with that op.** The default response is a 4 KB summary listing the op's properties (name, description, required, typeHint) — cheaper than guess-and-retry, and prevents the textbook field-name fumbles (`_type` vs `type` on `ATTRIBUTE`, `count` vs `n` on `TOP`, etc.). Examples: `{type: "tas", op: "ATTRIBUTE"}`, `{type: "nassql", op: "FROM"}`, `{type: "metadata", op: "SPEC"}`. Reach for `full: true` only when nested validation detail (enum values past 6 entries, recursive sub-shapes) actually matters.
140
+
141
+ Verify before saving:
142
+ - `run_query` for full execution. Watch for empty-payload trap (see `gotchas`).
143
+ - `run_partial_query` for sub-tree verification when you have nested filters or multi-step NASSQL pipelines.
144
+
145
+ ## Step 7 — Save + hand off
146
+
147
+ Save with `create_query`:
148
+
149
+ ```
150
+ create_query({
151
+ type: 'tas' | 'nassql' | 'metadata',
152
+ shortName: '<descriptive-kebab-case>',
153
+ payload: { ... },
154
+ descriptions: {
155
+ '$': '<top-level intent — what this query answers>',
156
+ '$.filter.input[0]': '<why this op shape>',
157
+ // … per-op notes capture the load-bearing reasoning
158
+ },
159
+ tmd: { description: '<one-line summary>', tags: ['investigator', 'foray-N'] },
160
+ md: '<companion doc explaining intent / expected output / gotchas>'
161
+ })
162
+ ```
163
+
164
+ The `descriptions` are the most valuable thing you leave behind — future agents reading this query via `get_query` get the reasoning for free.
165
+
166
+ Then hand off:
167
+
168
+ > *"Saved as `15-cpu-by-host`. Open in the ui to refine the time window, run, or attach to a dashboard: `http://localhost:<port>/queries/15-cpu-by-host`. (Or if you'd like a thresholded analysis right now, I can hand it to the analyzer.)"*
169
+
170
+ ## Anti-patterns to avoid
171
+
172
+ - **Skipping the scope-clarification step**. *"Hosts with high CPU"* on a multi-universe tenant authored against the wrong universe is a wrong answer; the user has to redo the work.
173
+ - **Asking five clarifying questions.** Pick the one or two that are load-bearing for the query shape. The rest can default.
174
+ - **Hard-coding tenant-specific service / universe names.** Always look up via discovery; tenant data changes.
175
+ - **Defaulting to thresholded queries.** Default to data-fetching. Threshold only when the user said.
176
+ - **Treating "service" as DXI_SERVICE.** Almost always, "service" means `saService` (the organizational axis). See `entities/dxi_service` for the disambiguation.
177
+ - **Long-form summaries instead of saving the query.** The deliverable is a saved query the user can refine, not a paragraph of explanation. Save first, explain in the handoff.
178
+
179
+ ## See also
180
+
181
+ - `cookbooks/universes-and-scopes` — the universe-axis details.
182
+ - `cookbooks/service-hierarchies` — the service-axis details + the `excludeSubServices` knob.
183
+ - `cookbooks/query-vs-analysis-separation` — the data-vs-analysis default and the pattern catalog.
184
+ - `cookbooks/discovery-flow` — discovery tool ordering.
185
+ - `cookbooks/gotchas` — empirical surprises across all of the above.
186
+ - `entities/universe`, `entities/service`, `entities/dxi_service` — the foundational entities.
@@ -0,0 +1,88 @@
1
+ ---
2
+ id: k8s_deployment_and_namespace
3
+ title: k8s_DEPLOYMENT / k8s_NAMESPACE / k8s_CLUSTER — the Kubernetes structural layer
4
+ layer: INFRASTRUCTURE
5
+ related_entities: [k8s_pod, k8s_replicaset, k8s_service, host]
6
+ related_cookbooks: []
7
+ tags: [k8s, infrastructure, integration-specific]
8
+ ---
9
+
10
+ # k8s_DEPLOYMENT, k8s_NAMESPACE, k8s_CLUSTER
11
+
12
+ ## What they are
13
+
14
+ These three vertex types describe the **structural** Kubernetes layer above the running pods/containers:
15
+
16
+ - `k8s_CLUSTER` — a monitored Kubernetes cluster (top of the tree).
17
+ - `k8s_NAMESPACE` — a namespace within a cluster (logical grouping).
18
+ - `k8s_DEPLOYMENT` — a Deployment workload (declared spec for a set of pods).
19
+
20
+ `k8s_REPLICASET` (an intermediate the deployment owns), `k8s_DAEMONSET`, and `k8s_STATEFULSET` are siblings of `k8s_DEPLOYMENT` at the workload-owner level.
21
+
22
+ ## Why this matters
23
+
24
+ When a user says "the X application" in a Kubernetes-native shop, the right anchor entity is usually `k8s_DEPLOYMENT`, not a DXO2 service or APM application. The deployment name is what developers and SREs talk about every day; pods come and go.
25
+
26
+ The hierarchy:
27
+ ```
28
+ k8s_CLUSTER
29
+ └─ contains → k8s_NAMESPACE
30
+ └─ contains → k8s_DEPLOYMENT (or DAEMONSET / STATEFULSET)
31
+ └─ orchestrates → k8s_REPLICASET
32
+ └─ orchestrates → k8s_POD
33
+ └─ contains → k8s_CONTAINER
34
+ ```
35
+
36
+ The exact edge `semantic` values vary (`contains`, `orchestrates`, `composed_of`); `discovery_edge_semantics` on a tenant returns the empirical set.
37
+
38
+ ## Useful attributes
39
+
40
+ k8s_CLUSTER:
41
+ - `name`, `k8s_cluster_name`, `k8s_cluster_namespaces`, `k8s_cluster_nodes`.
42
+ - `k8s_agent_data_source`, `k8s_project`, `k8s_type`.
43
+
44
+ k8s_NAMESPACE:
45
+ - `name`, `k8s_namespace_phase`, `k8s_namespace_uuid`.
46
+ - `k8s_namespace_labels_kubernetes.io/metadata.name`.
47
+
48
+ k8s_DEPLOYMENT:
49
+ - `name`, `k8s_deployment.name`, `k8s_deployment_vertexid`.
50
+ - `k8s_deployment_annotations_deployment.kubernetes.io/revision`.
51
+ - `k8s_cluster_name`, `k8s_project`, `k8s_type`, `keyPrefix`.
52
+
53
+ ## Common starting moves
54
+
55
+ - "How is application X" → search by name across `k8s_DEPLOYMENT` and DXO2 services. If `k8s_DEPLOYMENT` matches, walk down to pods and roll up CPU / memory / restart-count.
56
+ - "All pods in namespace prod" → filter `k8s_POD` by traversal from the matching `k8s_NAMESPACE`.
57
+ - "Cluster overview" → `k8s_CLUSTER` for top-level rollup, then `k8s_NAMESPACE` counts per cluster.
58
+
59
+ ## Mapping to "application"
60
+
61
+ DXO2 has multiple notions of application; k8s adds another:
62
+
63
+ - DXO2 application — a service with `type=application` (recently introduced; see `lexicon/application`).
64
+ - APM-side application — `applicationName` attribute on BT / SERVLET / etc.
65
+ - Kubernetes application — the convention is "one Deployment per app" (occasionally many Deployments grouped by labels).
66
+
67
+ When grounding for a user query mentioning "application X", the agent should:
68
+ 1. Search by name across `k8s_DEPLOYMENT`, DXO2 service-with-type=application, and APM-flavored entities.
69
+ 2. Pick the strongest match. If `k8s_DEPLOYMENT` is the only hit, that's the anchor.
70
+ 3. If multiple match, ask the user to disambiguate or explore all of them.
71
+
72
+ ## Common synonyms / mistakes
73
+
74
+ - "Cluster" is unambiguous in k8s shops; in NetOps it could mean a different concept entirely.
75
+ - "Namespace" is k8s-specific terminology; users say "the prod environment" / "staging" — these usually map to k8s_NAMESPACE but sometimes to a DXO2 service or a label.
76
+ - "Deployment" is unambiguous in k8s shops. In non-k8s contexts it can mean "a release", which is a different concept (no vertex type).
77
+
78
+ ## Related entities
79
+
80
+ - **k8s_POD / k8s_CONTAINER** — the runtime layer below.
81
+ - **k8s_SERVICE** — the network-routing layer (NOT the same as a DXO2 service).
82
+ - **HOST** — when the cluster's worker nodes are also monitored as APM/Infrastructure HOSTs, both vertex types coexist.
83
+
84
+ ## See also
85
+
86
+ - `entities/k8s_pod_and_container` — for the runtime layer.
87
+ - `lexicon/service` — k8s_SERVICE vs DXO2 service vs others.
88
+ - `lexicon/application` — when "application" means a deployment.
@@ -0,0 +1,64 @@
1
+ ---
2
+ id: k8s_pod_and_container
3
+ title: k8s_POD / k8s_CONTAINER — the Kubernetes execution layer
4
+ layer: INFRASTRUCTURE
5
+ related_entities: [k8s_deployment, k8s_namespace, k8s_node, k8s_service, host]
6
+ related_cookbooks: []
7
+ tags: [k8s, infrastructure, integration-specific]
8
+ ---
9
+
10
+ # k8s_POD and k8s_CONTAINER
11
+
12
+ ## What they are
13
+
14
+ A `k8s_POD` is a Kubernetes pod — one or more containers scheduled together onto a node. A `k8s_CONTAINER` is a single container within that pod. Sidecars and init containers each get their own `k8s_CONTAINER` vertex; pod-level metrics aggregate across them.
15
+
16
+ Most tenants running k8s have many more containers than pods (sidecar-heavy environments push the ratio above 2:1). The relationship is `k8s_POD --contains--> k8s_CONTAINER`.
17
+
18
+ ## Where they live
19
+
20
+ Both live in the **INFRASTRUCTURE** layer (despite the runtime being heavily APM-flavored — Kubernetes-as-infrastructure is the platform's framing). The k8s agent is the producer.
21
+
22
+ ## Useful attributes
23
+
24
+ k8s_POD:
25
+ - `name`, `k8s_pod_nodename`, `k8s_pod_vertexid`, `k8s_container.name`.
26
+ - `k8s_cluster_name`, `k8s_agent_data_source`, `k8s_project`.
27
+ - `agent`, `product`, `ACNId`, `SourceProduct`, `resourceType`.
28
+
29
+ k8s_CONTAINER:
30
+ - `name`, `k8s_container_image`, `k8s_container_imagePullPolicy`.
31
+ - `k8s_pod_nodename`, `k8s_cluster_name`, `k8s_agent_data_source`.
32
+
33
+ ## How metrics are reported
34
+
35
+ The k8s agent reports per-pod and per-container CPU / memory / disk-IO / network. Pod-level metrics aggregate across containers. To find them:
36
+
37
+ - Use MM `discovery_metrics` filtered by `metric.source` containing the cluster name and pod or container name.
38
+ - The container's image often disambiguates which container's metrics you want — e.g. `metric.path` containing `nginx-sidecar` vs `app`.
39
+
40
+ Restart-count and crash-loop signals show up at the pod level via `restart_count_total` (or similar — name varies by k8s agent version).
41
+
42
+ ## Common starting moves
43
+
44
+ - "Pods crashlooping" — filter `k8s_POD` by `agent-monitors` edges where the corresponding metric crosses a threshold; use NASSQL `FROM_DATA` joined to `FROM_TOPOLOGY`.
45
+ - "Memory pressure on pod X" — pod's `k8s_pod_nodename` is the host; combine pod metrics with k8s_NODE-level pressure.
46
+ - "All containers running image Y" — filter `k8s_CONTAINER` by `k8s_container_image LIKE %Y%`.
47
+
48
+ ## Common synonyms / mistakes
49
+
50
+ - "Pod" alone is unambiguous. "Container" is ambiguous in non-k8s shops where it can mean a Docker container, an LXC, an OCI runtime — in DXO2 with k8s monitoring it almost always means `k8s_CONTAINER`. With ECS it means `AWS_ECS_FARGATE_CONTAINER`.
51
+ - Don't confuse `k8s_POD` with the application or deployment — a pod is **one running instance** of the deployment's spec. To answer "the X application" the right anchor is usually `k8s_DEPLOYMENT`, not the pod.
52
+
53
+ ## Related entities
54
+
55
+ - **k8s_DEPLOYMENT** / **k8s_REPLICASET** / **k8s_DAEMONSET** / **k8s_STATEFULSET** — the workload owners (pod creators).
56
+ - **k8s_NAMESPACE** — the namespace the pod belongs to.
57
+ - **k8s_NODE** — the worker node the pod runs on.
58
+ - **k8s_SERVICE** — the network-level service that routes traffic to a set of pods.
59
+ - **HOST** — when the same node is also monitored by an Infrastructure agent, both `k8s_NODE` and `HOST` may exist for the same physical machine. Match by hostname / IP.
60
+
61
+ ## See also
62
+
63
+ - `entities/k8s_deployment_and_namespace` — for the workload-owner side.
64
+ - `lexicon/service` — k8s_SERVICE vs DXO2 service disambiguation.