Skip to content

Local OTEL smoke stack: kind + VictoriaMetrics + VMUI, driven by Makefile targets#23

Merged
berendt merged 3 commits into
mainfrom
implement/issue-22-local-otel-stack
Jul 2, 2026
Merged

Local OTEL smoke stack: kind + VictoriaMetrics + VMUI, driven by Makefile targets#23
berendt merged 3 commits into
mainfrom
implement/issue-22-local-otel-stack

Conversation

@berendt

@berendt berendt commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Closes #22

Summary

A one-command local OTEL smoke stack — analogous to make testbed — for exercising the neutron monitor --otel seam (#19) end to end against the OSISM testbed. A kind cluster runs single-node VictoriaMetrics, which ingests the tester's OTLP/HTTP push directly (no OTel Collector) and serves VMUI (no Grafana). The whole thing is Makefile + manifests + docs; the tester binary is untouched, exactly as the issue's non-goals require.

make otel-up          # boot kind + VictoriaMetrics on :8428
make testbed-monitor  # neutron monitor --otel against the testbed
make otel-ui          # open VMUI with pre-filled queries

Change set (in commit order)

59989a1 — Add kind and VictoriaMetrics manifests for local OTEL stack
The backend half.

  • contrib/otel/kind.yaml: single-node cluster ostester-otel, extraPortMapping host 8428 → node NodePort 30428, so the host binary and browser reach VM at plain http://localhost:8428.
  • contrib/otel/victoria-metrics.yaml: plain manifests (no Helm) — Namespace + single-replica Deployment + NodePort Service (30428). Image pinned to victoriametrics/victoria-metrics:v1.146.0 by digest. Flags: -retentionPeriod=30d, -opentelemetry.usePrometheusNaming=true (stores series under the Prometheus canonical names the README schema documents), and -opentelemetry.promoteAllResourceAttributes=true (attaches the cloud/scenario resource attributes as labels). emptyDir storage — survives monitor restarts, not make otel-down.

bcb1a87 — Add otel-up/down/verify/ui and testbed-monitor Make targets
The lifecycle.

  • otel-up: preflight-checks docker/kind/kubectl/curl, creates the cluster idempotently, applies the manifests, waits for the rollout, polls /health.
  • otel-down: deletes the cluster and its state.
  • otel-verify: asserts the five documented metric families are stored (non-zero exit if any missing) and prints the cloud/scenario label values.
  • otel-ui: opens VMUI with two pre-filled queries.
  • testbed-monitor: reuses the testbed file guards, then runs neutron monitor --otel with the signal-specific OTEL_EXPORTER_OTLP_METRICS_ENDPOINT pointed at VM and a 15 s export interval. Adds MONITOR_INTERVAL ?= 5m / MONITOR_ITERATIONS ?= 0. Warns (does not fail) when :8428/health is unreachable, since --otel export failures already degrade to warnings. Widens the help column so the longer target names stay aligned.

7e8be57 — Document the local OTEL smoke stack in the README
New README §9 subsection: prerequisites, the three-command flow, how the collector-less ingestion and Prometheus naming work, the query cookbook (works against this stack unchanged), and teardown. Cross-references the existing collector example, and warns about using the signal-specific OTEL_EXPORTER_OTLP_METRICS_ENDPOINT (the generic OTEL_EXPORTER_OTLP_ENDPOINT would miss VM's ingestion path and silently drop metrics).

Divergences from the issue

  • -opentelemetry.promoteAllResourceAttributes=true added beyond the issue's manifest sketch (which listed only usePrometheusNaming). Without it the cloud/scenario attributes would not appear as labels, so the acceptance criterion ("…with cloud and scenario resource attributes attached") would fail. The flag exists from VM v1.145.0, which is why the image is pinned to v1.146.0 and must not be downgraded past it.
  • otel-verify is stronger than the sketched curl … | grep openstack_tester: it checks each of the five documented metric families individually (failing on any miss) and echoes the cloud/scenario label values — matching the acceptance criteria directly rather than a coarse grep.
  • kind host-port bound to loopback (listenAddress: "127.0.0.1"), not in the issue — a security hardening so the unauthenticated VM store is not published on every host interface. The manifest comment documents the residual NodePort exposure on the docker network as accepted for a throwaway stack.
  • Reviewer note — stale run-record sweep claim. The final testbed-monitor target deliberately runs no post-run run-*.json sweep; its Makefile comment explains why (monitor cleans up each iteration itself, and a shared-directory sweep would tear down a concurrent make testbed run's resources). However, the bcb1a87 commit message ("reuses the testbed guards and run-record sweep") and a README sentence ("any leftover run-*.json is swept, exactly as make testbed does") still describe the earlier, swept behavior. The code is the intended final state; the prose is stale. Flagging rather than fixing, since the diff is final for this PR.

Verification

Per the issue's acceptance criteria, this is validated by running make otel-upmake testbed-monitormake otel-verify / make otel-ui against the testbed; no automated tests are added (the change is manifests + Makefile + docs).


Implemented by planwerk-agent 6b3f3ea with Claude:claude-opus-4-8

berendt added 3 commits July 2, 2026 16:41
The backend half of the local OTEL smoke stack: a single-node kind
cluster mapping host port 8428 to NodePort 30428, and a pinned
VictoriaMetrics single-node that ingests the tester's OTLP/HTTP push
natively at /opentelemetry/v1/metrics — no OTel Collector.

-opentelemetry.usePrometheusNaming stores the OTLP series under the
Prometheus canonical names the README documents, and
-opentelemetry.promoteAllResourceAttributes attaches the tester's
cloud and scenario resource attributes to every series.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Christian Berendt <berendt@b42labs.com>
One-command lifecycle for the local OTEL smoke stack:

- otel-up boots the kind cluster (idempotent), applies the manifests,
  waits for the rollout, and polls /health.
- otel-down deletes the cluster and its state.
- otel-verify checks the five documented metric families are stored and
  prints the cloud/scenario label values.
- otel-ui opens VMUI with two pre-filled queries.
- testbed-monitor reuses the testbed guards and run-record sweep, then
  runs neutron monitor --otel with the signal-specific
  OTEL_EXPORTER_OTLP_METRICS_ENDPOINT pointed at VictoriaMetrics and a
  15s export interval for fast local feedback.

Widens the help column so the longer target names stay aligned.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Christian Berendt <berendt@b42labs.com>
New README §9 subsection: prerequisites, the three-command flow
(otel-up -> testbed-monitor -> otel-ui), how the collector-less
VictoriaMetrics ingestion and Prometheus naming work, the query
cookbook, and teardown. Cross-references the collector example and the
existing cookbook, and warns about the signal-specific OTLP endpoint
variable.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Christian Berendt <berendt@b42labs.com>
@berendt
berendt marked this pull request as ready for review July 2, 2026 14:46
@berendt
berendt merged commit b3f8ec0 into main Jul 2, 2026
2 checks passed
@berendt
berendt deleted the implement/issue-22-local-otel-stack branch July 2, 2026 14:46
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.

Local OTEL smoke stack: kind + VictoriaMetrics + VMUI, driven by Makefile targets

1 participant