| 1 | # Go V2 Host Scope And Virtual Node Emission |
| 2 | |
| 3 | ## Scope |
| 4 | |
| 5 | This spec records the framework contract for Go collector v2 host-scope routing. |
| 6 | It applies to `pkg/metrix`, `plugin/framework/jobruntime`, |
| 7 | `plugin/framework/chartengine`, and v2 collectors that emit metrics for remote |
| 8 | or virtual-node targets. |
| 9 | |
| 10 | ## Metrix Host Scope |
| 11 | |
| 12 | - `metrix.HostScope{}` is the default host scope. |
| 13 | - Unscoped writes are equivalent to writes in the default scope. |
| 14 | - A non-default host scope carries: |
| 15 | - `ScopeKey`: stable scope partition key; |
| 16 | - `GUID`: Netdata host/vnode GUID; |
| 17 | - `Hostname`: Netdata host/vnode hostname when defining the host; |
| 18 | - `Labels`: deterministic host/vnode labels. |
| 19 | - Series identity includes host scope. The same metric name and labels can exist |
| 20 | in default scope and multiple non-default scopes without collision. |
| 21 | - `Read()` without `ReadHostScope` returns default-scope series only. |
| 22 | - `Read(ReadHostScope(key))` returns only that scope's series. |
| 23 | - `Reader.HostScopes()` enumerates all scopes present in the snapshot and is not |
| 24 | filtered by the reader's active host scope. |
| 25 | - Flattened synthetic series preserve the source host scope. |
| 26 | - Scope metadata conflicts in one collect cycle are data errors surfaced through |
| 27 | `CommitCycleSuccess() error`, not panics. |
| 28 | |
| 29 | ## Jobruntime V2 |
| 30 | |
| 31 | - V2 jobruntime owns host/vnode orchestration. Chartengine remains host-agnostic. |
| 32 | - One `chartengine.Engine` is used per host scope for a job. |
| 33 | - Scope engines are created lazily. |
| 34 | - Default-scope metrics continue to emit under the job-level vnode when one is |
| 35 | configured, otherwise under the global host. |
| 36 | - Explicit non-default scopes emit under their `metrix.HostScope` GUID and host |
| 37 | metadata. |
| 38 | - Collection and `metrix.CommitCycleSuccess()` are still all-or-nothing. |
| 39 | - Post-collect plan/apply/commit is per-scope partial success. A failed scope |
| 40 | rolls back its own registry changes and does not block unrelated scopes. |
| 41 | - Disappeared scopes are retained and read with empty scoped readers until the |
| 42 | per-scope chartengine emits lifecycle removals. After successful removal |
| 43 | emission, jobruntime releases scoped registry owners and destroys the scope |
| 44 | engine. |
| 45 | - Job cleanup emits obsolete charts for each retained scope before releasing |
| 46 | registry owners. |
| 47 | |
| 48 | ## Vnode Registry |
| 49 | |
| 50 | - V2 vnode definitions go through the shared `framework/vnoderegistry` registry. |
| 51 | - Registry entries are keyed by host GUID and owner. |
| 52 | - Metadata is update-on-change. A new normalized metadata value for an existing |
| 53 | GUID replaces retained metadata and causes another `HOST_DEFINE`. |
| 54 | - Owner release removes an entry only after the last owner for that GUID leaves. |
| 55 | - Job-level vnode owners and explicit scoped vnode owners use separate owner |
| 56 | namespaces. |
| 57 | |
| 58 | ## Chartengine Runtime Metrics |
| 59 | |
| 60 | - Per-scope engines do not register per-scope runtime components. |
| 61 | - Jobruntime feeds chartengine runtime samples into one job-level |
| 62 | `chartengine.RuntimeAggregator`. |
| 63 | - Aggregated runtime metrics do not include host-scope/workload labels. |
| 64 | - Counter-like runtime metrics are summed across samples. |
| 65 | - Gauge-like size metrics represent the latest successful build rollup, summed |
| 66 | across successful engines in that rollup. |
| 67 | - `build_seq_violation_active` is `1` when any observed engine reports a |
| 68 | sequence violation in the rollup, otherwise `0`. |
| 69 | |
| 70 | ## Collector Contract |
| 71 | |
| 72 | - V2 collectors that need per-target virtual nodes should write target metrics |
| 73 | through `meter.WithHostScope(scope)` or equivalent scoped vec/instrument |
| 74 | bindings. |
| 75 | - V2 collectors should leave metrics unscoped when those metrics belong to the |
| 76 | default job vnode/global host. |
| 77 | - Collector-generated scope keys must be deterministic and stable for the target |
| 78 | host/vnode identity. |
| 79 | - Collector-generated host labels should include `_vnode_type=<source>` when a |
| 80 | collector creates virtual nodes from an internal mechanism rather than a |
| 81 | user-defined vnode entry. The value must identify the mechanism or source |
| 82 | without embedding high-cardinality target values. |
| 83 | - Azure Monitor resource-tag virtual nodes use `_vnode_type=azure_workload`. |
| 84 | Their GUID and `ScopeKey` are the deterministic SHA1 UUID of |
| 85 | `azure_monitor:` plus the trimmed, case-preserved tag value. |
| 86 | - Collectors are responsible for bounding or documenting scope cardinality risk. |