Skip to content

feat: add the redisvl[otel] observability foundation (FDE-86) - #755

Open
vishal-bala wants to merge 4 commits into
mainfrom
feat/FDE-83-otel/02-FDE-86-foundation
Open

vishal-bala wants to merge 4 commits into
mainfrom
feat/FDE-83-otel/02-FDE-86-foundation

Conversation

@vishal-bala

@vishal-bala vishal-bala commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

SemanticCache is gaining OpenTelemetry metrics and spans, so that applications can see hit rates, match distances against the threshold, and where a lookup spends its time. This change adds the plumbing that instrumentation builds on, following OpenTelemetry's guidance for libraries: depend on the API only, leave the SDK and exporters to the application, and cost next to nothing when no SDK is configured. It emits no telemetry itself.

Changes

The redisvl[otel] extra and redisvl.utils.otel

The otel extra depends on opentelemetry-api>=1.30.0, the first release that accepts the histogram bucket advice the cache metrics will set. The internal redisvl.utils.otel module returns a tracer and a meter from the global providers, under the redisvl instrumentation scope with RedisVL's version and the semantic-conventions 1.44.0 schema URL. With no SDK configured they are the API's own no-ops, at about 2 µs for one span and two histogram records on an Apple M4 Pro.

When the API is not installed, or REDISVL_OTEL_DISABLED is true, the module returns stand-ins with the same interface, so instrumented code never branches. The metric and attribute names the instrumentation will use are defined in the same module. RedisVL never constructs a provider and never initialises redis-py's own observability; both belong to the application.

Tests and CI

The SDK the tests need sits in a non-default otel-test dependency group, so a plain uv sync stays free of OpenTelemetry and the existing import check keeps running without optional dependencies. A shared otel_sdk fixture configures in-memory exporters and resets the set-once global providers on teardown. Three tests cover the instrumentation scope with an SDK, the off switch with an SDK configured, and the path with no SDK in a fresh interpreter: the global providers stay the API's proxies, redis-py's observability is not initialised, and the per-call cost is bounded.

A new CI leg runs the default suite without OpenTelemetry. Every other leg has it, because mistralai brings in the SDK and fastmcp the API, so the leg installs every extra except those two and skips the MCP tests, which need fastmcp.

Minor

  • make install and the test matrix sync the otel-test group.

Notes

This PR sits in a stack on top of the KNN lookup change. On its own it adds an extra that emits nothing, so it should merge together with the instrumentation above it rather than alone.

Next Steps

  1. Record SemanticCache operation-duration and match-distance histograms.
  2. Emit spans for cache operations and embeddings.
  3. Document the feature, with an example and a starter dashboard.

Reviewer Brief

Start here: redisvl/utils/otel.py, get_tracer() and get_meter(). Every later instrumentation call goes through them, and they return the stand-ins when the API isn't installed or REDISVL_OTEL_DISABLED is true.

Where it could fail

  • otel.py:79-117 (the _NoOp* stand-ins): they must accept every argument the instrumentation above passes, or code fails only on installs without OpenTelemetry. The test-without-otel job is the guard for that.
  • otel.py:129-138: the getters and settings are cached for the life of the process. Tests rely on _clear_caches() and on the otel_sdk fixture, which resets the API's private globals and would break if a future release renames them.
  • .github/workflows/test.yml:189: the import opentelemetry guard keeps the job meaningful if a new extra pulls OpenTelemetry in; it must fail the job, not just warn.

Not verified: the opentelemetry-api>=1.30.0 floor, which was bisected when this PR was written and not re-run here; the tests ran on 1.42.1.

Since the last brief: 77623f1b and 81d49791 merge main up to 506b961b (Python 3.15 support); uv.lock is main's lock plus this PR's OpenTelemetry entries, unchanged by uv lock under uv 0.12.3 and 0.13.1. This PR's own diff is unchanged.

Reviewed 536991a6, fixes in 9e67dc66 · Claude Code (claude-opus-5-5) · lenses: correctness, security, design, tests, docs, Redis behaviour


Note

Low Risk
Adds an optional extra and internal helpers with no production call sites yet; CI explicitly guards the no-OpenTelemetry install path.

Overview
Adds optional OpenTelemetry support via redisvl[otel] (opentelemetry-api>=1.30.0) and internal redisvl.utils.otel, which exposes cached get_tracer() / get_meter() under the redisvl instrumentation scope, shared metric/attribute name constants, and no-op stand-ins when the API is missing or REDISVL_OTEL_DISABLED=true—so future instrumentation does not branch on installs.

Testing and CI: an otel-test uv group pulls in the SDK only where tests need it; make install, CONTRIBUTING, and the main matrix use uv sync --all-extras --group otel-test. A new test-without-otel job syncs extras without mistralai/mcp (transitive OTel), asserts import opentelemetry fails, and runs the suite minus MCP tests. otel_sdk fixture plus tests/unit/test_otel.py cover scope/version, the env off switch, and API-only no-SDK behavior (including a subprocess overhead bound).

This PR does not yet emit cache metrics or spans from product code; it only lays the dependency and helper layer for follow-up work.

Reviewed by Cursor Bugbot for commit 81d4979. Bugbot is set up for automated code reviews on this repo. Configure here.

@vishal-bala
vishal-bala added this pull request to stack #756 October 13, 2026 16:21
@vishal-bala vishal-bala added the auto:internal Changes only affect the internal API label Oct 14, 2026
@vishal-bala
vishal-bala marked this pull request as ready for review October 14, 2026 08:09
@vishal-bala vishal-bala added auto:minor Increment the minor version when merged and removed auto:internal Changes only affect the internal API labels Oct 14, 2026
@vishal-bala
vishal-bala requested a review from limjoobin October 30, 2026 08:57

@limjoobin limjoobin left a comment •

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.

LGTM, thanks! This PR adds the optional OpenTelemetry foundation for SemanticCache.

Looks like a rebase is needed for this first though!

Base automatically changed from feat/FDE-83-otel/01-FDE-85-knn-check to main November 2, 2026 09:10
Adds the plumbing RedisVL's OpenTelemetry instrumentation builds on. It
emits no telemetry of its own.

- An `otel` extra that depends on opentelemetry-api only; the
  application owns the SDK and exporters. The floor, 1.30.0, is the
  first API release that accepts histogram bucket advice.
- redisvl.utils.otel returns a tracer and meter from the global
  providers under the `redisvl` scope, RedisVL's version and the
  semantic-conventions 1.44.0 schema URL. With no SDK configured they
  are the API's own no-ops: about 2 us for one span and two histogram
  records on an Apple M4 Pro. When the API is not installed, or
  REDISVL_OTEL_DISABLED is "true", stand-ins with the same interface are
  returned, so call sites never branch. The metric and attribute names
  the instrumentation will use are defined there in one place.
- The SDK the tests need sits in a non-default `otel-test` group, so a
  plain `uv sync` stays free of OpenTelemetry. A shared `otel_sdk`
  fixture configures in-memory exporters and resets the set-once global
  providers afterwards.
- A CI leg runs the default suite without OpenTelemetry, installing
  every extra except mistralai and mcp, which pull it in.
make install and CI sync --group otel-test; CONTRIBUTING.md now does too, so the OpenTelemetry tests don't depend on another extra pulling in the SDK.
@vishal-bala
vishal-bala force-pushed the feat/FDE-83-otel/02-FDE-86-foundation branch from 9e67dc6 to 2a92921 Compare November 2, 2026 09:10
…feat/FDE-83-otel/02-FDE-86-foundation

# Conflicts:
#	uv.lock

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto:minor Increment the minor version when merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants