noz-in

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2026 License: Apache-2.0

README

noz-in

License Release Go Reference

Move your Grafana dashboards onto SigNoz in one command, and promote only the queries proven equivalent to native SigNoz Builder queries.

Grafana dashboard, one noz-in command, then the same dashboard live in SigNoz

Start in Grafana with 140 panels of Node Exporter Full. Run one command. End up in SigNoz, on live data, with every panel accounted for.
download the clip

noz-in migrates a whole Grafana dashboard (and its Prometheus alert rules) into SigNoz. Every query comes across and renders; the ones it can prove equivalent to a native SigNoz Builder query are promoted, and the ones it can't stay as verified PromQL passthrough. Nothing is ever claimed correct without being measured against your live SigNoz.

This is an independent community project, not affiliated with or endorsed by SigNoz, Inc.


Contents

  1. Why migrate to SigNoz, and why it's hard
  2. How it works
  3. Quickstart: Grafana → SigNoz
  4. Alerts come across too
  5. Using the MCP server and agent skill
  6. How it's engineered
  7. License

1. Why migrate to SigNoz, and why it's hard

Observability is consolidating onto one OpenTelemetry-native backend, and for a lot of teams that backend is SigNoz: metrics, logs, and traces in one self-hosted platform. The thing that stalls the move is the dashboards. Importing existing Grafana dashboards is one of the most-requested things in the SigNoz community (SigNoz/signoz#6425), and teams don't evaluate a backend on an empty screen. They evaluate it on the dashboards they already depend on.

You can't just find-and-replace the queries, either. PromQL does not mean the same thing once SigNoz's Query Builder is in the path. The two engines bucket and label time differently, so a naive conversion looks perfect and is quietly, numerically wrong. A dashboard you can't trust is worse than no dashboard.

The starting point: Grafana's Node Exporter Full on a live Linux host, with 140 panels and hundreds of PromQL queries.

noz-in removes that blocker in one command, and tells you exactly which queries it proved and which it didn't.

2. How it works

Two rules hold the whole thing together:

  • The floor. Every query migrates. If noz-in can prove a native Builder query is equivalent, it emits that. If it can't, it emits your original PromQL as verified passthrough, so every panel still renders. Nothing is dropped, and every decision carries a readable reason code.
  • The invariant. Nothing is labeled native without passing a live differential against its own PromQL on your target first, including a temporal phase-shift check. The same gate applies to deterministic rules, human overrides, and agent proposals.

Every query lands on one of three verdicts:

Verdict Meaning
native A Builder query proven equivalent on your live data, editable in the visual builder with drilldown and click-to-filter.
passthrough The original PromQL, verified to run, that SigNoz executes as-is so the panel still renders.
needs_review Genuinely ambiguous, flagged with a reason code instead of a guess.

3. Quickstart: Grafana → SigNoz

Everything below runs on the single-machine stack in deploy/local/: Docker only, nothing to provision. Requires Docker (Compose v2) and Go 1.25+.

Step 1. Stand up SigNoz with Foundry

casting.yaml and casting.yaml.lock are committed, so this reproduces the exact pinned SigNoz stack.

curl -fsSL https://signoz.io/foundry.sh | FOUNDRY_VERSION=v0.2.13 bash
export PATH="$HOME/.local/bin:$PATH"
cd deploy/local && foundryctl cast -f casting.yaml

Wait for the API, then create an admin user and a service-account key:

curl -fsS http://127.0.0.1:8080/api/v1/health
NOZIN_STATE_DIR=./state SIGNOZ_URL=http://127.0.0.1:8080 ../destination/bootstrap.sh

Step 2. Get noz-in

Grab a prebuilt binary for macOS, Linux, or Windows (amd64 / arm64) from the latest release, or build from source:

go build -o noz-in ./cmd/noz-in
./noz-in version

Step 3. Migrate a dashboard

Point it at a Grafana dashboard JSON and your live SigNoz. Let the stack ingest for a couple of minutes first, so metrics exist to verify against.

./noz-in grafana deploy/source/grafana/dashboards/node-exporter-full.json \
  --target http://127.0.0.1:8080 \
  --api-key-file deploy/local/state/api-key \
  --allow-insecure-http \
  --source-namespace judge-local \
  --var job=node-exporter --var node=local-node \
  --out out/

Read the summary. Every panel is accounted for. native counts are earned live. On a fresh stack it's common to see 0 native while everything renders as verified passthrough, which is the tool refusing to overclaim rather than a failure. The run writes <name>.signoz.json (import), <name>.report.json (evidence), and a self-contained <name>.report.html.

Step 4. Open it in SigNoz

Import out/node-exporter-full.signoz.json (or let the live run create it), and the dashboard renders on real data, and native panels are editable in the Query Builder with drilldown restored.

The migrated Node Exporter Full dashboard live in SigNoz, rendering real node metrics

Step 5. Verify a promotion (optional)

verify runs a single candidate against its source PromQL on the live target and prints a fidelity band, adopting only what it can prove refusing what diverges (or phase-shifts).

./noz-in verify \
  --source 'node_memory_MemTotal_bytes{job="node-exporter"}' \
  --candidate candidate.json \
  --target http://127.0.0.1:8080 --api-key-file deploy/local/state/api-key \
  --allow-insecure-http --fidelity 0.05

Offline runs work too: ./noz-in grafana dashboard.json --offline --out out migrates without any network access, but offline runs can never promote to native, because promotion requires the live differential.

4. Alerts come across too

Prometheus alert rules migrate alongside the dashboards, translated conservatively: thresholds extracted, for semantics approximated with an explicit reason, unsafe shapes failed closed into disabled review.

./noz-in rules rules/*.yaml \
  --target http://127.0.0.1:8080 --api-key-file deploy/local/state/api-key \
  --source-namespace prometheus:production --out out

27 migrated kube-prometheus alert rules evaluating in SigNoz

27 kube-prometheus node-exporter rules migrated in one run, with severities, labels, and for semantics preserved; unsafe shapes land as disabled review rather than a wrong alert.

Refusing to write is a feature. kube-prometheus ships severity variants that share an alert name (NodeFilesystemSpaceFillingUp exists as both warning and critical). Two rules that would collapse to one identity are a silent-overwrite bug, so the run stops before any target write and names exactly which two collided. Full contract in docs/rules.md.

5. Using the MCP server and agent skill

noz-in raises the native rate without weakening the guarantee: a human or an AI agent can propose Builder queries for the residual, and every proposal passes the same live differential before it's adopted. The agent proposes; the tool verifies.

MCP server

The MCP adapter exposes migrate_dashboard, explain_verdict, and validate_queries over the same application layer as the CLI. Credentials are server configuration, not tool arguments; HTTP mode is loopback-only with a bearer token.

./noz-in mcp --transport stdio --root /workspace --out /workspace/out

Point your coding agent at it (details and the container smoke test in docs/mcp.md).

Agent skill

skills/noz-in-assist is a packaged Agent Skill any coding agent (Claude Code, or anything that reads SKILL.md) can load to run migrations conversationally. The division of labor is strict, and the agent is never trusted:

  1. Deterministic first. The agent runs the CLI, which migrates everything and live-verifies what it can prove. This alone yields a complete, rendering dashboard.
  2. Agent proposes, never decides. For queries left as passthrough, it proposes Builder candidates using the bundled references (PromQL→Builder mapping, gotchas).
  3. Every proposal passes the same live gate. noz-in verify executes the candidate and the source PromQL against the live target; a hallucinated query cannot pass a numeric differential it never satisfies, so it stays honest passthrough.
  4. Adoption is re-verified. Adopted overrides go into overrides.yaml, and re-emitting re-verifies each one live before writing it as native.

Through SigNoz's own MCP, the agent can query the migrated dashboards and explain verdicts using live data. The full propose → verify → adopt sequence is diagrammed in docs/transpiler.md.

6. How it's engineered

The pipeline

flowchart LR
    G["Grafana JSON"] --> S["Source adapters<br/>rows · datasources · variables"]
    R["Prometheus rules"] --> S
    S --> M["Neutral model<br/>panels · queries · verdicts"]
    M --> T["Transpiler<br/>Prometheus AST → Builder candidate"]
    T --> D{"representable?"}
    D -- "no" --> PQ["PromQL passthrough<br/>+ reason code"]
    D -- "candidate" --> V["Live differential gate<br/>Builder vs its own PromQL<br/>+ phase-shift check"]
    V -- "equivalent" --> N["native Builder query"]
    V -- "diverged · phase shift · no data" --> PQ
    N --> E["SigNoz v5 emitter"]
    PQ --> E
    E --> API["SigNoz APIs<br/>v5 query_range · dashboards · rules"]
    E --> EV["Evidence report<br/>JSON + self-contained HTML"]

Package-by-package reading order: docs/architecture.md.

SigNoz's query engine is the oracle

This is not a JSON converter that POSTs to SigNoz at the end. Correctness is measured on SigNoz, not asserted from a parser:

  • Every query is parsed with the real prometheus/promql/parser, never a regex, into the same AST SigNoz embeds.
  • For every Builder candidate, noz-in fires a pair of executions at /api/v5/query_range: the Builder envelope and the verbatim PromQL, over the same window at the same step, then compares them series by series and point by point.
  • /api/v5/query_range/preview and the metadata APIs resolve metric type, temporality, and label identity before anything is claimed. Dashboard and rule APIs use stable, source-namespaced identities so repeated runs reconcile instead of duplicating.

The phase-shift finding

That pairing is what surfaced the core defect. An early version of the gate compared values within a 5% tolerance and promoted a slow-moving gauge that was rendering exactly one step late, because one bucket of drift was ~0.006%, far under tolerance. SigNoz's Builder latest labels each bucket at its start; PromQL evaluates at the boundary, so the same signal comes out one step apart:

Re-derived independently, builder[t] == promql[t+60s] for 10/10 points. The fix compares each point at the same slot and ±one step and rejects anything that only lines up when shifted, tagging it BUILDER_TEMPORAL_PHASE_SHIFT. That is the project's core idea in one line: native is a measurement, not a claim. The adversarial audit that found and fixed it (23 query shapes, 13 panel types, a 140-panel dashboard, 41 kube-prometheus alerts) is in docs/deep-audit-findings.md.

Honesty over screenshots

The same discipline decides visualizations. A Grafana stat/gauge panel is tempting to emit as a SigNoz value panel. It looks better in a screenshot, but on pinned SigNoz v0.133 a PromQL value panel can surface the window's oldest point (a CPU series 85.79 … 9.79 displayed 85.79). A confident wrong number is worse than an honest graph, so those emit as graphs with PANEL_TYPE_DOWNGRADE and the full series stays visible (docs/compatibility.md).

Evidence and reproducibility

The frozen corpus asserts 151 dashboards, 3,186 recursive panels, and 4,973 queries with zero parser errors; committed HTML reports from real runs live in docs/examples/. Contracts and guarantees are in docs/guarantees.md; the pinned reference topology and versions in VERSIONS.md and deploy/README.md. Build and test with:

make fmt vet test-race lint build

7. License

Licensed under the Apache License 2.0. SigNoz is a trademark of SigNoz, Inc. This is an independent community project, not affiliated with or endorsed by SigNoz, Inc.

Directories

Path Synopsis
cmd
noz-in command
internal
app
artifactbind
Package artifactbind verifies exact adjacent artifacts named by migration evidence without depending on a source or target schema.
Package artifactbind verifies exact adjacent artifacts named by migration evidence without depending on a source or target schema.
artifactset
Package artifactset publishes and verifies migration artifacts as committed generations while preserving their stable, user-facing filenames.
Package artifactset publishes and verifies migration artifacts as committed generations while preserving their stable, user-facing filenames.
atomicfile
Package atomicfile contains the platform-specific durability step required after atomically replacing a file.
Package atomicfile contains the platform-specific durability step required after atomically replacing a file.
diff
Package diff compares Prometheus and SigNoz query results.
Package diff compares Prometheus and SigNoz query results.
httpdetail
Package httpdetail bounds and neutralizes untrusted response text before it is copied into errors, terminal output, and migration evidence.
Package httpdetail bounds and neutralizes untrusted response text before it is copied into errors, terminal output, and migration evidence.
metricmap
Package metricmap loads explicit Prometheus-to-OpenTelemetry metric name mappings.
Package metricmap loads explicit Prometheus-to-OpenTelemetry metric name mappings.
safeoutput
Package safeoutput prevents generated output from replacing an input or an authoritative artifact through lexical, symbolic-link, or hard-link aliases.
Package safeoutput prevents generated output from replacing an input or an authoritative artifact through lexical, symbolic-link, or hard-link aliases.
stableidentity
Package stableidentity validates and hashes user-controlled identity components used by idempotent target upserts.
Package stableidentity validates and hashes user-controlled identity components used by idempotent target upserts.
target/perses
Package perses emits the SigNoz v6 (Perses-native) dashboard shape used by the v2 dashboard API (POST /api/v2/dashboards).
Package perses emits the SigNoz v6 (Perses-native) dashboard shape used by the v2 dashboard API (POST /api/v2/dashboards).
transportpolicy
Package transportpolicy centralizes credential-bearing HTTP policy.
Package transportpolicy centralizes credential-bearing HTTP policy.
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL