Skip to content

fix(byoo-otel-collector): set honor_timestamps false on federated scrape jobs - #1530

Open
kristinapathak wants to merge 1 commit into
mainfrom
fix/byoo-federate-honor-timestamps
Open

fix(byoo-otel-collector): set honor_timestamps false on federated scrape jobs#1530
kristinapathak wants to merge 1 commit into
mainfrom
fix/byoo-federate-honor-timestamps

Conversation

@kristinapathak

@kristinapathak kristinapathak commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Why

The BYOO collector scrapes an in-cluster Prometheus through /federate. That
Prometheus commonly runs several replicas behind a single service, and we do not
control how it is deployed.

When it does, four things combine:

  • The collector's scrape resolves to one replica per scrape, round-robin across
    the service endpoints.
  • Each replica keeps its own scrape clock, so the same series has slightly
    different timestamps on each replica.
  • /federate returns explicit timestamps, and the collector honors them by
    default (honor_timestamps defaults to true).
  • The rendered scrape configs apply a labelkeep that strips
    prometheus_replica, so nothing downstream distinguishes the two sources.

Consecutive samples of one series can therefore carry timestamps that move
backwards. A Prometheus-compatible receiver treats that as a conflict
(out-of-order, duplicate-for-timestamp, or out-of-bounds) and rejects the entire
write request rather than the offending series, so unrelated metrics batched
with it are dropped too.

honor_timestamps: false makes the collector stamp federated samples with its
own scrape time. Its clock is monotonic, so this neutralizes all three conflict
classes for the federated path regardless of how the upstream Prometheus is
deployed. The tradeoff is up to one scrape interval (30s) of timestamp
imprecision, already accepted in this codebase for the kubernetes-cadvisor
job.

What changed

  • honor_timestamps: false on every federated scrape job that lacked it, in the
    k8s templates of both renderers:
    • current: src/compute-plane-services/byoo-otel-collector/internal/otelconfig/source_templates/src-config-k8s-{container,helm}.yaml.tmpl,
      with generator/gen/ and internal/otelconfig/templates/ regenerated via
      make update-config-template
    • legacy: src/libraries/go/lib/pkg/otelconfig/backendconfig/templates/config-k8s-{container,helm}.yaml.tmpl
  • Scope is wider than kube-state-metrics and nvidia-dcgm-exporter. The
    current renderer's k8s templates also federate nvcf-worker and nvca, and
    those jobs were missing the setting too. They hit the same service and are
    affected identically, so they are included. kubernetes-cadvisor already had
    it. Four jobs per template in the current renderer, two per template in the
    legacy one, which has no nvcf-worker or nvca job.
  • New test in each package asserting the invariant directly: every scrape job
    whose metrics_path is /federate must set honor_timestamps: false. The
    test is written against the rendered config, not the template text, and also
    asserts the vm templates produce no federated jobs, which pins the scoping
    decision below.
  • Regenerated committed example configs: 40 in byoo-otel-collector/examples/
    plus the metric-subset golden, and 36 in go-lib/examples/. Every diff is
    exactly the added honor_timestamps lines; no vm example changed.
  • tools/byoo: added the missing go-lib requirement so the go-lib example
    generator builds. It was replaced but never required.

The opentelemetry-collector self-scrape job is untouched.

Why the vm templates are excluded

The vm templates do not federate. They scrape nvidia-dcgm-exporter,
kube-state-metrics and nvcf-worker at /metrics, and the kubelet cadvisor
endpoint through a __metrics_path__ relabel. Direct scrape targets expose no
explicit timestamps, so honor_timestamps has nothing to override and setting
it is a no-op. Verified by reading all four vm templates in both renderers: no
/federate path appears in any of them. The new tests assert this holds.

Customer Release Notes

Platform metrics federated from the in-cluster Prometheus are now timestamped at
collection time by the BYOO collector rather than carrying the upstream scrape
timestamp. This makes ingest resilient to clock differences between upstream
Prometheus replicas, at the cost of up to one scrape interval (30s) of timestamp
imprecision.

Plan Summary

Not applicable.

Usage

Not applicable.

Testing

  • byoo-otel-collector: GOWORK=off go test ./... passes.
  • go-lib: GOWORK=off GOFLAGS=-mod=vendor go test ./pkg/otelconfig/... passes.
  • Both new tests were confirmed red before the template change and green after.
    Red output named exactly the jobs missing the setting: nvcf-worker, nvca,
    kube-state-metrics, nvidia-dcgm-exporter in the current renderer, and
    kube-state-metrics, nvidia-dcgm-exporter in the legacy one.
  • Every regenerated artifact was diffed against the committed file before being
    overwritten. Across all 77 regenerated examples the only changed line in the
    whole diff is + honor_timestamps: false. The commit is 431
    insertions and 0 deletions.
  • gofmt and go vet clean on both changed test files.

Pre-existing failures unrelated to this change: TestRun and
TestRun_sidecar_deployments in src/libraries/go/lib/cmd/icms-translate, and
make check-testdata failing on BSD sed.

Notes

This is not confirmed to be the cause of any specific ingest failure. The
receive-side logs that would name the conflicting series are not available to
us. The change is justified on its own merits: it makes the federated path
immune to upstream replica clock skew, which we cannot control.

Regenerating the go-lib examples surfaced an environment dependency worth
flagging. render.go emits ca_file only when the file exists on disk at the
secrets path, so a naive regeneration on a host without it silently drops that
line from four kratos_thanos_stg examples. The regeneration here supplied the
fixture so the committed files stay byte-accurate, but the generator is not
hermetic and a future contributor will hit this.

The four *_validator.yaml examples under byoo-otel-collector/examples/ are
stale: their input testdata/validator.json no longer exists, so
make update-examples does not regenerate them and they still reflect an older
template shape. Left alone as out of scope.

References

Closes #1529

Related Pull Requests

Dependencies

No new third-party packages. The tools/byoo go.mod / go.sum change adds a
requirement on the in-repo go-lib module, which was already wired in via a
replace directive. This overlaps with the same fix in #1527; whichever merges
second will need the overlap resolved.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Prometheus metrics collected from Kubernetes workloads now use collector-assigned timestamps consistently.
    • Updated monitoring configurations across container and Helm deployments, including worker, node, Kubernetes, state-metrics, and GPU exporter metrics.
    • Standardized timestamp handling across supported Kubernetes observability configurations to improve metric consistency and prevent source timestamp discrepancies.

…ape jobs

The collector federates from an in-cluster Prometheus that may run several
replicas behind a single service. Each replica keeps its own scrape clock, and
the rendered labelkeep strips prometheus_replica, so consecutive samples of one
series can carry timestamps that move backwards. A Prometheus-compatible
receiver rejects the entire write request in that case, dropping unrelated
metrics batched with it.

Setting honor_timestamps: false makes the collector stamp federated samples with
its own monotonic scrape time, which neutralizes out-of-order,
duplicate-for-timestamp, and out-of-bounds for the federated path regardless of
how the upstream Prometheus is deployed. The tradeoff is up to one scrape
interval (30s) of timestamp imprecision, already accepted for the
kubernetes-cadvisor job.

Applied to every federated job that lacked it in the k8s templates of both
renderers. The vm templates scrape their targets directly, and direct scrape
targets expose no explicit timestamps, so they are unchanged.

Also adds the missing go-lib requirement to tools/byoo so the go-lib example
generator builds. It was replace'd but never require'd.

Closes #1529

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Kristina Pathak <kpathak@nvidia.com>
@kristinapathak
kristinapathak requested review from a team as code owners September 3, 2026 19:27
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e38c84b8-9f44-484e-92b0-0f41861fba20

📥 Commits

Reviewing files that changed from the base of the PR and between 2402108 and 1b5b423.

⛔ Files ignored due to path filters (3)
  • src/compute-plane-services/byoo-otel-collector/generator/gen/generated_src-config-k8s-container.yaml.tmpl is excluded by !**/gen/**
  • src/compute-plane-services/byoo-otel-collector/generator/gen/generated_src-config-k8s-helm.yaml.tmpl is excluded by !**/gen/**
  • tools/byoo/go.sum is excluded by !**/*.sum
📒 Files selected for processing (86)
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_azure_monitor.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_input1.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_input2.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_input3.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_input4.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_kratos_logs_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_kratos_thanos_prd.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_metric_subset.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_otelcollector_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_container_telemetry_endpoint_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_azure_monitor.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_input1.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_input2.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_input3.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_input4.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_kratos_logs_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_kratos_thanos_prd.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_otelcollector_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_function_helm_telemetry_endpoint_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_azure_monitor.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_input1.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_input2.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_input3.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_input4.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_kratos_logs_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_kratos_thanos_prd.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_otelcollector_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_container_telemetry_endpoint_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_azure_monitor.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_input1.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_input2.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_input3.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_input4.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_kratos_logs_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_kratos_thanos_prd.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_otelcollector_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/config_task_helm_telemetry_endpoint_kratos_thanos_stg.yaml
  • src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render_test.go
  • src/compute-plane-services/byoo-otel-collector/internal/otelconfig/source_templates/src-config-k8s-container.yaml.tmpl
  • src/compute-plane-services/byoo-otel-collector/internal/otelconfig/source_templates/src-config-k8s-helm.yaml.tmpl
  • src/compute-plane-services/byoo-otel-collector/internal/otelconfig/templates/config-k8s-container.yaml.tmpl
  • src/compute-plane-services/byoo-otel-collector/internal/otelconfig/templates/config-k8s-helm.yaml.tmpl
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_azure_monitor.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_input1.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_input2.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_input3.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_input4.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_kratos_logs_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_kratos_thanos_prd.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_kratos_thanos_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_container_validator.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_azure_monitor.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_input1.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_input2.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_input3.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_input4.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_kratos_logs_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_kratos_thanos_prd.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_kratos_thanos_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_function_helm_validator.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_azure_monitor.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_input1.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_input2.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_input3.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_input4.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_kratos_logs_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_kratos_thanos_prd.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_kratos_thanos_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_container_validator.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_azure_monitor.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_input1.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_input2.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_input3.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_input4.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_kratos_logs_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_kratos_thanos_prd.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_kratos_thanos_stg.yaml
  • src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/config_task_helm_validator.yaml
  • src/libraries/go/lib/pkg/otelconfig/backendconfig/templates/config-k8s-container.yaml.tmpl
  • src/libraries/go/lib/pkg/otelconfig/backendconfig/templates/config-k8s-helm.yaml.tmpl
  • src/libraries/go/lib/pkg/otelconfig/config/render_test.go
  • tools/byoo/go.mod

Included review availability: Your plan provides up to 12 included reviews per hour; 10 remain after this review.


📝 Walkthrough

Walkthrough

The change sets honor_timestamps: false on federated Kubernetes Prometheus scrape jobs across current and legacy OpenTelemetry templates and example configurations. Render tests cover Kubernetes federation and confirm that VM templates do not emit federated jobs.

Changes

Federated scrape configuration

Layer / File(s) Summary
Compute-plane templates and examples
src/compute-plane-services/byoo-otel-collector/internal/otelconfig/**/*.tmpl, src/compute-plane-services/byoo-otel-collector/examples/otelconfigs/k8s/*
Federated jobs for nvcf-worker, nvca, kube-state-metrics, kubernetes-cadvisor, and nvidia-dcgm-exporter set honor_timestamps: false.
Shared library templates and examples
src/libraries/go/lib/pkg/otelconfig/**/*.tmpl, src/libraries/go/lib/examples/otelconfig/byoo-otel-collector/k8s/*
Shared Kubernetes configurations apply the same timestamp setting to federated scrape jobs.
Render validation and module linkage
src/compute-plane-services/byoo-otel-collector/internal/otelconfig/render_test.go, src/libraries/go/lib/pkg/otelconfig/config/render_test.go, tools/byoo/go.mod
Render tests validate the setting for Kubernetes federation and the absence of federation in VM templates. The tools module adds the shared library dependency.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 1b5b4

Kubernetes federated scrapes now assign collection-time timestamps, preventing replica clock skew from causing rejected metric writes while retaining the accepted scrape-interval timestamp imprecision. Current templates, generated examples, and render coverage align with this behavior, with no remaining merge-blocking risk.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 2 files. (84 skipped: … 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 uses the required Conventional Commits format, includes the required scope for a fix, and accurately describes the federated scrape timestamp change.
Linked Issues check ✅ Passed The changes satisfy issue #1529 by setting honor_timestamps: false on federated Kubernetes scrape jobs in both current and legacy renderer templates. Rendered configuration tests verify the invariant,…
Out of Scope Changes check ✅ Passed All changes support the linked issue: renderer templates, generated configuration examples, rendered-config tests, and the dependency required for example generation. No unrelated code changes are evi…
Full details: Linked Issues check

Explanation

The changes satisfy issue #1529 by setting honor_timestamps: false on federated Kubernetes scrape jobs in both current and legacy renderer templates. Rendered configuration tests verify the invariant, VM templates remain unchanged, examples are regenerated, and the required go-lib dependency is added.

Full details: Out of Scope Changes check

Explanation

All changes support the linked issue: renderer templates, generated configuration examples, rendered-config tests, and the dependency required for example generation. No unrelated code changes are evident.

Full details: Docstring Coverage

Explanation

Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 2 files. (84 skipped: 84 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/byoo-federate-honor-timestamps

Warning

Some tools did not complete. Review the errors below.

🔧 golangci-lint (2.13.2)

level=error msg="Running error: context loading failed: failed to load packages: failed to load packages: failed to load with go/packages: err: exit status 1: stderr: go: -mod may only be set to readonly or vendor when in workspace mode, but it is set to "mod"\n\tRemove the -mod flag to use the default readonly value, \n\tor set GOWORK=off to disable workspace mode.\n"


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

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.

fix(byoo-otel-collector): set honor_timestamps false on federated scrape jobs

1 participant