Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compute-plane-services/byoo-otel-collector/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.157.0
0.158.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

root="src/compute-plane-services/byoo-otel-collector"
rg -n --hidden --glob '!**/.git/**' \
  '0\.157\.0|0\.158\.0|collector.*version|VERSION' "$root"

Repository: NVIDIA/nvcf

Length of output: 50368


🏁 Script executed:

#!/bin/bash
set -euo pipefail

root="src/compute-plane-services/byoo-otel-collector"

printf '\n== VERSION ==\n'
cat -n "$root/VERSION"

printf '\n== otel-collector-build.yaml version lines ==\n'
rg -n '0\.157\.0|0\.158\.0|major_minor|version' "$root/otel-collector-build.yaml" "$root/AGENTS.md" "$root/scripts/update-collector-version.sh" | sed -n '1,120p'

printf '\n== relevant release wiring ==\n'
sed -n '50,60p' "$root/AGENTS.md"
sed -n '1,40p' "$root/otel-collector-build.yaml"

Repository: NVIDIA/nvcf

Length of output: 14758


Align VERSION with the collector config

src/compute-plane-services/byoo-otel-collector/VERSION is 0.158.0, but src/compute-plane-services/byoo-otel-collector/otel-collector-build.yaml still pins v0.157.0 throughout. This drifts the release version from the collector major/minor and will produce inconsistent release metadata.

🤖 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/byoo-otel-collector/VERSION` at line 1, Update the
VERSION value for the byoo-otel-collector to match the collector configuration’s
pinned v0.157.0 release, ensuring the VERSION file and otel-collector-build.yaml
use consistent release metadata.

Source: Coding guidelines

67 changes: 67 additions & 0 deletions src/compute-plane-services/byoo-otel-collector/perf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# BYOO Collector Performance Test Suite

A repeatable performance test suite for the BYOO OpenTelemetry collector. It
exercises the collector under controlled telemetry load using the same workload
shape produced in production, by rendering through the shared translation
library (`icms-translate`) rather than hand-written collector manifests.

> Status: first milestone. Only rendering and render-shape validation are
> implemented today. Deployment, load generation, the OTLP sink, measurements,
> and reporting land in later milestones.

## Why translation-driven

The collector spec and config are generated by calling
`function.Translate(msg, tcfg)` from the shared translation library, so the
suite tests the identical collector spec and config that would be deployed:

- Container functions get the collector as a workload sidecar.
- Helm functions get the collector on the generated utils pod, fronted by a
ClusterIP OTLP Service.

The suite extracts the authentic collector container and, for deployment, runs
it with lightweight stand-ins for the non-collector containers, which are not
what the suite measures.

## Layout

- `cmd/perf` — CLI entrypoint (`render`, `run`, `cleanup`).
- `pkg/spec` — synthetic container/Helm launch specs and translate config.
- `pkg/render` — runs `function.Translate` and extracts the collector.
- `pkg/validate` — render-shape validation gate.
- `pkg/profile` — `dev` and `baseline` execution profiles.

This is a standalone Go module. Run its Go commands with `GOWORK=off`:

```bash
GOWORK=off go build ./...
GOWORK=off go test ./...
```

## Usage

```bash
# Render and validate both shapes (no cluster required).
GOWORK=off go run ./cmd/perf render --shape both

# Render one shape and print the deployable workload as YAML.
GOWORK=off go run ./cmd/perf render --shape container --output yaml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Will this run it using kubectl against a cluster?

```

### `render` flags

- `--shape` (`both`): `container`, `helm`, or `both`.
- `--profile` (`dev`): `dev` or `baseline`.
- `--collector-image`: BYOO collector image reference.
- `--namespace` (`byoo-perf`): namespace for rendered objects.
- `--output` (`summary`): `summary`, `yaml`, or `json`.

`run` and `cleanup` are scaffolded and return a clear "not implemented" message.

## Execution profiles

- `dev`: short run (10s warmup, 30s window, 1 repetition) for wiring and local
iteration.
- `baseline`: longer, repeatable run (60s warmup, 5m window, 3 repetitions).

All profile values are documented defaults and will be overridable per run.
207 changes: 207 additions & 0 deletions src/compute-plane-services/byoo-otel-collector/perf/cmd/perf/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Command perf is the entrypoint for the BYOO collector performance test
// suite. In this first milestone only "render" is fully wired; "run" and
// "cleanup" are scaffolding for the deployment/load milestones (S4+).
package main

import (
"flag"

@mikeyrcamp mikeyrcamp Jul 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This CLI is fairly comprehensive with many of sub-commands. I would recommend using cobra as we were are with other CLIs

"fmt"
"os"
"strings"

"sigs.k8s.io/yaml"

"github.com/NVIDIA/nvcf/src/libraries/go/lib/pkg/icms-translate/translate/common"

"github.com/NVIDIA/nvcf/src/compute-plane-services/byoo-otel-collector/perf/pkg/profile"
"github.com/NVIDIA/nvcf/src/compute-plane-services/byoo-otel-collector/perf/pkg/render"
"github.com/NVIDIA/nvcf/src/compute-plane-services/byoo-otel-collector/perf/pkg/spec"
"github.com/NVIDIA/nvcf/src/compute-plane-services/byoo-otel-collector/perf/pkg/validate"
)

func main() {
if len(os.Args) < 2 {
usage()
os.Exit(2)
}

var err error
switch os.Args[1] {
case "render":
err = cmdRender(os.Args[2:])
case "run":
err = cmdRun(os.Args[2:])
case "cleanup":
err = cmdCleanup(os.Args[2:])
case "-h", "--help", "help":
usage()
return
default:
fmt.Fprintf(os.Stderr, "unknown command %q\n\n", os.Args[1])
usage()
os.Exit(2)
}

if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}

func usage() {
fmt.Fprint(os.Stderr, `perf - BYOO OpenTelemetry collector performance test suite

Usage:
perf <command> [flags]

Commands:
render Render the production workload shape via icms-translate and validate it (no cluster required).
run Deploy, drive load, and measure (not yet implemented; see S4+).
cleanup Remove test resources (not yet implemented; see S5+).

Run "perf <command> -h" for command flags.
`)
}

func cmdRender(args []string) error {
fs := flag.NewFlagSet("render", flag.ContinueOnError)
shapeFlag := fs.String("shape", "both", `deployment shape: "container", "helm", or "both"`)
profileFlag := fs.String("profile", "dev", `execution profile: "dev" or "baseline"`)
collectorImage := fs.String("collector-image", spec.DefaultCollectorImage, "BYOO collector image reference")
namespace := fs.String("namespace", "byoo-perf", "namespace for rendered objects")
output := fs.String("output", "summary", `output format: "summary", "yaml", or "json"`)
if err := fs.Parse(args); err != nil {
return err
}

prof, err := profile.Lookup(*profileFlag)
if err != nil {
return err
}
shapes, err := shapesFromFlag(*shapeFlag)
if err != nil {
return err
}

opts := spec.DefaultOptions()
opts.Namespace = *namespace
opts.CollectorImage = *collectorImage

exp := validate.Expectations{
Image: opts.CollectorImage,
Resources: common.GetDefaultContainerResourcesBYOO(),
}

fmt.Printf("profile=%s warmup=%s window=%s reps=%d\n\n", prof.Name, prof.Warmup, prof.MeasurementWindow, prof.Repetitions)

for _, shape := range shapes {
res, err := render.Render(shape, opts)
if err != nil {
return fmt.Errorf("render %s: %w", shape, err)
}
if err := validate.Render(res, exp); err != nil {
return err
}

switch *output {
case "summary":
printSummary(res)
case "yaml", "json":
if err := printObjects(res, *namespace, *output); err != nil {
return err
}
default:
return fmt.Errorf("unknown output %q (want \"summary\", \"yaml\", or \"json\")", *output)
}
}
return nil
}

func printSummary(res *render.Result) {
fmt.Printf("[%s] VALID\n", res.Shape)
fmt.Printf(" collector image : %s\n", res.Collector.Image)
fmt.Printf(" config version : %s\n", res.OTelVersion)
fmt.Printf(" owner pod : %s\n", res.OwnerPod)
if res.Service != nil {
fmt.Printf(" otlp service : %s\n", res.Service.Name)
}
fmt.Printf(" ports : %s\n", portSummary(res))
fmt.Printf(" objects : %d translated\n\n", len(res.Objects))
}

func portSummary(res *render.Result) string {
parts := make([]string, 0, len(res.Collector.Ports))
for _, p := range res.Collector.Ports {
parts = append(parts, fmt.Sprintf("%s:%d", p.Name, p.ContainerPort))
}
return strings.Join(parts, " ")
}

func printObjects(res *render.Result, namespace, format string) error {
pod := res.BenchPod(namespace)
out, err := yaml.Marshal(pod)
if err != nil {
return fmt.Errorf("marshal bench pod: %w", err)
}
if format == "json" {
out, err = yaml.YAMLToJSON(out)
if err != nil {
return fmt.Errorf("convert to json: %w", err)
}
}
fmt.Printf("# shape=%s benchmark workload (authentic collector + emptyDir stand-ins)\n", res.Shape)
fmt.Printf("%s\n", out)
return nil
}

func cmdRun(args []string) error {
fs := flag.NewFlagSet("run", flag.ContinueOnError)
_ = fs.String("shape", "both", `deployment shape: "container", "helm", or "both"`)
_ = fs.String("profile", "dev", `execution profile: "dev" or "baseline"`)
_ = fs.String("mode", "k3d", `deployment mode: "k3d" or "remote"`)
_ = fs.Bool("retain", false, "retain test resources for debugging instead of cleaning up")
if err := fs.Parse(args); err != nil {
return err
}
return fmt.Errorf("`run` is not implemented yet; it lands with the deployment/load milestones (S4-S9)")
}

func cmdCleanup(args []string) error {
fs := flag.NewFlagSet("cleanup", flag.ContinueOnError)
_ = fs.String("mode", "k3d", `deployment mode: "k3d" or "remote"`)
_ = fs.String("namespace", "byoo-perf", "namespace to clean up")
if err := fs.Parse(args); err != nil {
return err
}
return fmt.Errorf("`cleanup` is not implemented yet; it lands with the deployment milestone (S5)")
}

func shapesFromFlag(s string) ([]spec.Shape, error) {
switch s {
case "container":
return []spec.Shape{spec.ShapeContainer}, nil
case "helm":
return []spec.Shape{spec.ShapeHelm}, nil
case "both":
return []spec.Shape{spec.ShapeContainer, spec.ShapeHelm}, nil
default:
return nil, fmt.Errorf("unknown shape %q (want \"container\", \"helm\", or \"both\")", s)
}
}
50 changes: 50 additions & 0 deletions src/compute-plane-services/byoo-otel-collector/perf/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module github.com/NVIDIA/nvcf/src/compute-plane-services/byoo-otel-collector/perf

go 1.25.0

require (
github.com/NVIDIA/nvcf/src/libraries/go/lib v0.0.0
k8s.io/api v0.34.2
k8s.io/apimachinery v0.34.2
sigs.k8s.io/yaml v1.6.0
)

require (
dario.cat/mergo v1.0.2 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/google/go-containerregistry v0.21.5 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
golang.org/x/net v0.55.0 // indirect
golang.org/x/text v0.37.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)

// The perf suite consumes the shared SIS translation library directly so that
// it renders exactly the workload shape NVCA produces in production.
replace github.com/NVIDIA/nvcf/src/libraries/go/lib => ../../../libraries/go/lib

// Mirror the k8s pins used by the shared library. replace directives in
// dependencies are not inherited, so we repeat them here for the main module.
replace (
k8s.io/api => k8s.io/api v0.34.2
k8s.io/apimachinery => k8s.io/apimachinery v0.34.2
k8s.io/client-go => k8s.io/client-go v0.34.2
)
Loading
Loading