master
md 172 lines 8.73 KB
Rendered Raw
1 ---
2 name: project-writing-go-modules-framework-v2
3 description: Use when creating or migrating a Go go.d collector to framework V2, touching CollectorV2, metrix.CollectorStore, ChartTemplateYAML/charts.yaml, charttpl/chartengine, V2 host scopes/vnodes, or V2 collector tests. Focuses on concise maintainer-preferred V2 collector patterns.
4 ---
5
6 # Writing Go go.d Modules With Framework V2
7
8 Use with `project-writing-collectors`. Keep this skill loaded for style; read
9 source files for evidence.
10
11 ## Read First
12
13 - Contract: `src/go/plugin/framework/collectorapi/collector.go`
14 - Framework-change workflow:
15 `src/go/plugin/framework/docs/changing-framework-code.md`
16 - Canonical new-collector guide:
17 `src/go/plugin/go.d/docs/how-to-write-a-collector.md`
18 - Helper-package guide:
19 `src/go/plugin/go.d/docs/helper-packages.md`
20 - V1-to-V2 migration guide:
21 `src/go/plugin/go.d/docs/migrate-v1-to-v2.md`
22 - Runtime/chart lifecycle: `src/go/plugin/framework/chartengine/README.md`
23 - Template format: `src/go/plugin/framework/charttpl/README.md`
24 - Host scopes/vnodes: `.agents/sow/specs/go-v2-host-scope.md`
25 - Primary modern example: `src/go/plugin/go.d/collector/cato_networks/`.
26 Use focused pieces from it, not the whole collector shape.
27 - Older V2 collectors can still be useful for local patterns, but review them
28 for stale style before treating them as examples.
29
30 ## Decision Discipline
31
32 - You MUST aim for the clean end state, not the smallest collector diff. If a
33 framework capability is missing and the problem is general, design the
34 framework change instead of hiding the issue in collector-local glue.
35 - If any framework-scope package changes, stop and satisfy
36 `src/go/plugin/framework/docs/changing-framework-code.md` before writing code.
37 - You MUST re-check scope after each coherent batch. If the work reveals an
38 independent collector cleanup, framework fix, or integration-doc change,
39 either defer it explicitly or land it separately before continuing.
40
41 ## Core Style
42
43 - New collectors MUST implement `collectorapi.CollectorV2` from
44 `src/go/plugin/framework/collectorapi/collector.go` and register via
45 `CreateV2`.
46 - `New()` SHOULD own defaults, `metrix.NewCollectorStore()`, typed metric
47 instruments, and test seams.
48 - V2 collectors MUST write metrics through `metrix.CollectorStore` during
49 `Collect()` and provide chart template YAML through `ChartTemplateYAML()`;
50 embedded `charts.yaml` is RECOMMENDED.
51 - `Collect(ctx)` MUST return `error` and write metrics to `metrix`; it MUST NOT
52 return a V1 `map[string]int64`.
53 - Files SHOULD stay boring: public lifecycle methods in `collector.go`, setup
54 helpers in `init.go` when needed, orchestration in `collect.go`, distinct
55 upstream operations in `collect_<operation>.go`, metrics in `metrix.go` /
56 `write_metrics.go`, focused tests.
57 - Before adding custom HTTP, selector, logging, command-execution, SQL, ping,
58 or log-file plumbing, check `src/go/plugin/go.d/docs/helper-packages.md` and
59 reuse an existing helper when it fits.
60 - If Functions exist, isolate them in a `<name>func/` subpackage with a narrow
61 `Deps` interface declared there. The Function package MUST NOT import the
62 collector package or hold `*Collector`.
63 - Public config options SHOULD stay small and justified. A proposed config
64 option MUST name the concrete operator decision it enables; "operators may
65 want to tune it" is not enough. Internal tuning SHOULD use constants unless
66 the operator has a real decision to make.
67
68 ## Metrics And Charts
69
70 - Instruments SHOULD be created once when the metric surface is known.
71 - Use `store.Write().SnapshotMeter("")` for normal metrics.
72 - Use `Vec(...)` for labels, `Gauge` for current values,
73 `Counter.ObserveTotal()` for source counters, and `StateSet` for fixed
74 one-active-state values.
75 - Metric names MUST be stable and selected by `charts.yaml`.
76 - In `charts.yaml`: use `version: v1`, `context_namespace`, `instances.by_labels`,
77 `label_promotion`, `algorithm: incremental` for counters, and `absolute` for
78 gauges.
79 - Put multipliers, divisors, hidden flags, and float formatting in the chart
80 template, not ad hoc chart-emission code.
81 - `metrix` registers a descriptor per metric NAME permanently (no unregister), so
82 re-registering a name with a changed kind, summary quantile set, or histogram
83 bounds PANICS. When a name's contract can drift across cycles, keep the per-name
84 handle for the job lifetime and SKIP a drifted series instead of re-registering.
85 - To reproduce a V1 chart context in a migration, inject `context_namespace` (the
86 fixed prefix, or `prefix.<app>` per job) so autogen rebuilds `prefix.<metric>` /
87 `prefix.<app>.<metric>` without hand-built chart IDs.
88 - Skip empty distributions -- e.g. a summary whose every quantile is NaN -- so a
89 chart waits for real data, matching how scalar NaN values are already skipped.
90 - For dynamic surfaces whose label sets churn, `metrix`'s `Vec` handle cache is
91 unbounded; cache per-series instruments yourself and evict handles unseen for N
92 cycles to stay bounded. Prefer a framework fix if the need is general
93 (Decision Discipline).
94
95 ## Compatibility Rules
96
97 - For V1-to-V2 migrations, start with
98 `src/go/plugin/go.d/docs/migrate-v1-to-v2.md`.
99
100 ### Migration Hard Stops
101
102 - A collector using V1 chart `Vars` is blocked until framework support, an
103 approved equivalent design, or explicit breaking-alert approval exists.
104 - `collecttest.AssertChartCoverage` is not chart-identity parity; it cannot
105 prove old chart IDs, family, priority, lifecycle, labels, or alert variables.
106 - A finished migration MUST pass an import/runtime-path audit proving no V1
107 collection path or V1 map-to-`metrix` bridge remains reachable from normal
108 execution.
109
110 - Temporary V1-to-V2 parity bridges MAY be used during development, but the
111 finished collector MUST NOT keep a runtime V1 map-to-`metrix` bridge.
112 - For migrations, first create a compatibility manifest covering chart IDs,
113 contexts, dimension IDs/names, labels, config keys, DynCfg schema keys,
114 stock config, alerts, docs, and lifecycle behavior.
115 - Migrations MUST preserve existing public contracts unless the SOW records an
116 explicit breaking decision.
117 - Migrations MUST keep old YAML/JSON field names. Add new config as opt-in when
118 cardinality, cost, or user-visible identity could surprise existing users.
119 - Collector integration artifacts MUST follow
120 `.agents/skills/integrations-lifecycle/consistency.md`; do not preserve a
121 partial local artifact checklist in V2 collector work.
122 - MUST NOT log raw secrets, DSNs, bearer tokens, or URLs with embedded
123 credentials.
124
125 ## Hot-Path Logging
126
127 - Collectors MUST NOT emit `Warningf`/`Errorf` every collection cycle for a
128 recoverable partial failure. Use the built-in logger limiter:
129 `c.Limit("collector:stable-operation-key", 1, time.Hour).Warningf(...)`.
130 - Limiter keys MUST be stable and low-cardinality. Use operation names, not
131 entity IDs, labels, URLs, raw errors, or user-controlled values.
132 - `Once()` is reset by `JobV2.runOnce()`, so it is useful inside one cycle only;
133 it is not cross-cycle spam protection.
134 - Full collection failure SHOULD still return an error with context so the job
135 retry path handles it. Limit only fail-soft warnings/errors where collection
136 continues with partial or stale data.
137
138 ## Host Scopes
139
140 - Host scopes SHOULD be used only after a product decision says the data belongs
141 on a generated vnode.
142 - `ScopeKey` and `GUID` MUST be deterministic.
143 - Collector-generated vnodes MUST set `_vnode_type=<source>`.
144 - Host-scope cardinality MUST be bounded and documented. Collectors SHOULD NOT
145 create VM/disk/NIC/path/sensor scopes by default.
146 - Scope identity MUST use stable IDs. Human-readable names SHOULD be hostnames
147 or promoted labels only.
148
149 ## Tests
150
151 At minimum, V2 work MUST include these tests, or the PR/SOW MUST justify why a
152 specific item does not apply:
153
154 - config YAML/JSON serialization compatibility;
155 - `Init`, `Check`, `Collect`, and `Cleanup` lifecycle coverage;
156 - explicit metric-store cycle tests with `BeginCycle`, success commit, and abort
157 on expected collection errors;
158 - chart-template schema/decode/validate/compile coverage;
159 - chart coverage assertions for fixtures expected to materialize all dimensions;
160 - host-scope tests when scopes/vnodes are used.
161
162 ## Pre-PR Check
163
164 - A finished V1-to-V2 migration MUST NOT keep a runtime
165 `map[string]int64` collection path or V1 map-to-`metrix` bridge.
166 - The PR description or design note MUST enumerate affected collector
167 consistency artifacts and justify every artifact that did not need a matching
168 change. SHOULD-level exceptions and escape hatches MUST be reviewer-visible.
169 - Existing public chart/metric/config identity MUST be preserved unless the SOW
170 records an explicit breaking decision.
171 - New labels and scopes MUST be bounded and documented.
172 - Enrichment SHOULD be split from the V2 compatibility migration when possible.