Skip to content

feat: declaration-first usage metering (ms.Meter + Record)#122

Merged
I-am-nothing merged 1 commit into
mainfrom
feat/meter-gauge-envelope-v2
Jun 17, 2026
Merged

feat: declaration-first usage metering (ms.Meter + Record)#122
I-am-nothing merged 1 commit into
mainfrom
feat/meter-gauge-envelope-v2

Conversation

@I-am-nothing

@I-am-nothing I-am-nothing commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Declaration-first usage metering — BY NAME

A module declares each metric once in setup, then emits by name at runtime — exactly mirroring the existing ms.Emits (declare) / ms.Emit (emit by name) pair. No stored handle, no Gauge() method, no kind on the wire.

API

  • Declare (setup): ms.Meter(name string, kind Kind, opts ...MetricOption) — registers the metric into the module manifest as a side effect; returns nothing (no *Metric handle). Kind is ms.Counter or ms.Gauge; options are ms.Unit(...) and ms.Price(microDollars) (price optional). Mirrors how ms.Emits registers.
  • Emit (runtime): ms.Record(ctx context.Context, name string, value float64) error — package-level, mirrors ms.Emit. Resolves the declared metric by name from the registry; returns an error if the name was never declared via ms.Meter (declaration-first, fail fast). No chaining.

Guards

  • Reserved infra.* / platform.* prefix → panic at declaration (platform-measured, not module-declarable).
  • Duplicate metric name → panic at declaration.
  • Undeclared name at Record → error.
  • Negative / NaN / Inf value at Record → error (never panics the handler).

Wire / transport

  • Envelope stays v1 (no kind field on the wire — the manifest-fed catalog is authoritative; no production emitters to stay compatible with).
  • Transport unchanged in this PR (MS_METER_LAMBDA_ARN / lambda.Invoke; dev = stderr). The dispatch-HTTP rewrite is PR docs: add SDK package structure to README #2.

Design ref

docs-temp/milestone-d-meter/design.md §4 (Axis 1) / §5 (app-module-sdk).

Review follow-ups (non-blocking)

  • Blocking fixed: Record dev-mode path now guards the nil logger before Printf, so a zero Client{} (or one from NewFromARN, which leaves logger nil) cannot panic. Regression test added.
  • ValidateMetricName deliberately restates registry.ValidateName because meter is a public package that cannot import internal/registry; a shared internal/namecheck could dedup later if it becomes a maintenance burden.
  • NewFromARN leaves logger nil by design (dev sink only); the invariant is now safe via the nil-guard rather than implicit.
  • internal/core (m *Module).Meter calls Declare then AddMetric in lockstep from a single call site; manifest/registry stay in sync.
  • Minor: TestRecord_DevModeLogsToStderr is non-parallel (uses a shared logger sink); not a correctness issue.

@I-am-nothing I-am-nothing force-pushed the feat/meter-gauge-envelope-v2 branch from 213b70c to 9803ba7 Compare June 16, 2026 08:53
@I-am-nothing I-am-nothing changed the title feat(meter): Gauge + kind envelope v2 + value validation feat: declaration-first usage metering (ms.Meter + Record) Jun 16, 2026
@I-am-nothing I-am-nothing force-pushed the feat/meter-gauge-envelope-v2 branch from 9803ba7 to 41f5173 Compare June 17, 2026 06:57
…by name)

Declare each metric once in setup via ms.Meter(name, kind, ms.Unit/ms.Price)
(side-effect registration into the manifest, no handle returned), then emit at
runtime BY NAME with package-level ms.Record(ctx, name, value) — mirroring the
existing ms.Emits/ms.Emit pair. No *Metric handle, no Gauge() method, no kind on
the wire; the manifest-fed catalog is authoritative and the envelope stays v1.

Guards: reserved infra.*/platform.* prefix + duplicate-name panic at
declaration; undeclared-name + negative/non-finite value return an error from
Record. Transport unchanged (MS_METER_LAMBDA_ARN / lambda.Invoke; dispatch-HTTP
rewrite is PR #2).

Fix defensive-nil bug: Record's dev-mode path (lambdaClient == nil) guards the
logger before Printf, so a zero Client{} (or one from NewFromARN, which leaves
logger nil) cannot panic. Adds a regression test.

Design ref: docs-temp/milestone-d-meter/design.md §4/§5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@I-am-nothing I-am-nothing force-pushed the feat/meter-gauge-envelope-v2 branch from 41f5173 to 0a025c0 Compare June 17, 2026 07:04
@I-am-nothing I-am-nothing merged commit 583351f into main Jun 17, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant