Skip to content

OpenTelemetry tracing support#786

Open
tewbo wants to merge 8 commits intoydb-platform:mainfrom
tewbo:otel-tracing-support
Open

OpenTelemetry tracing support#786
tewbo wants to merge 8 commits intoydb-platform:mainfrom
tewbo:otel-tracing-support

Conversation

@tewbo
Copy link
Copy Markdown

@tewbo tewbo commented Mar 21, 2026

Pull request type

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

What is the current behavior?

The YDB Python SDK does not provide built-in OpenTelemetry tracing support. There is legacy integration with OpenTracing API which uses the deprecated standard.

Issue Number: N/A

What is the new behavior?

Adds OpenTelemetry tracing support to the YDB Python SDK. When enabled via enable_tracing(), the SDK automatically creates spans for key operations:

  • ydb.CreateSession — session creation
  • ydb.ExecuteQuery — query execution (session and transaction level, both sync and async)
  • ydb.Commit / ydb.Rollback — transaction commit and rollback
  • ydb.Driver.Initialize — driver initialization

Each span includes standard attributes: db.system.name, db.namespace, server.address, server.port, ydb.session.id, ydb.node.id, ydb.tx.id.

W3C Trace Context (traceparent) is automatically propagated in gRPC metadata, enabling end-to-end distributed tracing between client and YDB server. Execute spans cover the full operation lifecycle, including streaming result iteration — not just the initial gRPC call. Errors are recorded on spans with error.type, db.response.status_code, and exception events.

Tracing is opt-in (pip install ydb[tracing] + enable_tracing()). Without it, the SDK behavior is unchanged — all tracing code paths are no-op.

Other information

  • Includes unit tests for sync, async, error handling, parent-child relationships, context propagation, noop mode, and concurrent span isolation

@tewbo tewbo marked this pull request as draft March 23, 2026 10:36
@KirillKurdyukov KirillKurdyukov self-requested a review March 23, 2026 13:47
@tewbo tewbo marked this pull request as ready for review March 24, 2026 07:02

def _set_error_on_span(span, exception):
if isinstance(exception, issues.Error) and exception.status is not None:
error_type = exception.status.name
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error_type мы проставляем здесь как transport или ydb_error

Это можно определить по status code исключения.

"error.type", ydbException.Code
                is StatusCode.ClientTransportUnknown
                or StatusCode.ClientTransportUnavailable
                or StatusCode.ClientTransportTimeout
                or StatusCode.ClientTransportResourceExhausted
                or StatusCode.ClientTransportUnimplemented
                ? "transport_error"
                : "ydb_error"

options={"bdist_wheel": {"universal": True}},
extras_require={
"yc": ["yandexcloud", ],
"tracing": ["opentelemetry-api>=1.0.0", "opentelemetry-sdk>=1.0.0"],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's rename it to opentelemetry, we already have a tracing module and ydb[tracing] looks confusing


with ydb.QuerySessionPool(driver) as pool:
with tracer.start_as_current_span("sync-example"):
pool.execute_with_retries("SELECT 1")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add a dedicated page to our docs (docs folder) that describes how it works

if _enabled:
return

_tracer = trace.get_tracer("ydb.sdk")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it a good idea? what do you think about an ability to pass already existed tracer to this method?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that tracer is optional parameter

enable_tracing(tracer = null)

     tracer ?? trace.get_tracer("ydb.sdk")

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.

3 participants