Skip to content

feat(opa-gson): add MetricsTypeAdapterFactory mirroring opa-jackson #59#72

Open
sanajitjana wants to merge 2 commits into
open-policy-agent:mainfrom
sanajitjana:fix/59-gson-metrics-module
Open

feat(opa-gson): add MetricsTypeAdapterFactory mirroring opa-jackson #59#72
sanajitjana wants to merge 2 commits into
open-policy-agent:mainfrom
sanajitjana:fix/59-gson-metrics-module

Conversation

@sanajitjana

Copy link
Copy Markdown

Fix issue #59

Summary

Adds MetricsTypeAdapterFactory to opa-gson, closing the parity gap with
opa-jackson's MetricsModule.

Changes

  • MetricsTypeAdapterFactory — serializes Metrics.Timer as nanoseconds,
    Metrics.Counter as int, Metrics.Histogram as its Values object
  • MetricsTypeAdapterFactoryTest — parallel tests to MetricsModuleTest

JSON Shape

Matches DecisionLogPlugin's output:

{"timer_rego_query_eval_ns": 12345}

@sanajitjana
sanajitjana force-pushed the fix/59-gson-metrics-module branch from 3837416 to 22aef8e Compare June 23, 2026 09:30
@sspaink

sspaink commented Jun 23, 2026

Copy link
Copy Markdown
Member

@sanajitjana thank you for working on this! can you sign your commits please for the DCO check to pass?

… MetricsModule

Signed-off-by: Sanajit Jana <sanajit.jana@safexpress.com>
@sanajitjana
sanajitjana force-pushed the fix/59-gson-metrics-module branch from 3012180 to 34d4884 Compare June 27, 2026 15:25
@sanajitjana

Copy link
Copy Markdown
Author

@sspaink - it's done now.

if (timer == null) {
out.nullValue();
} else {
out.value(timer.value().toNanos());

@sspaink sspaink Jul 6, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timer JSON shape diverges from the opa-jackson MetricsModule this mirrors.

This emits nanoseconds as an integer (12345), but opa-jackson serializes Metrics.Timer as its Duration via @JsonValue, which with JavaTimeModule produces fractional seconds — a 12345 ns timer yields 0.000012345. So a consumer who swaps mappers gets a structurally different value for the same timer, which cuts against the "close the parity gap" goal of the PR.

The nanosecond shape here is the correct one: it matches DecisionLogPlugin (timer.value().toNanos()) and OPA's canonical decision-log format, where the timer_<name>_ns key declares the unit as nanoseconds. jackson's fractional-seconds output is effectively a unit mismatch under that key, so opa-jackson is the module that should change — not this one.

So: keep this gson adapter as written, and align opa-jackson's MetricsModule to emit nanoseconds too (e.g. a JsonSerializer<Metrics.Timer> or a @JsonValue method returning value().toNanos(), plus updating MetricsModuleTest to assert against toNanos()). That also drops the JavaTimeModule requirement on that path.

@sanajitjana if you have the time, would you mind folding that jackson fix into this PR so parity is actually true when it lands? No pressure — if you'd rather keep this PR scoped to gson, I'll follow up with the jackson change separately.

}

private static final class CounterAdapter extends TypeAdapter<Metrics.Counter> {
@Override

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CounterAdapter and HistogramAdapter (below) ship with zero test coverage.

MetricsTypeAdapterFactoryTest only exercises the Timer path, and SimpleMetrics.counter(...)/histogram(...) both return null, so there is no in-tree implementation that produces a non-null Counter or Histogram. That leaves the int-counter path and the whole Histogram.Values field layout (via gson.getAdapter(Values.class)) unverified.

Consider adding one test per adapter using a small hand-built Metrics.Counter/Metrics.Histogram stub — these are the paths that go beyond what opa-jackson's MetricsModule covers, so they're the most valuable to pin down.

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.

2 participants