feat(llama-index): add loongsuite-instrumentation-llama-index (#18) - #273
Open
RichardoMrMu wants to merge 13 commits into
Open
RichardoMrMu wants to merge 13 commits into
RichardoMrMu wants to merge 13 commits into
Conversation
…-index/CHANGELOG.md
…-index/pyproject.toml
…-index/test-requirements.txt
…-index/src/opentelemetry/instrumentation/llama_index/package.py
…-index/src/opentelemetry/instrumentation/llama_index/version.py
…-index/src/opentelemetry/instrumentation/llama_index/__init__.py
…-index/tests/conftest.py
…-index/tests/test_instrumentor.py
…-index/tests/__init__.py
…loongsuite_instrumentation_llama_index.py
github-actions
Bot
requested review from
123liuziming,
Cirilla-zmh and
ralf0131
September 22, 2026 01:56
…format) CI precommit failed on the new package: E402 in tests/conftest.py (imports intentionally after sys.path setup + pytest_configure), PLC0415 for lazy imports in src, and I001/format. Follow the existing per-file-ignores convention used by every other loongsuite instrumentation package (PLC0415 for the package, E402+F811 for tests), and apply ruff import sorting + formatting. No behavior change; 15 tests still pass.
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Structured prediction classification, active-span teardown, hierarchy verification, and CI registration need correction.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 3
Open (4)
What changed in this PR
Adds automatic OpenTelemetry instrumentation for LlamaIndex via its native dispatcher.
Changes:
- Maps LlamaIndex spans and events to GenAI telemetry.
- Adds lifecycle, hierarchy, classification, and embedding tests.
- Registers packaging and bootstrap metadata.
| File | Description |
|---|---|
pyproject.toml |
Adds Ruff exceptions. |
loongsuite-distro/.../loongsuite_instrumentation_llama_index.py |
Adds bootstrap registry metadata. |
.../tests/test_instrumentor.py |
Tests spans and lifecycle. |
.../tests/conftest.py |
Configures test tracing. |
.../tests/__init__.py |
Initializes tests. |
.../test-requirements.txt |
Adds test dependencies. |
.../version.py |
Defines package version. |
.../package.py |
Defines instrument dependency. |
.../llama_index/__init__.py |
Implements instrumentation. |
.../README.md |
Documents usage. |
.../pyproject.toml |
Defines package metadata. |
.../LICENSE |
Adds Apache license. |
.../CHANGELOG.md |
Records initial release. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+166
to
+167
| if method in ("predict", "apredict", "structured_predict"): | ||
| return _SPAN_KIND_LLM, _OP_CHAT |
Comment on lines
+584
to
+588
| dispatcher.span_handlers = [ | ||
| h | ||
| for h in dispatcher.span_handlers | ||
| if h is not self._span_handler | ||
| ] |
Comment on lines
+188
to
+189
| "instrumentation-loongsuite/loongsuite-instrumentation-llama-index/**/*.py" = ["PLC0415"] | ||
| "instrumentation-loongsuite/loongsuite-instrumentation-llama-index/tests/**/*.py" = ["E402", "F811"] |
Comment on lines
+135
to
+142
| by_span_id = {s.context.span_id: s for s in spans} | ||
| chat = next(s for s in spans if s.name.endswith(".chat")) | ||
| complete = next(s for s in spans if s.name.endswith(".complete")) | ||
|
|
||
| # complete's parent chain must reach the chat span within the same trace. | ||
| assert complete.parent is not None | ||
| assert complete.parent.span_id in by_span_id | ||
| assert complete.context.trace_id == chat.context.trace_id |
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.


What
Adds a new instrumentation package
loongsuite-instrumentation-llama-index, providing automatic OpenTelemetry instrumentation for LlamaIndex (llama-index-core).Closes #18 (roadmap #36 — "Add instrumentation for llama-index",
contribution welcome).How
Rather than monkey-patching call sites, this attaches to LlamaIndex's native instrumentation dispatcher (
llama_index.core.instrumentation). LlamaIndex already emits a span/event stream through a rootDispatcher, assigning each instrumented call a spanid_and aparent_span_idthat reflects the logical call tree (e.g.query→retrieve/synthesize,chat→complete). The package registers aBaseSpanHandler+BaseEventHandleron that dispatcher and re-projects the stream onto OpenTelemetry spans following the ARMS gen-ai semantic conventions, consumingparent_span_iddirectly so the OTel trace preserves LlamaIndex's own parent/child structure.Span-kind mapping (
gen_ai.span.kind): LLM / EMBEDDING / RETRIEVER / RERANKER / TASK (synthesis) / CHAIN (query engine) / AGENT (chat engine, agent run). Classification is method-first so class names embedding a misleading keyword (e.g.RetrieverQueryEngine.query) are classified correctly (CHAIN, not RETRIEVER). LLM/embedding events fold request model, messages and provider token usage onto the span. Content capture can be disabled withOTEL_INSTRUMENTATION_LLAMA_INDEX_CAPTURE_CONTENT=false.Testing
tests/test_instrumentor.pydrives the realllama-index-coredispatcher with in-processMockLLM/MockEmbeddingand asserts on spans exported to anInMemorySpanExporter(no network, no credentials). Each GREEN assertion is paired with a RED baseline:chatproduces an LLM span with correctgen_ai.*attributes;chat→completeshare onetrace_idwithcompletenested underchat(provingparent_span_idmapping); embedding produces an EMBEDDING span.uninstrument(), a subsequent chat produces zero spans.15 tests pass (
pytest), onllama-index-core 0.14.25+opentelemetry-sdk.Notes
pyproject.toml, entry point, CHANGELOG and bootstrap-registry entry follow the existingloongsuite-instrumentation-*conventions (e.g. terminus2).