Skip to content

docs: add a SemanticCache telemetry notebook and starter Grafana dashboard (FDE-89) - #820

Draft
vishal-bala wants to merge 3 commits into
mainfrom
feat/FDE-83-otel/05-FDE-89-example-dashboard
Draft

vishal-bala wants to merge 3 commits into
mainfrom
feat/FDE-83-otel/05-FDE-89-example-dashboard

Conversation

@vishal-bala

@vishal-bala vishal-bala commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

The PR below adds SemanticCache traces, metrics and a reference guide. This PR makes them something a user can try in a few minutes: a notebook that shows what the telemetry says about a real cache, and a local stack with a starter Grafana dashboard for hit rate, threshold tuning and latency. It continues the work for #684.

Changes

A notebook that reads the cache's telemetry back

docs/user_guide/15_semantic_cache_observability.ipynb builds a five-entry FAQ cache over redis/langcache-embed-v2 and sends it 11 lookups: rewordings of stored questions, different questions that sit close to a stored one, and unrelated questions. It then reads back what RedisVL recorded:

  • the nearest distance of every lookup, from the retrieval spans, including misses;
  • one lookup's span tree, with its timings and attributes;
  • the hit rate and the distance histogram, from an in-memory metric reader;
  • the share of misses a looser threshold would have served, and which lookups those are. Two of them are different questions, which is the point the guide makes about distances not judging correctness.

By default everything stays in memory, so notebook validation exercises real output with no API key. With OTEL_EXPORTER_OTLP_ENDPOINT set, the notebook also exports over OTLP, turns on redis-py's command metrics, and its last cell (skipped in CI) sends three minutes of lookups.

A local stack and starter dashboard

docs/user_guide/how_to_guides/observability-stack/ holds a Docker Compose stack: Redis 8.8.0, an OpenTelemetry Collector, Prometheus, Jaeger and Grafana, with every port on 127.0.0.1. Grafana opens on grafana/semantic-cache.json, which has four rows:

  • Hit rate: per cache over the range and over time, and lookups per second by result.
  • Threshold tuning: heatmaps of the nearest distance on misses and on hits, and two "what if" stats driven by Looser threshold and Tighter threshold variables.
  • Latency: operation and embedding percentiles, and redis-py's FT.SEARCH and PIPELINE latency.
  • Traces: links to the service's recent and slowest lookups in Jaeger.

The dashboard needs only a Prometheus data source, so it can be imported into another Grafana.

Guide and CI

The guide gains an "Explore with a local stack" section, and its redis-py section now names the command metric, says which commands a lookup and a store record, and notes that redis-py uses db.system where RedisVL uses db.system.name. The notebook is listed in the how-to index. The notebook CI job gets the SDK from the dev dependency group.

Notes

  • Traces are linked, not embedded. Grafana 13.2.1's Jaeger data source calls Jaeger's v1 HTTP API, which Jaeger 2.22 no longer serves, so a trace panel would show only an error. Links into Jaeger's own UI work with any version.
  • The threshold pickers list fixed values. They offer the distance bucket boundaries up to 0.5, matching redisvl/utils/otel.py, because the "what if" stats match a bucket's le label exactly. The panel descriptions say thresholds are per cache, so the stats are not split by cache.
  • The example uses a real embedding model. Its distances are what a user would see. redis/langcache-embed-v2 is already used by other notebooks, so CI's model cache holds it, and no API key is needed.

Release Notes

  • A new notebook, "Tune the Semantic Cache with Telemetry", and a local Docker Compose stack with a starter Grafana dashboard show SemanticCache's OpenTelemetry traces and metrics in use.

Reviewer Brief

Start here: docs/user_guide/15_semantic_cache_observability.ipynb, the "Configure OpenTelemetry" cell. It decides what runs in CI (in-memory only) and what feeds the stack (OTLP plus redis-py metrics), and every later cell depends on it.

Where it could fail

  • grafana/semantic-cache.json, the two "what if" stats: they match le="$looser" and le="$tighter" exactly, so a pipeline that formats bucket labels differently from the Collector's Prometheus exporter (for example 0.150) returns no data rather than an error.
  • The notebook's lookup_rows: it pairs each prompt with a semantic_cache.check span by start time, so any extra lookup added before the loop would misalign the table.
  • observability-stack/compose.yaml: the five images are pinned to exact tags, and the traces row already depends on a Grafana and Jaeger pairing; a version bump needs the dashboard rechecked.

Not verified: the notebook job in CI itself (the same nbval command ran locally); Docker on Linux; importing the dashboard into a Grafana other than 13.2.1, or behind Prometheus's own OTLP receiver, whose metric and label names differ.

Beyond CI: the notebook ran end to end over OTLP against the stack, and every dashboard panel rendered with its data in Grafana 13.2.1, with the Jaeger links opening the lookup traces; nbval passed locally (10 passed, 1 skipped); the docs build adds no warnings, and the notebook's links to guide anchors resolve.

Reviewed 1cdce2e9, fixes in ed42e048 · Claude Code (claude-opus-5-5) · lenses: correctness, security, design, tests, docs, Redis behaviour

@vishal-bala
vishal-bala added this pull request to stack #756 November 5, 2026 09:32
Base automatically changed from feat/FDE-83-otel/04-FDE-88-spans to main November 7, 2026 13:41
… dashboard

The notebook runs an FAQ cache through hits, near misses and misses and
reads its traces and metrics back from in-memory readers, so notebook
validation exercises real output without any API key. With
OTEL_EXPORTER_OTLP_ENDPOINT set, it also exports to a Docker Compose stack
(Redis, OpenTelemetry Collector, Prometheus, Jaeger, Grafana) whose
dashboard covers hit rate, threshold tuning and latency.

The notebook CI job now installs the otel-test group for the SDK. The guide
gains a section on the stack and notes on redis-py's command metrics.
…rding

Publish every stack port on 127.0.0.1 and give anonymous Grafana users the
Editor role, so the unauthenticated services are not reachable from the
network. Fix the "hites" panel title, list the OTLP exporter and the
redis-py 7.4 floor the notebook's export mode needs, and correct the
notebook's lookup groups and kernel-restart hint. The threshold and
embedding panels now say they count only misses with a candidate, are per
cache, and are not split by cache, respectively.
@vishal-bala
vishal-bala force-pushed the feat/FDE-83-otel/05-FDE-89-example-dashboard branch from 8e768dc to 3d016b0 Compare November 7, 2026 13:41

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant