Skip to content

feat: add OTel observability benchmark demo - #13

Open
Ladas wants to merge 1 commit into
praxis-proxy:mainfrom
Ladas:feat/otel-benchmark-demo
Open

feat: add OTel observability benchmark demo#13
Ladas wants to merge 1 commit into
praxis-proxy:mainfrom
Ladas:feat/otel-benchmark-demo

Conversation

@Ladas

@Ladas Ladas commented Aug 25, 2026

Copy link
Copy Markdown

Summary

  • Full observability stack on KIND for benchmarking the Praxis
    experimental AI gateway's OTel tracing overhead
  • AI scenario: 500 RPS, 22 spans/request (extended AI filter chain
    with intelligent_route, token_count, time_to_first_token,
    model_to_header)
  • Core scenario: 2000 RPS, 10 spans/request
  • Each runs baseline/otel-noop/otel-full configurations with vegeta
  • 5 Grafana dashboards, Tempo traces, Loki logs, Prometheus metrics
  • Adds otel feature to praxis-experimental-server
    (praxis-core/otel + praxis-filter/otel + praxis-ai-proxy/opentelemetry)
  • FEATURES build-arg in Containerfile for opt-in OTel builds

Dependencies

Demo structure

demos/otel-benchmark/
├── forge.yaml          # Forge environment config
├── README.md           # AI gateway benchmark (step-by-step)
├── README-core.md      # Core proxy benchmark
├── configs/            # 4 praxis proxy configs (baseline/full × core/AI)
├── manifests/          # Praxis deployment + ServiceMonitor
├── scripts/            # Parameterized benchmark.sh + report.sh
└── stacks/             # Mock backends + observability (collector, dashboards)

Test plan

  • praxis-forge doctor passes
  • praxis-forge up --config forge.yaml creates KIND cluster
  • All 9 stacks deploy successfully
  • Traces visible in Tempo via Grafana (22 spans per AI request)
  • Dashboards show real data after traffic
  • Benchmark scripts complete with valid reports
  • skip/pr-conventions label needed (1436 lines — demo with
    JSON dashboards and configs, not splittable)

Known limitations

  • [patch.crates-io] pins praxis crates to main rev 1b439271 for
    the Tokio runtime fix and filter/otel feature not yet in v0.5.3.
    Remove once praxis publishes v0.5.4+.

@github-actions

Copy link
Copy Markdown

Unsigned commits: 74990af. Please sign your commits.

@github-actions

Copy link
Copy Markdown

PR too large: 1500 lines added (limit: 750, excludes Cargo files, tests, docs, examples, and benchmarks). Please split into smaller PRs. Add skip/pr-conventions label to override.

@Ladas
Ladas marked this pull request as draft August 25, 2026 18:32
@Ladas
Ladas force-pushed the feat/otel-benchmark-demo branch from 74990af to 476fc27 Compare August 26, 2026 09:58

@praxis-bot praxis-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

4 findings (1 Large, 3 Medium)

Overall: well-structured demo with good reproducibility design -- pinned chart versions, configurable benchmark parameters, multiple runs with warmup. The OTel collector pipeline, Tempo integration, and benchmark methodology are sound. The three-way comparison (baseline / noop / full) is the right approach for isolating overhead. A few issues to address.

Comment thread demos/otel-benchmark/Containerfile.ai-otel Outdated
Comment thread demos/otel-benchmark/scripts/report.sh Outdated
f.write(f"**Platform:** KIND (1 node) | **Backend:** Fortio echo\n\n")
f.write(f"## Summary\n\n")
f.write(f"| Config | P50 (us) | P99 (us) | RPS | Runs | P50 delta | P99 delta |\n")
f.write(f"|--------|----------|----------|-----|------|-----------|-----------||\n")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Medium] Trailing || on separator lines creates a ghost 8th column, breaking Markdown table rendering. This line has 7 header columns but 8 separator segments. The same issue appears on line 96 (the "Previous Results" table).

Fix both separator lines by removing the trailing extra |:

f.write(f"|--------|----------|----------|-----|------|-----------|-----------|\n")

and line 96:

f.write(f"|--------|----------|----------|-----|-----------|-----------|\n")

Comment thread demos/otel-benchmark/forge.yaml Outdated

CLUSTER_NAME="${CLUSTER_NAME:-otel-bench-local}"
CTX="kind-${CLUSTER_NAME}"
GATEWAY_URL="http://localhost:18080"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Medium] Neither benchmark.sh nor benchmark-ai.sh validate that vegeta is installed before starting. With set -euo pipefail, the first vegeta command will fail, but only after the script has already modified the Kubernetes deployment (created configmap, changed image, scaled pods). This leaves the cluster in a partially modified state.

Add a prerequisite check near the top of both scripts:

for cmd in vegeta kubectl; do
  command -v "$cmd" >/dev/null 2>&1 || { echo "Error: $cmd not found"; exit 1; }
done

@Ladas
Ladas force-pushed the feat/otel-benchmark-demo branch 7 times, most recently from 76b9126 to 6988b33 Compare August 28, 2026 08:25
@Ladas
Ladas force-pushed the feat/otel-benchmark-demo branch from 6988b33 to b232cf7 Compare August 31, 2026 16:56

@praxis-bot praxis-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

PR Review (re-review)

Summary: Previous findings addressed -- ARG FEATURES replaces the fragile sed approach, vegeta prerequisite check added, report table formatting fixed. One new issue found.

Severity Count
Critical 0
Large 0
Medium 1

RESULTS_PREFIX=""
TARGET_FN=core_target
SCENARIO_TITLE=""
REPORT_SCRIPT="report.sh"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Medium] REPORT_SCRIPT is set to "report-ai.sh" for the AI scenario, but that file does not exist -- the only report script is report.sh (which auto-detects the scenario via the results directory contents). After running bash scripts/benchmark.sh --scenario ai, line 154 prints an instruction to run a nonexistent script.

Change to:

REPORT_SCRIPT="report.sh"

@Ladas
Ladas marked this pull request as ready for review September 1, 2026 13:23
@Ladas
Ladas force-pushed the feat/otel-benchmark-demo branch from b232cf7 to cf132ab Compare September 1, 2026 13:25
Full observability stack on KIND for benchmarking Praxis experimental
server OTel tracing overhead across two scenarios:

- AI gateway (500 RPS, 22 spans/request, POST /v1/chat/completions)
- Core proxy (2000 RPS, 10 spans/request, GET to echo backend)

AI scenario uses extended filter chain: request_id, access_log,
model_to_header, token_usage_headers, token_count, time_to_first_token,
intelligent_route, and load_balancer — demonstrating the full AI
gateway pipeline in the trace waterfall.

Each scenario runs baseline/otel-noop/otel-full configurations with
vegeta load testing via a single parameterized benchmark.sh script.

Stack: Prometheus, Grafana 11.x, Tempo, Loki, OTel Collector,
MLflow (file-backed SQLite), Fortio echo, llm-d inference-sim,
plus 5 Grafana dashboards.

Also adds:
- otel feature to praxis-experimental-server (praxis-core/otel +
  praxis-filter/otel + praxis-ai-proxy/opentelemetry)
- FEATURES build-arg in Containerfile
- Patches praxis crates to main rev 1b439271 for Tokio runtime fix
  and filter/otel feature not yet in v0.5.3

Signed-off-by: Ladislav Smola <lsmola@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip/pr-conventions Skip conventions checks for PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants