Skip to content

fix(observability): add missing controller Prometheus fields (JobsSubmitted/Failed/Completed) - #534

Merged
lusoris merged 1 commit into
masterfrom
fix/observability-prometheus-job-fields
Jun 3, 2026
Merged

lusoris merged 1 commit into
masterfrom
fix/observability-prometheus-job-fields

Conversation

@lusoris

@lusoris lusoris commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The Metrics struct in pkg/observability/observability.go was missing the three controller job-counter fields (JobsSubmitted, JobsFailed, JobsCompleted). NewMetrics() already initialized them and cmd/vmafx-controller/grpc_server.go already called .Inc() on them, so the package would not compile.
  • Also fixed tab-concatenated entries in go.mod / go.sum (pre-existing corruption that prevented go build) and added the missing modernc.org/sqlite dependency required by the controller queue package.

Wire-up verification

cmd/vmafx-controller/grpc_server.go calls:

  • c.metrics.JobsSubmitted.Inc() — line 153 (SubmitJob handler)
  • c.metrics.JobsFailed.Inc() — line 277 (ReportResult, error branch)
  • c.metrics.JobsCompleted.Inc() — line 279 (ReportResult, success branch)

All three are now declared on the struct and registered in the Prometheus registry under vmafx_controller_{jobs_submitted,jobs_completed,jobs_failed}_total.

Test plan

  • go vet ./pkg/observability/... ./cmd/vmafx-controller/... — passes
  • go test ./pkg/observability/... ./cmd/vmafx-controller/... — all pass (including TestNewMetrics_RegistersAllInstruments which explicitly exercises the three new counters)
  • pre-commit run --files pkg/observability/observability.go go.mod go.sum — all hooks pass

ADR-0108 deliverables checklist

  • Research digest: no digest needed: trivial bug fix, single missing struct field declaration
  • Decision matrix: no alternatives: only-one-way fix (declare the fields that were already used)
  • AGENTS.md invariant: no rebase-sensitive invariants introduced
  • Reproducer: go build ./pkg/observability/... failed with unknown field JobsSubmitted in struct literal; passes after this fix
  • Changelog fragment: changelog.d/fixes/observability-prometheus-job-fields.md
  • Rebase notes: no rebase impact: internal struct field addition, no ABI or API change

🤖 Generated with Claude Code

lusoris added a commit that referenced this pull request Jun 3, 2026
#534)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Jun 3, 2026
… binaries (ADR-0782) (#191)

Add OTel span instrumentation across all four VMAFX Go binaries
(vmafx-controller, vmafx-node, vmafx-server, vmafx-mcp). Rebased onto
master; keeps existing InitOTel API (ADR-0927), integrates ADR-0782
instruments as a pure addition.

Span coverage:
- vmafx.job.submit: controller SubmitJob gRPC handler (grpc_server.go)
- vmafx.scoring / vmafx.frame.extraction: node scoring pipeline
- vmafx.onnx.inference: AI path on vmafx-node

OTel metrics (pkg/observability/otel_instruments.go, new):
- vmafx.jobs.queued / vmafx.jobs.in_flight (UpDownCounters)
- vmafx.score_latency_ms (histogram, p50/p99 buckets)
- vmafx.frames_per_second / vmafx.gpu_utilization

Prometheus additions to pkg/observability.Metrics:
- JobsSubmitted / JobsCompleted / JobsFailed struct fields added
  (missing on master, causing compile failure — supersedes PR #534)

Infrastructure:
- go.mod/go.sum: fix tab-concatenated lines (pre-existing corruption);
  add modernc.org/sqlite v1.51.0 (required by vmafx-controller/queue)
- cmd/vmafx-controller/queue: add Depth() method (QueueDepthProvider)
- deploy/grafana/vmafx-overview.json: Grafana dashboard (new)
- deploy/helm/vmafx: optional otel-collector sidecar + values.yaml
- docs/observability/otel.md: quick-start, env vars, span names, metrics
- ADR-0782; changelog fragment; rebase-notes.md entry

All OTel init is non-fatal: missing OTLP collector never blocks startup.

go build ./cmd/... and go vet ./cmd/... (exc. pre-existing stale
executor_test.go API mismatch in vmafx-node) pass cleanly.

Co-authored-by: Lusoris <lusoris@pm.me>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
#534)

The core fix (JobsSubmitted/Failed/Completed fields added to Metrics struct)
was merged via PR #191 (feat(observability): wire OpenTelemetry). This commit
adds the missing changelog fragment for PR #534 that was blocked by conflicts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris
lusoris force-pushed the fix/observability-prometheus-job-fields branch from c7c6187 to 09f067d Compare June 3, 2026 12:46
@lusoris
lusoris marked this pull request as ready for review June 3, 2026 12:46
Copilot AI review requested due to automatic review settings June 3, 2026 12:46
@lusoris
lusoris merged commit 6fef483 into master Jun 3, 2026
26 of 33 checks passed
@lusoris
lusoris deleted the fix/observability-prometheus-job-fields branch June 3, 2026 12:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to fix a vmafx-controller observability build break by adding missing Prometheus controller job counters (JobsSubmitted, JobsFailed, JobsCompleted) to pkg/observability.Metrics, plus related module-file repairs and dependency additions. However, the provided diff for this review only contains a changelog fragment, so the functional Go changes described in the PR body are not visible here.

Changes:

  • Add a changelog.d/fixed/ fragment documenting the intended observability metrics fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- **observability**: add missing `JobsSubmitted`, `JobsFailed`, `JobsCompleted` fields to the
`Metrics` struct in `pkg/observability`. These fields were already initialised in `NewMetrics()`
and consumed by the controller gRPC server, but were absent from the struct declaration,
preventing the package from compiling. Fixes PR #534.
@@ -0,0 +1,4 @@
- **observability**: add missing `JobsSubmitted`, `JobsFailed`, `JobsCompleted` fields to the
@lusoris lusoris added this to the 1.0.0 — First release milestone Sep 4, 2026
lusoris added a commit that referenced this pull request Sep 30, 2026
…ocumentation gate

The standards gate now installs praetor main 25451d8 from the remote
module proxy (PRAETOR_REF was f41e74d on master). Every praetor-managed
file is regenerated with that engine's own code: adopt (with
--verification-max-entries 200000), sync, compile-context and
devcontainer --source-root at the pin, which keeps the vmafx-dev-mcp
base image.

Baseline (ADR-1351): f41e74d re-records 185 entries on this tree with no
growth, 25451d8 records 431. All 246 new fingerprints are engine
changes, replayed on the same tree against each commit's parent:
d7a3778 adds 61 process exits from library code (Python 51, Go 5,
Rust 5), 025bbc6 adds 142 long Python functions and 36 recursive ones,
53e7594 adds 7 Go calls without a deadline. They are recorded with
--allow-increase and a reason.

Documentation gate: praetor fixed cordanaLLM/praetor#532, #533 and #534,
so the gate now passes here. .standards.yaml raises max_files to 8192
and max_file_bytes to 4 MiB, and style-excludes the generated ADR
index, the ADR row fragments and testdata fixtures, the files the
repository's own markdownlint hook already skips. The other 75
findings are fixed in the source: the 14 predictor model cards and
their template in predictor_train.py (pinned by
test_predictor_card_markdown.py), an MD013 re-enable in the SYCL
overview and a fence language in the ADR fragments README. The figure
engine under tools/figures/, the docs-figures target, a .gitattributes
block and a workflow step arrive with it.

Praetor defects, filed or tracked upstream and worked around here:
- adopt still refuses to extend the Makefile block because of computed
  targets such as $(BUILD_DIR): (#537, open). GNU Make finds no
  docs-lint or docs-figures rule outside the block, so the block is
  praetor's own DocumentationMakefileBlock() text.
- The repository-wide dist/ rule hid tools/figures/dist/; .gitignore
  re-includes it (#591).
- black, ruff and markdownlint would rewrite or flag the locked
  figure engine; their pre-commit hooks skip tools/figures/ (#578).
- Praetor requires the retired numbered workspace root to be ignored
  (#641, filed with this change). The ADR-1277 contract check accepts
  only that rule inside praetor's block, skips tools/markdownlint/ when
  scanning for references and still fails on a local directory. ADR-1351
  amends ADR-1277.

Also: repository.default_branch: master renders the ruleset for master;
REUSE.toml labels the vendored interfig sources and the player bundle;
adopt's praetorctl pre-tool hook registrations in .claude/settings.json,
.codex/hooks.json and .gemini/settings.json are left out, since audit
does not verify them and they change every agent session.
T-PRAETOR-DOCS-GATE-LIMITS-2026-09-28 is closed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Sep 30, 2026
…ocumentation gate

The standards gate now installs praetor main 25451d8 from the remote
module proxy (PRAETOR_REF was f41e74d on master). Every praetor-managed
file is regenerated with that engine's own code: adopt (with
--verification-max-entries 200000), sync, compile-context and
devcontainer --source-root at the pin, which keeps the vmafx-dev-mcp
base image.

Baseline (ADR-1351): f41e74d re-records 185 entries on this tree with no
growth, 25451d8 records 431. All 246 new fingerprints are engine
changes, replayed on the same tree against each commit's parent:
d7a3778 adds 61 process exits from library code (Python 51, Go 5,
Rust 5), 025bbc6 adds 142 long Python functions and 36 recursive ones,
53e7594 adds 7 Go calls without a deadline. They are recorded with
--allow-increase and a reason.

Documentation gate: praetor fixed cordanaLLM/praetor#532, #533 and #534,
so the gate now passes here. .standards.yaml raises max_files to 8192
and max_file_bytes to 4 MiB, and style-excludes the generated ADR
index, the ADR row fragments and testdata fixtures, the files the
repository's own markdownlint hook already skips. The other 75
findings are fixed in the source: the 14 predictor model cards and
their template in predictor_train.py (pinned by
test_predictor_card_markdown.py), an MD013 re-enable in the SYCL
overview and a fence language in the ADR fragments README. The figure
engine under tools/figures/, the docs-figures target, a .gitattributes
block and a workflow step arrive with it.

Praetor defects, filed or tracked upstream and worked around here:
- adopt still refuses to extend the Makefile block because of computed
  targets such as $(BUILD_DIR): (#537, open). GNU Make finds no
  docs-lint or docs-figures rule outside the block, so the block is
  praetor's own DocumentationMakefileBlock() text.
- The repository-wide dist/ rule hid tools/figures/dist/; .gitignore
  re-includes it (#591).
- black, ruff and markdownlint would rewrite or flag the locked
  figure engine; their pre-commit hooks skip tools/figures/ (#578).
- Praetor requires the retired numbered workspace root to be ignored
  (#641, filed with this change). The ADR-1277 contract check accepts
  only that rule inside praetor's block, skips tools/markdownlint/ when
  scanning for references and still fails on a local directory. ADR-1351
  amends ADR-1277.

Also: repository.default_branch: master renders the ruleset for master;
REUSE.toml labels the vendored interfig sources and the player bundle;
adopt's praetorctl pre-tool hook registrations in .claude/settings.json,
.codex/hooks.json and .gemini/settings.json are left out, since audit
does not verify them and they change every agent session.
T-PRAETOR-DOCS-GATE-LIMITS-2026-09-28 is closed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Sep 30, 2026
…ocumentation gate

The standards gate now installs praetor main 25451d8 from the remote
module proxy (PRAETOR_REF was f41e74d on master). Every praetor-managed
file is regenerated with that engine's own code: adopt (with
--verification-max-entries 200000), sync, compile-context and
devcontainer --source-root at the pin, which keeps the vmafx-dev-mcp
base image.

Baseline (ADR-1351): f41e74d re-records 185 entries on this tree with no
growth, 25451d8 records 431. All 246 new fingerprints are engine
changes, replayed on the same tree against each commit's parent:
d7a3778 adds 61 process exits from library code (Python 51, Go 5,
Rust 5), 025bbc6 adds 142 long Python functions and 36 recursive ones,
53e7594 adds 7 Go calls without a deadline. They are recorded with
--allow-increase and a reason.

Documentation gate: praetor fixed cordanaLLM/praetor#532, #533 and #534,
so the gate now passes here. .standards.yaml raises max_files to 8192
and max_file_bytes to 4 MiB, and style-excludes the generated ADR
index, the ADR row fragments and testdata fixtures, the files the
repository's own markdownlint hook already skips. The other 75
findings are fixed in the source: the 14 predictor model cards and
their template in predictor_train.py (pinned by
test_predictor_card_markdown.py), an MD013 re-enable in the SYCL
overview and a fence language in the ADR fragments README. The figure
engine under tools/figures/, the docs-figures target, a .gitattributes
block and a workflow step arrive with it.

Praetor defects, filed or tracked upstream and worked around here:
- adopt still refuses to extend the Makefile block because of computed
  targets such as $(BUILD_DIR): (#537, open). GNU Make finds no
  docs-lint or docs-figures rule outside the block, so the block is
  praetor's own DocumentationMakefileBlock() text.
- The repository-wide dist/ rule hid tools/figures/dist/; .gitignore
  re-includes it (#591).
- black, ruff and markdownlint would rewrite or flag the locked
  figure engine; their pre-commit hooks skip tools/figures/ (#578).
- Praetor requires the retired numbered workspace root to be ignored
  (#641, filed with this change). The ADR-1277 contract check accepts
  only that rule inside praetor's block, skips tools/markdownlint/ when
  scanning for references and still fails on a local directory. ADR-1351
  amends ADR-1277.

Also: repository.default_branch: master renders the ruleset for master;
REUSE.toml labels the vendored interfig sources and the player bundle;
adopt's praetorctl pre-tool hook registrations in .claude/settings.json,
.codex/hooks.json and .gemini/settings.json are left out, since audit
does not verify them and they change every agent session.
T-PRAETOR-DOCS-GATE-LIMITS-2026-09-28 is closed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request Sep 30, 2026
…ocumentation gate

The standards gate now installs praetor main 25451d8 from the remote
module proxy (PRAETOR_REF was f41e74d on master). Every praetor-managed
file is regenerated with that engine's own code: adopt (with
--verification-max-entries 200000), sync, compile-context and
devcontainer --source-root at the pin, which keeps the vmafx-dev-mcp
base image.

Baseline (ADR-1351): f41e74d re-records 185 entries on this tree with no
growth, 25451d8 records 431. All 246 new fingerprints are engine
changes, replayed on the same tree against each commit's parent:
d7a3778 adds 61 process exits from library code (Python 51, Go 5,
Rust 5), 025bbc6 adds 142 long Python functions and 36 recursive ones,
53e7594 adds 7 Go calls without a deadline. They are recorded with
--allow-increase and a reason.

Documentation gate: praetor fixed cordanaLLM/praetor#532, #533 and #534,
so the gate now passes here. .standards.yaml raises max_files to 8192
and max_file_bytes to 4 MiB, and style-excludes the generated ADR
index, the ADR row fragments and testdata fixtures, the files the
repository's own markdownlint hook already skips. The other 75
findings are fixed in the source: the 14 predictor model cards and
their template in predictor_train.py (pinned by
test_predictor_card_markdown.py), an MD013 re-enable in the SYCL
overview and a fence language in the ADR fragments README. The figure
engine under tools/figures/, the docs-figures target, a .gitattributes
block and a workflow step arrive with it.

Praetor defects, filed or tracked upstream and worked around here:
- adopt still refuses to extend the Makefile block because of computed
  targets such as $(BUILD_DIR): (#537, open). GNU Make finds no
  docs-lint or docs-figures rule outside the block, so the block is
  praetor's own DocumentationMakefileBlock() text.
- The repository-wide dist/ rule hid tools/figures/dist/; .gitignore
  re-includes it (#591).
- black, ruff and markdownlint would rewrite or flag the locked
  figure engine; their pre-commit hooks skip tools/figures/ (#578).
- Praetor requires the retired numbered workspace root to be ignored
  (#641, filed with this change). The ADR-1277 contract check accepts
  only that rule inside praetor's block, skips tools/markdownlint/ when
  scanning for references and still fails on a local directory. ADR-1351
  amends ADR-1277.

Also: repository.default_branch: master renders the ruleset for master;
REUSE.toml labels the vendored interfig sources and the player bundle;
adopt's praetorctl pre-tool hook registrations in .claude/settings.json,
.codex/hooks.json and .gemini/settings.json are left out, since audit
does not verify them and they change every agent session.
T-PRAETOR-DOCS-GATE-LIMITS-2026-09-28 is closed.
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