Repository navigation
feat: add the redisvl[otel] observability foundation (FDE-86) - #755
Open
vishal-bala wants to merge 4 commits into
Open
vishal-bala wants to merge 4 commits into
vishal-bala wants to merge 4 commits into
Conversation
vishal-bala
marked this pull request as ready for review
October 14, 2026 08:09
limjoobin
approved these changes
Oct 30, 2026
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
force-pushed
the
feat/FDE-83-otel/02-FDE-86-foundation
branch
from
November 2, 2026 09:10
9e67dc6 to
2a92921
Compare
…feat/FDE-83-otel/02-FDE-86-foundation # Conflicts: # uv.lock
…feat/FDE-83-otel/02-FDE-86-foundation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
SemanticCacheis 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 andredisvl.utils.otelThe
otelextra depends onopentelemetry-api>=1.30.0, the first release that accepts the histogram bucket advice the cache metrics will set. The internalredisvl.utils.otelmodule returns a tracer and a meter from the global providers, under theredisvlinstrumentation 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_DISABLEDistrue, 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-testdependency group, so a plainuv syncstays free of OpenTelemetry and the existing import check keeps running without optional dependencies. A sharedotel_sdkfixture 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 installand the test matrix sync theotel-testgroup.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
SemanticCacheoperation-duration and match-distance histograms.Reviewer Brief
Start here:
redisvl/utils/otel.py,get_tracer()andget_meter(). Every later instrumentation call goes through them, and they return the stand-ins when the API isn't installed orREDISVL_OTEL_DISABLEDistrue.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. Thetest-without-oteljob 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 theotel_sdkfixture, which resets the API's private globals and would break if a future release renames them..github/workflows/test.yml:189: theimport opentelemetryguard 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.0floor, which was bisected when this PR was written and not re-run here; the tests ran on 1.42.1.Since the last brief:
77623f1band81d49791mergemainup to506b961b(Python 3.15 support);uv.lockismain's lock plus this PR's OpenTelemetry entries, unchanged byuv lockunder uv 0.12.3 and 0.13.1. This PR's own diff is unchanged.Reviewed
536991a6, fixes in9e67dc66· Claude Code (claude-opus-5-5) · lenses: correctness, security, design, tests, docs, Redis behaviourNote
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 internalredisvl.utils.otel, which exposes cachedget_tracer()/get_meter()under theredisvlinstrumentation scope, shared metric/attribute name constants, and no-op stand-ins when the API is missing orREDISVL_OTEL_DISABLED=true—so future instrumentation does not branch on installs.Testing and CI: an
otel-testuv group pulls in the SDK only where tests need it;make install, CONTRIBUTING, and the main matrix useuv sync --all-extras --group otel-test. A newtest-without-oteljob syncs extras without mistralai/mcp (transitive OTel), assertsimport opentelemetryfails, and runs the suite minus MCP tests.otel_sdkfixture plustests/unit/test_otel.pycover 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.