Skip to content

docs(cluster-management): add NVCF UI page to Configuration section - #565

Closed
apartha-nv wants to merge 2 commits into
mainfrom
docs/enabling-nvcf-ui
Closed

docs(cluster-management): add NVCF UI page to Configuration section#565
apartha-nv wants to merge 2 commits into
mainfrom
docs/enabling-nvcf-ui

Conversation

@apartha-nv

@apartha-nv apartha-nv commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

TL;DR

Add a dedicated NVCF UI page to the Configuration section of the docs, documenting how to enable the opt-in gateway route for the nvcf-ui addon.

Additional Details (optional for docs, build, test, refactor, ci, chore, style, and revert PRs)

PR #312 added the opt-in HTTPRoute and ReferenceGrant for the nvcf-ui addon to the gateway-routes chart but did not include documentation. This PR adds that documentation as a standalone page in the Configuration nav section (between Multi-Tenancy and KAI Scheduler), covering prerequisites, the helmfile values to set, how to sync, and a verification step.

For the Reviewer

  • docs/user/cluster-management/nvcf-ui.md — new page
  • fern/versions/dev.yml — nav entry added between Multi-Tenancy and KAI Scheduler

For QA (optional for docs, build, test, refactor, ci, chore, style, and revert PRs)

Docs-only change. No QA needed.

Issues

Relates to #312

Checklist

  • I am familiar with the Contributing Guidelines.
  • I have signed off my commits for Developer Certificate of Origin (DCO) compliance.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

Summary by CodeRabbit

  • New Features
    • Added optional OpenTelemetry client metrics for outbound HTTP requests, including duration, body size, status, error, and dependency labels.
    • Added a feature flag to enable client metrics, disabled by default.
    • Added support for stable URL templates to limit metric label cardinality.
    • Added documentation for configuring the optional NVCF UI and NVCA feature flags.
  • Documentation
    • Added guidance for outbound client metrics instrumentation and configuration.
  • Tests
    • Added coverage for metrics export, transport wrapping, error classification, and URL templates.

NVCA now emits OpenTelemetry Semantic Conventions metrics for its
outbound HTTP dependency calls from one shared client. A new OTel
MeterProvider + Prometheus exporter bridge serves semconv
http.client.* metrics on the existing /metrics endpoint, alongside
the current client_golang metrics (no second endpoint, no scrape
change).

Instrumentation lives in a metrics RoundTripper on the shared
retryable HTTP client (ICMS and ReVal wired), gated by a new
ClientMetrics feature flag that is off by default.

- Adds OTel MeterProvider (internal/otel/meter.go) bridged to
  Prometheus; the exporter registers into the same registry /metrics
  already serves.
- Adds semconv helper packages (httpsemconv, msgsemconv, rpcsemconv)
  for a consistent, bounded label vocabulary; HTTP is wired,
  messaging/RPC are scaffolded for follow-ups.
- Adds shared Recorder + metrics RoundTripper
  (internal/metrics/clientmetrics/) recording RED metrics with the
  four NVCA default labels, peer.service, and per-operation
  url.template supplied via request context.
- Adds generic WithTransportWrapper option on NewRetryableClient;
  otelhttp client metrics are suppressed so the custom RoundTripper
  is the single source (avoids double-counting
  http.client.request.duration).
- Instruments ICMS and ReVal. NGC is operator-side and is a follow-up;
  SQS/NATS (queue) and gRPC are out of scope.

New dependencies: go.opentelemetry.io/otel/exporters/prometheus
v0.66.0, go.opentelemetry.io/otel/metric v1.44.0,
go.opentelemetry.io/otel/sdk/metric v1.44.0,
github.com/prometheus/otlptranslator (vendored).

Relates to NVCFSRE-7498
Add a dedicated page documenting how to enable the opt-in NVCF UI
gateway route introduced in PR #312 (feat(gateway-routes): add opt-in
HTTPRoute for the nvcf-ui addon.

The page covers prerequisites, the helmfile environment values to set,
the sync command, and a verification step. It is placed in the
Configuration section of the navigation between Multi-Tenancy and
KAI Scheduler.

Relates to #312
EOF
)

Signed-off-by: Anand Parthasarathi <aparthasarat@nvidia.com>
@apartha-nv
apartha-nv requested review from a team as code owners July 30, 2026 06:23
@apartha-nv
apartha-nv requested a review from vrv3814 July 30, 2026 06:23
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Added feature-gated OpenTelemetry outbound HTTP metrics for NVCA, including Prometheus export, semantic conventions, transport wrappers, ICMS/ReVal integration, URL-template labels, tests, documentation, and dependency wiring.

Changes

Outbound client metrics

Layer / File(s) Summary
Metric contracts and recording
src/compute-plane-services/nvca/internal/metrics/semconv/*, src/compute-plane-services/nvca/internal/metrics/clientmetrics/*
Adds bounded semantic-convention attributes, shared HTTP histograms, URL-template context handling, and Bazel targets.
Prometheus meter provider
src/compute-plane-services/nvca/internal/otel/*
Adds enabled and no-op OpenTelemetry meter-provider setup with Prometheus registry export and tests.
HTTP transport instrumentation
src/libraries/go/lib/pkg/http/*, src/compute-plane-services/nvca/internal/metrics/clientmetrics/*
Adds optional outer transport wrapping, disables duplicate default OTel metrics, records request outcomes, and validates exported series.
NVCA client integration
src/compute-plane-services/nvca/pkg/nvca/*, src/compute-plane-services/nvca/pkg/featureflag/featureflag.go
Adds the ClientMetrics flag, agent lifecycle handling, ICMS URL templates, and conditional ICMS/ReVal instrumentation.
Documentation and dependency wiring
src/compute-plane-services/nvca/docs/*, src/compute-plane-services/nvca/internal/metrics/METRICS.md, docs/user/cluster-management/*, MODULE.bazel, NOTICE, **/go.mod
Documents metrics, feature flags, and NVCF UI setup while updating Bazel repositories, Go modules, licenses, and navigation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant NVCAAgent
  participant RetryableHTTPClient
  participant ClientMetricsTransport
  participant Prometheus
  CLI->>NVCAAgent: pass ClientMetrics feature flag
  NVCAAgent->>RetryableHTTPClient: configure wrapped ICMS/ReVal clients
  RetryableHTTPClient->>ClientMetricsTransport: send outbound request
  ClientMetricsTransport->>Prometheus: record duration, sizes, and labels
Loading

Suggested reviewers: vrv3814

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commits and accurately describes a real part of the PR: adding the NVCF UI documentation page.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch docs/enabling-nvcf-ui
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/enabling-nvcf-ui

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands.

@apartha-nv

Copy link
Copy Markdown
Contributor Author

Closing in favor of a clean branch rebased on main.

@apartha-nv apartha-nv closed this Jul 30, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
src/libraries/go/lib/pkg/http/retryclient.go (1)

93-136: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

WithTransportWrapper silently assumes every wrapper is a metrics wrapper.

The option is documented as a generic extension point for "cross-cutting transport behaviour such as metrics," but the implementation unconditionally disables otelhttp's own default HTTP client metrics whenever any wrapper is supplied (Lines 133-135). A future caller using WithTransportWrapper for a non-metrics purpose (e.g., request signing, header injection) would silently lose otelhttp's default metrics with no indication.

Consider decoupling: only suppress otelhttp's metrics via a dedicated, explicit option (or document that WithTransportWrapper implies metrics ownership) so the side effect isn't implicit in a general-purpose extension point.

♻️ Proposed fix: make suppression explicit
-	// otelhttp provides client tracing (unchanged for all callers). Its own HTTP
-	// client metrics are suppressed only when a metrics transport wrapper is
-	// present, so that wrapper is the single source for the semconv HTTP client
-	// series and does not double-count. Callers without a transport wrapper keep
-	// otelhttp's default metric behaviour.
-	var otelOpts []otelhttp.Option
-	if f.transportWrapper != nil {
-		otelOpts = append(otelOpts, otelhttp.WithMeterProvider(metricnoop.NewMeterProvider()))
-	}
+	// otelhttp provides client tracing (unchanged for all callers). Its own HTTP
+	// client metrics are suppressed only when the caller explicitly opts in via
+	// WithSuppressDefaultHTTPMetrics, so that a metrics transport wrapper can be
+	// the single source of the semconv HTTP client series without double-counting.
+	var otelOpts []otelhttp.Option
+	if f.suppressDefaultHTTPMetrics {
+		otelOpts = append(otelOpts, otelhttp.WithMeterProvider(metricnoop.NewMeterProvider()))
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/libraries/go/lib/pkg/http/retryclient.go` around lines 93 - 136, Decouple
otelhttp metric suppression from the generic WithTransportWrapper option: add a
dedicated explicit feature/Option for callers that own HTTP client metrics, and
check that option—not f.transportWrapper—in NewRetryableClient before applying
metricnoop.NewMeterProvider. Keep transport wrapping available without changing
otelhttp’s default metrics unless suppression is explicitly requested.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/compute-plane-services/nvca/AGENTS.md`:
- Around line 399-419: Reduce AGENTS.md to below 400 lines by removing the
detailed “OTel client metrics (outbound dependencies)” recipe and moving its
guidance to internal/metrics/METRICS.md. Retain only a concise pointer in
AGENTS.md directing contributors to that document for OTel client metrics
instructions.

In `@src/compute-plane-services/nvca/docs/users/byoc/featureflags.md`:
- Around line 7-8: Remove Markdown bold emphasis from both “Note” labels in
src/compute-plane-services/nvca/docs/users/byoc/featureflags.md at lines 7-8 and
83, leaving each label as plain text while preserving the surrounding
documentation.
- Line 12: Update the configuration example code fence in featureflags.md to
declare the yaml language, using a yaml fence for the existing code block while
preserving its contents.

In
`@src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go`:
- Around line 40-48: Update the ClientAttrs documentation to state that
peerService and method are included only when non-empty, matching the existing
conditional attribute construction; leave the implementation behavior unchanged.

In `@src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go`:
- Around line 55-84: Add tests covering ClassifyError in
src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go, including
wrapped errors and precedence between deadline, cancellation,
connection-refused, timeout, and fallback classifications. Add tests in
src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go,
src/compute-plane-services/nvca/internal/metrics/semconv/msgsemconv/msgsemconv.go,
and
src/compute-plane-services/nvca/internal/metrics/semconv/rpcsemconv/rpcsemconv.go
for optional attributes, status/error combinations, and the -1 and 0 sentinel
values.

---

Nitpick comments:
In `@src/libraries/go/lib/pkg/http/retryclient.go`:
- Around line 93-136: Decouple otelhttp metric suppression from the generic
WithTransportWrapper option: add a dedicated explicit feature/Option for callers
that own HTTP client metrics, and check that option—not f.transportWrapper—in
NewRetryableClient before applying metricnoop.NewMeterProvider. Keep transport
wrapping available without changing otelhttp’s default metrics unless
suppression is explicitly requested.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 048b19ee-82bc-4aab-a4be-31487b5e703a

📥 Commits

Reviewing files that changed from the base of the PR and between 6e96474 and 98344fc.

⛔ Files ignored due to path filters (97)
  • src/compute-plane-services/nvca/go.sum is excluded by !**/*.sum
  • src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/http/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/http/retryclient.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/.gitignore is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/.golangci.yml is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/CODE_OF_CONDUCT.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/LICENSE is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/MAINTAINERS.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/README.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/SECURITY.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/constants.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/doc.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/label_namer.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/metric_namer.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/metric_type.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/strategy.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/strconv.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/github.com/prometheus/otlptranslator/unit_namer.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/LICENSE is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/README.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/errors.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/counter/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/counter/counter.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/gen.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/observ/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/observ/instrumentation.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/version.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/README.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/features.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/exporters/prometheus/internal/x/x.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/LICENSE is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/README.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/aggregation.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/cache.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/config.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/doc.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/env.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/README.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/doc.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/exemplar.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/filter.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/fixed_size_reservoir.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/histogram_reservoir.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/reservoir.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/storage.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exemplar/value.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/exporter.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/instrument.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/instrumentkind_string.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/aggregate.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/atomic.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/doc.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/drop.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exemplar.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/exponential_histogram.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/filtered_reservoir.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/histogram.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/lastvalue.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/limit.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/aggregate/sum.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/observ/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/observ/instrumentation.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/concurrent_safe.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reservoir/doc.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/reuse_slice.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/README.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/internal/x/x.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/manual_reader.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/meter.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/BUILD.bazel is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/README.md is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/data.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/metricdata/temporality_string.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/periodic_reader.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/pipeline.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/provider.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/reader.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/splitmetrics.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/version.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/go.opentelemetry.io/otel/sdk/metric/view.go is excluded by !**/vendor/**
  • src/compute-plane-services/nvca/vendor/modules.txt is excluded by !**/vendor/**
  • src/libraries/go/lib/go.sum is excluded by !**/*.sum
📒 Files selected for processing (37)
  • MODULE.bazel
  • NOTICE
  • docs/user/cluster-management/nvcf-ui.md
  • fern/versions/dev.yml
  • src/compute-plane-services/nvca/AGENTS.md
  • src/compute-plane-services/nvca/MODULE.bazel
  • src/compute-plane-services/nvca/docs/users/byoc/featureflags.md
  • src/compute-plane-services/nvca/docs/users/byoc/featureflags.md.tmpl
  • src/compute-plane-services/nvca/go.mod
  • src/compute-plane-services/nvca/internal/metrics/METRICS.md
  • src/compute-plane-services/nvca/internal/metrics/clientmetrics/BUILD.bazel
  • src/compute-plane-services/nvca/internal/metrics/clientmetrics/e2e_scrape_test.go
  • src/compute-plane-services/nvca/internal/metrics/clientmetrics/recorder.go
  • src/compute-plane-services/nvca/internal/metrics/clientmetrics/roundtripper.go
  • src/compute-plane-services/nvca/internal/metrics/clientmetrics/roundtripper_test.go
  • src/compute-plane-services/nvca/internal/metrics/clientmetrics/urltemplate.go
  • src/compute-plane-services/nvca/internal/metrics/semconv/BUILD.bazel
  • src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/BUILD.bazel
  • src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go
  • src/compute-plane-services/nvca/internal/metrics/semconv/msgsemconv/BUILD.bazel
  • src/compute-plane-services/nvca/internal/metrics/semconv/msgsemconv/msgsemconv.go
  • src/compute-plane-services/nvca/internal/metrics/semconv/rpcsemconv/BUILD.bazel
  • src/compute-plane-services/nvca/internal/metrics/semconv/rpcsemconv/rpcsemconv.go
  • src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go
  • src/compute-plane-services/nvca/internal/otel/BUILD.bazel
  • src/compute-plane-services/nvca/internal/otel/meter.go
  • src/compute-plane-services/nvca/internal/otel/meter_test.go
  • src/compute-plane-services/nvca/pkg/featureflag/featureflag.go
  • src/compute-plane-services/nvca/pkg/nvca/BUILD.bazel
  • src/compute-plane-services/nvca/pkg/nvca/agent.go
  • src/compute-plane-services/nvca/pkg/nvca/agent_manager.go
  • src/compute-plane-services/nvca/pkg/nvca/cli.go
  • src/compute-plane-services/nvca/pkg/nvca/icms_client.go
  • src/libraries/go/lib/go.mod
  • src/libraries/go/lib/pkg/http/BUILD.bazel
  • src/libraries/go/lib/pkg/http/retryclient.go
  • src/libraries/go/lib/pkg/http/retryclient_transportwrapper_test.go

Comment on lines +399 to +419
### OTel client metrics (outbound dependencies)

Outbound dependency clients are instrumented with OpenTelemetry metrics that
follow the OpenTelemetry Semantic Conventions, separate from the client_golang
metrics above. This path does not use the manual zero-init loops; instruments are
created from an OTel MeterProvider and exported through the OTel to Prometheus
bridge onto the same `/metrics` endpoint.

- Pipeline: `internal/otel/meter.go` builds the MeterProvider and Prometheus
exporter. It is gated by the `ClientMetrics` feature flag; when off, a no-op
meter provider is installed and nothing is emitted.
- Recording: `internal/metrics/clientmetrics/` holds the shared `Recorder` and
the HTTP metrics `RoundTripper`. The wrapper is attached to a client through the
shared HTTP factory's `WithTransportWrapper` option.
- Labels: use the semconv helpers in `internal/metrics/semconv/` (`httpsemconv`,
`msgsemconv`, `rpcsemconv`). Keep label values bounded.
- Adding a dependency: for a new HTTP client, pass the metrics transport wrapper
with a `peer.service` name (add the constant in
`internal/metrics/clientmetrics`). For a new client type, add a thin decorator
over the shared `Recorder`. See `internal/metrics/METRICS.md` for the recipe.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Keep this AGENTS.md below 400 lines.

The file now reaches line 442. Move this detailed metrics recipe to internal/metrics/METRICS.md and retain only a short pointer here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/compute-plane-services/nvca/AGENTS.md` around lines 399 - 419, Reduce
AGENTS.md to below 400 lines by removing the detailed “OTel client metrics
(outbound dependencies)” recipe and moving its guidance to
internal/metrics/METRICS.md. Retain only a concise pointer in AGENTS.md
directing contributors to that document for OTel client metrics instructions.

Source: Coding guidelines

Comment on lines +7 to +8
**Note**: make sure to copy over existing spec feature flag values into the equivalent override values,
since that list overwritten not merged.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove Markdown bold emphasis.

Repository documentation rules prohibit Markdown bold.

  • src/compute-plane-services/nvca/docs/users/byoc/featureflags.md#L7-L8: replace the bold “Note” label with plain text.
  • src/compute-plane-services/nvca/docs/users/byoc/featureflags.md#L83-L83: replace the bold “Note” label with plain text.
📍 Affects 1 file
  • src/compute-plane-services/nvca/docs/users/byoc/featureflags.md#L7-L8 (this comment)
  • src/compute-plane-services/nvca/docs/users/byoc/featureflags.md#L83-L83
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/compute-plane-services/nvca/docs/users/byoc/featureflags.md` around lines
7 - 8, Remove Markdown bold emphasis from both “Note” labels in
src/compute-plane-services/nvca/docs/users/byoc/featureflags.md at lines 7-8 and
83, leaving each label as plain text while preserving the surrounding
documentation.

Source: Coding guidelines


Example:

```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Declare the code-block language.

Use a yaml fence so Markdown tooling and renderers classify the configuration example correctly.

-```
+```yaml
🧰 Tools
🪛 markdownlint-cli2 (0.23.1)

[warning] 12-12: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/compute-plane-services/nvca/docs/users/byoc/featureflags.md` at line 12,
Update the configuration example code fence in featureflags.md to declare the
yaml language, using a yaml fence for the existing code block while preserving
its contents.

Source: Linters/SAST tools

Comment on lines +40 to +48
// ClientAttrs returns the semconv attribute set for one outbound HTTP client
// call. peerService and method are always included. statusCode is included when
// greater than zero (a response was received); urlTemplate and errType are
// included only when non-empty, so successful calls carry no error.type and
// transport failures carry no status code.
func ClientAttrs(peerService, method, serverAddress, urlTemplate string, statusCode int, errType string) []attribute.KeyValue {
attrs := make([]attribute.KeyValue, 0, 6)
if peerService != "" {
attrs = append(attrs, semconv.PeerService(peerService))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align ClientAttrs documentation with its optional-attribute behavior.

The comment says peerService and method are always included, but the implementation omits both when empty. Update the contract to say they are included when non-empty, or enforce non-empty inputs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go`
around lines 40 - 48, Update the ClientAttrs documentation to state that
peerService and method are included only when non-empty, matching the existing
conditional attribute construction; leave the implementation behavior unchanged.

Comment on lines +55 to +84
// PeerService returns the peer.service attribute for the given dependency name.
func PeerService(name string) attribute.KeyValue {
return PeerServiceKey.String(name)
}

// ErrorType returns the error.type attribute for the given value.
func ErrorType(value string) attribute.KeyValue {
return ErrorTypeKey.String(value)
}

// ClassifyError maps an error to a bounded error.type value. It returns an
// empty string for a nil error so callers can omit the attribute on success.
func ClassifyError(err error) string {
if err == nil {
return ""
}
switch {
case errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded):
return ErrorTypeTimeout
case errors.Is(err, context.Canceled):
return ErrorTypeCanceled
case errors.Is(err, syscall.ECONNREFUSED):
return ErrorTypeConnectionRefused
}
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
return ErrorTypeTimeout
}
return ErrorTypeOther
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

git ls-files 'src/compute-plane-services/nvca/internal/metrics/semconv/**' 'src/compute-plane-services/nvca/internal/metrics/**' | sed -n '1,200p'

Repository: NVIDIA/nvcf

Length of output: 2199


🏁 Script executed:

python3 - <<'PY'
import subprocess, shlex, os, textwrap, json, sys
paths = [
    'src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go',
    'src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go',
    'src/compute-plane-services/nvca/internal/metrics/semconv/msgsemconv/msgsemconv.go',
    'src/compute-plane-services/nvca/internal/metrics/semconv/rpcsemconv/rpcsemconv.go',
]
for p in paths:
    print(f"\n## {p}")
    try:
        out = subprocess.check_output(['bash','-lc', f"grep -n \"^func \\|^type \\|^var \\|^const \\|^package \" {shlex.quote(p)} | sed -n '1,120p'"], text=True)
        print(out)
    except subprocess.CalledProcessError as e:
        print(e.output)
PY

Repository: NVIDIA/nvcf

Length of output: 1170


🏁 Script executed:

rg -n "ClassifyError|ClientAttrs|ErrorTypeTimeout|ErrorTypeCanceled|ErrorTypeConnectionRefused" src/compute-plane-services/nvca/internal/metrics -g '*_test.go'

Repository: NVIDIA/nvcf

Length of output: 149


🏁 Script executed:

python3 - <<'PY'
import os, glob, subprocess, textwrap

targets = [
    'src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go',
    'src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go',
    'src/compute-plane-services/nvca/internal/metrics/semconv/msgsemconv/msgsemconv.go',
    'src/compute-plane-services/nvca/internal/metrics/semconv/rpcsemconv/rpcsemconv.go',
]
for t in targets:
    base = os.path.dirname(t)
    stem = os.path.splitext(os.path.basename(t))[0]
    test_candidates = [p for p in glob.glob(os.path.join(base, '*_test.go'))]
    print(f'\n## {t}')
    print('test files:', ', '.join(os.path.relpath(p) for p in sorted(test_candidates)) or '(none)')
    for p in sorted(test_candidates):
        with open(p, 'r', encoding='utf-8') as f:
            txt = f.read()
        hits = [line for line in txt.splitlines() if any(k in line for k in ['ClassifyError', 'ClientAttrs', 'ErrorTypeTimeout', 'ErrorTypeCanceled', 'ErrorTypeConnectionRefused', 'ErrorTypeOther', 'BatchMessageCount', 'GRPCStatusCodeKey'])]
        if hits:
            print(f'-- hits in {os.path.relpath(p)}')
            for h in hits[:20]:
                print(h)
PY

Repository: NVIDIA/nvcf

Length of output: 557


Add tests for the new semconv contracts.

  • Cover error-classification precedence and wrapping in src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go.
  • Cover optional attributes and status/error combinations in httpsemconv.go, msgsemconv.go, and rpcsemconv.go, including the -1 and 0 sentinels.
📍 Affects 4 files
  • src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go#L55-L84 (this comment)
  • src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go#L40-L66
  • src/compute-plane-services/nvca/internal/metrics/semconv/msgsemconv/msgsemconv.go#L43-L68
  • src/compute-plane-services/nvca/internal/metrics/semconv/rpcsemconv/rpcsemconv.go#L41-L61
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go` around
lines 55 - 84, Add tests covering ClassifyError in
src/compute-plane-services/nvca/internal/metrics/semconv/semconv.go, including
wrapped errors and precedence between deadline, cancellation,
connection-refused, timeout, and fallback classifications. Add tests in
src/compute-plane-services/nvca/internal/metrics/semconv/httpsemconv/httpsemconv.go,
src/compute-plane-services/nvca/internal/metrics/semconv/msgsemconv/msgsemconv.go,
and
src/compute-plane-services/nvca/internal/metrics/semconv/rpcsemconv/rpcsemconv.go
for optional attributes, status/error combinations, and the -1 and 0 sentinel
values.

Source: Coding guidelines

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