Repository navigation
Conversation
…er and AI clients MCDB-103303 #closes Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
🟢 Approval recommended
The propagation paths, optional-dependency behavior, logging integration, and synchronous/asynchronous clients are implemented consistently and covered by targeted tests.
0 open findings
What changed in this PR
Adds end-to-end W3C trace-context propagation through UDF execution and outbound AI requests.
Changes:
- Extracts incoming trace context and adds trace IDs to UDF logs.
- Adds reusable synchronous/asynchronous HTTP header-injection hooks.
- Extends AI-client tests and test dependencies for OpenTelemetry.
| File | Description |
|---|---|
singlestoredb/utils/otel.py |
Provides reusable OpenTelemetry injection hooks. |
singlestoredb/functions/ext/asgi.py |
Propagates request trace context through UDF execution. |
singlestoredb/functions/ext/utils.py |
Permits trace IDs in JSON logs. |
singlestoredb/ai/chat.py |
Uses shared sync/async tracing hooks. |
singlestoredb/ai/embeddings.py |
Adds tracing to OpenAI, Azure, and Bedrock requests. |
singlestoredb/tests/test_udf_trace_context.py |
Tests UDF propagation and logging. |
singlestoredb/tests/test_embeddings.py |
Tests embeddings-client propagation. |
singlestoredb/tests/test_ai_chat.py |
Tests asynchronous chat-client propagation. |
pyproject.toml |
Adds OpenTelemetry API to test dependencies. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This branch was successfully 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.
Summary
Continues the caller's W3C trace context through the Python UDF server and forwards it on outbound AI calls. This lets one UDF batch request be followed with a single trace ID across nova-gateway nginx, nova-gateway, the UDF, and the Unified Model Gateway (UMG), which already continues
traceparent.UDF server (
functions/ext/asgi.py)traceparentfrom the incoming request using the OpenTelemetry propagator and attaches it as the current context for the duration of the request. Async UDF tasks and sync UDFs (run viato_threadundercopy_context()) inherit it, so outbound calls the UDF makes carry the caller'straceparent.trace_idto the UDF request log records (initiated, timeout, cancelled, error, metrics), and allowstrace_idin the JSON log formatter.traceparentleaves behaviour unchanged. The internalrequest_idis unchanged.AI clients
singlestoredb/utils/otel.pyholds the header injection helpers that were previously local toai/chat.py.SingleStoreEmbeddingsFactorynow injectstraceparenton the OpenAI/Azure httpx clients (sync and async, including caller-provided clients) and on Bedrock requests.SingleStoreChatFactorywithhttpx.AsyncClient.AsyncClientawaits its event hooks, so the existing sync request hook raisedTypeErroron async calls (ainvoke,abatch). Async clients now get a coroutine hook.Only
opentelemetry-apiis used: no SDK, exporter, or spans are created. Everything is a no-op whenopentelemetry-apiis not installed, so it is not a runtime dependency. It is added to thetestdependency group so CI runs the new tests. The nova-notebook runtime image already hasopentelemetry-apithrough Pulse.Behaviour change to note: for OpenAI/Azure embeddings, when the caller does not pass
http_client/http_async_client, the factory now builds httpx clients itself (600s timeout, 5s connect), mirroring the chat factory. These use httpx default connection-pool limits instead of the openai SDK defaults.Test Plan
singlestoredb/tests/test_udf_trace_context.pycovers async and sync UDFs: an incomingtraceparentis propagated to outbound calls made inside the UDF andtrace_idis logged; no header and an invalid header propagate nothing. Both propagation tests fail onmain.test_embeddings.py(OpenAI default and custom clients, Bedrock) andtest_ai_chat.py(async client injectstraceparent; this fails onmainwithTypeError).pytest singlestoredb/tests/test_udf_trace_context.py test_embeddings.py test_ai_chat.py test_udf_event_loop.py: 40 passed. pre-commit passes.ainvoke, and chat.batchall sent the exact incomingtraceparent(5 of 5 requests).Not yet validated end to end on a cell. Still to check: that UDF container logs reach Loki and that
info-level request logs are emitted in the deployed UDF runtime.Deployment Plan
traceparentheader on outbound AI requests and atrace_idlog field.JIRA Issues
Closes MCDB-103303 (parent story MCDB-101082). Related: MCDB-103304 (nginx starts the trace, https://github.com/singlestore/helios/pull/28456) and MCDB-103305 (image bump).