This library usesOpenTelemetryto automatically generate traces providing insight on calls to Cloud Spanner.
For information on the benefits and utility of tracing, see theCloud Trace docs.
To take advantage of these traces, we first need to install OpenTelemetry:
We also need to tell OpenTelemetry which exporter to use. To export Spanner traces toCloud Tracing, add the following lines to your application:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.sampling import TraceIdRatioBased
from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
# BatchSpanProcessor exports spans to Cloud Trace
# in a seperate thread to not block on the main thread
from opentelemetry.sdk.trace.export import BatchSpanProcessor
# Create and export one trace every 1000 requests
sampler = TraceIdRatioBased(1/1000)
tracer_provider = TracerProvider(sampler=sampler)
tracer_provider.add_span_processor(
# Initialize the cloud tracing exporter
BatchSpanProcessor(CloudTraceSpanExporter())
)
observability_options = dict(
tracer_provider=tracer_provider,
# By default extended_tracing is set to True due
# to legacy reasons to avoid breaking changes, you
# can modify it though using the environment variable
# SPANNER_ENABLE_EXTENDED_TRACING=false.
enable_extended_tracing=False,
# By default end to end tracing is set to False. Set to True
# for getting spans for Spanner server.
enable_end_to_end_tracing=True,
)
spanner = spanner.NewClient(project_id, observability_options=observability_options)
To get more fine-grained traces from gRPC, you can enable the gRPC instrumentation by the following
and then in your Python code, please add the following lines:
from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient
grpc_client_instrumentor = GrpcInstrumentorClient()
grpc_client_instrumentor.instrument()
Generated spanner traces should now be available onCloud Trace.
Tracing is most effective when many libraries are instrumented to provide insight over the entire lifespan of a request.
For a list of libraries that can be instrumented, see the OpenTelemetry Integrations section of theOpenTelemetry Python docs
Annotating spans with SQL
By default your spans will be annotated with SQL statements where appropriate, but that can be a PII (Personally Identifiable Information)
leak. Sadly due to legacy behavior, we cannot simply turn off this behavior by default. However you can control this behavior by setting
SPANNER_ENABLE_EXTENDED_TRACING=false
to turn it off globally or when creating each SpannerClient, please set observability_options.enable_extended_tracing=false
End to end tracing
In addition to client-side tracing, you can opt in for end-to-end tracing. End-to-end tracing helps you understand and debug latency issues that are specific to Spanner. Referherefor more information.
To configure end-to-end tracing.
Opt in for end-to-end tracing. You can opt-in by either:
* Setting the environment variable SPANNER_ENABLE_END_TO_END_TRACING=true before your application is started
* In code, by setting observability_options.enable_end_to_end_tracing=true when creating each SpannerClient.
Set the trace context propagation in OpenTelemetry.
from opentelemetry.propagate import set_global_textmap
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
set_global_textmap(TraceContextTextMapPropagator())
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-28 UTC."],[],[],null,["Version latestkeyboard_arrow_down\n\n- [3.57.0 (latest)](/python/docs/reference/spanner/latest/opentelemetry-tracing)\n- [3.56.0](/python/docs/reference/spanner/3.56.0/opentelemetry-tracing)\n- [3.55.0](/python/docs/reference/spanner/3.55.0/opentelemetry-tracing)\n- [3.54.0](/python/docs/reference/spanner/3.54.0/opentelemetry-tracing)\n- [3.53.0](/python/docs/reference/spanner/3.53.0/opentelemetry-tracing)\n- [3.52.0](/python/docs/reference/spanner/3.52.0/opentelemetry-tracing)\n- [3.51.0](/python/docs/reference/spanner/3.51.0/opentelemetry-tracing)\n- [3.50.1](/python/docs/reference/spanner/3.50.1/opentelemetry-tracing)\n- [3.46.0](/python/docs/reference/spanner/3.46.0/opentelemetry-tracing)\n- [3.45.0](/python/docs/reference/spanner/3.45.0/opentelemetry-tracing)\n- [3.44.0](/python/docs/reference/spanner/3.44.0/opentelemetry-tracing)\n- [3.43.0](/python/docs/reference/spanner/3.43.0/opentelemetry-tracing)\n- [3.42.0](/python/docs/reference/spanner/3.42.0/opentelemetry-tracing)\n- [3.41.0](/python/docs/reference/spanner/3.41.0/opentelemetry-tracing)\n- [3.40.1](/python/docs/reference/spanner/3.40.1/opentelemetry-tracing)\n- [3.39.0](/python/docs/reference/spanner/3.39.0/opentelemetry-tracing)\n- [3.38.0](/python/docs/reference/spanner/3.38.0/opentelemetry-tracing)\n- [3.37.0](/python/docs/reference/spanner/3.37.0/opentelemetry-tracing)\n- [3.36.0](/python/docs/reference/spanner/3.36.0/opentelemetry-tracing)\n- [3.35.1](/python/docs/reference/spanner/3.35.1/opentelemetry-tracing)\n- [3.34.0](/python/docs/reference/spanner/3.34.0/opentelemetry-tracing)\n- [3.33.0](/python/docs/reference/spanner/3.33.0/opentelemetry-tracing)\n- [3.32.0](/python/docs/reference/spanner/3.32.0/opentelemetry-tracing)\n- [3.31.0](/python/docs/reference/spanner/3.31.0/opentelemetry-tracing)\n- [3.30.0](/python/docs/reference/spanner/3.30.0/opentelemetry-tracing)\n- [3.29.0](/python/docs/reference/spanner/3.29.0/opentelemetry-tracing)\n- [3.28.0](/python/docs/reference/spanner/3.28.0/opentelemetry-tracing)\n- [3.27.1](/python/docs/reference/spanner/3.27.1/opentelemetry-tracing)\n- [3.26.0](/python/docs/reference/spanner/3.26.0/opentelemetry-tracing)\n- [3.25.0](/python/docs/reference/spanner/3.25.0/opentelemetry-tracing)\n- [3.24.0](/python/docs/reference/spanner/3.24.0/opentelemetry-tracing)\n- [3.23.0](/python/docs/reference/spanner/3.23.0/opentelemetry-tracing)\n- [3.22.2](/python/docs/reference/spanner/3.22.2/opentelemetry-tracing)\n- [3.21.0](/python/docs/reference/spanner/3.21.0/opentelemetry-tracing)\n- [3.20.0](/python/docs/reference/spanner/3.20.0/opentelemetry-tracing)\n- [3.19.0](/python/docs/reference/spanner/3.19.0/opentelemetry-tracing)\n- [3.18.0](/python/docs/reference/spanner/3.18.0/opentelemetry-tracing)\n- [3.17.0](/python/docs/reference/spanner/3.17.0/opentelemetry-tracing)\n- [3.16.0](/python/docs/reference/spanner/3.16.0/opentelemetry-tracing)\n- [3.15.1](/python/docs/reference/spanner/3.15.1/opentelemetry-tracing)\n- [3.14.1](/python/docs/reference/spanner/3.14.1/opentelemetry-tracing)\n- [3.13.0](/python/docs/reference/spanner/3.13.0/opentelemetry-tracing)\n- [3.12.1](/python/docs/reference/spanner/3.12.1/opentelemetry-tracing)\n- [3.11.1](/python/docs/reference/spanner/3.11.1/opentelemetry-tracing)\n- [3.10.0](/python/docs/reference/spanner/3.10.0/opentelemetry-tracing)\n- [3.9.0](/python/docs/reference/spanner/3.9.0/opentelemetry-tracing)\n- [3.8.0](/python/docs/reference/spanner/3.8.0/opentelemetry-tracing)\n- [3.7.0](/python/docs/reference/spanner/3.7.0/opentelemetry-tracing)\n- [3.6.0](/python/docs/reference/spanner/3.6.0/opentelemetry-tracing)\n- [3.5.0](/python/docs/reference/spanner/3.5.0/opentelemetry-tracing)\n- [3.4.0](/python/docs/reference/spanner/3.4.0/opentelemetry-tracing)\n- [3.3.0](/python/docs/reference/spanner/3.3.0/opentelemetry-tracing)\n- [3.2.0](/python/docs/reference/spanner/3.2.0/opentelemetry-tracing)\n- [3.1.0](/python/docs/reference/spanner/3.1.0/opentelemetry-tracing)\n- [3.0.0](/python/docs/reference/spanner/3.0.0/opentelemetry-tracing)\n- [2.1.1](/python/docs/reference/spanner/2.1.1/opentelemetry-tracing)\n- [2.0.0](/python/docs/reference/spanner/2.0.0/opentelemetry-tracing)\n- [1.19.3](/python/docs/reference/spanner/1.19.3/opentelemetry-tracing)\n- [1.18.0](/python/docs/reference/spanner/1.18.0/opentelemetry-tracing)\n- [1.17.1](/python/docs/reference/spanner/1.17.1/opentelemetry-tracing)\n- [1.16.0](/python/docs/reference/spanner/1.16.0/opentelemetry-tracing)\n- [1.15.1](/python/docs/reference/spanner/1.15.1/opentelemetry-tracing)\n- [1.14.0](/python/docs/reference/spanner/1.14.0/opentelemetry-tracing)\n- [1.13.0](/python/docs/reference/spanner/1.13.0/opentelemetry-tracing)\n- [1.12.0](/python/docs/reference/spanner/1.12.0/opentelemetry-tracing)\n- [1.11.0](/python/docs/reference/spanner/1.11.0/opentelemetry-tracing)\n- [1.10.0](/python/docs/reference/spanner/1.10.0/opentelemetry-tracing) \n\nTracing with OpenTelemetry\n==========================\n\nThis library uses [OpenTelemetry](https://opentelemetry.io/) to automatically generate traces providing insight on calls to Cloud Spanner.\nFor information on the benefits and utility of tracing, see the [Cloud Trace docs](https://cloud.google.com/trace/docs/overview).\n\nTo take advantage of these traces, we first need to install OpenTelemetry: \n\n pip install opentelemetry-api opentelemetry-sdk\n pip install opentelemetry-exporter-gcp-trace\n\nWe also need to tell OpenTelemetry which exporter to use. To export Spanner traces to [Cloud Tracing](https://cloud.google.com/trace), add the following lines to your application: \n\n from opentelemetry import trace\n from opentelemetry.sdk.trace import TracerProvider\n from opentelemetry.sdk.trace.sampling import TraceIdRatioBased\n from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter\n # BatchSpanProcessor exports spans to Cloud Trace\n # in a seperate thread to not block on the main thread\n from opentelemetry.sdk.trace.export import BatchSpanProcessor\n\n # Create and export one trace every 1000 requests\n sampler = TraceIdRatioBased(1/1000)\n tracer_provider = TracerProvider(sampler=sampler)\n tracer_provider.add_span_processor(\n # Initialize the cloud tracing exporter\n BatchSpanProcessor(CloudTraceSpanExporter())\n )\n observability_options = dict(\n tracer_provider=tracer_provider,\n\n # By default extended_tracing is set to True due\n # to legacy reasons to avoid breaking changes, you\n # can modify it though using the environment variable\n # SPANNER_ENABLE_EXTENDED_TRACING=false.\n enable_extended_tracing=False,\n\n # By default end to end tracing is set to False. Set to True\n # for getting spans for Spanner server.\n enable_end_to_end_tracing=True,\n )\n spanner = spanner.NewClient(project_id, observability_options=observability_options)\n\nTo get more fine-grained traces from gRPC, you can enable the gRPC instrumentation by the following \n\n pip install opentelemetry-instrumentation opentelemetry-instrumentation-grpc\n\nand then in your Python code, please add the following lines: \n\n from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient\n grpc_client_instrumentor = GrpcInstrumentorClient()\n grpc_client_instrumentor.instrument()\n\nGenerated spanner traces should now be available on [Cloud Trace](https://console.cloud.google.com/traces).\n\nTracing is most effective when many libraries are instrumented to provide insight over the entire lifespan of a request.\nFor a list of libraries that can be instrumented, see the OpenTelemetry Integrations section of the [OpenTelemetry Python docs](https://opentelemetry-python.readthedocs.io/en/stable/)\n\nAnnotating spans with SQL\n-------------------------\n\nBy default your spans will be annotated with SQL statements where appropriate, but that can be a PII (Personally Identifiable Information)\nleak. Sadly due to legacy behavior, we cannot simply turn off this behavior by default. However you can control this behavior by setting\n\u003e SPANNER_ENABLE_EXTENDED_TRACING=false\n\nto turn it off globally or when creating each SpannerClient, please set observability_options.enable_extended_tracing=false\n\nEnd to end tracing\n------------------\n\nIn addition to client-side tracing, you can opt in for end-to-end tracing. End-to-end tracing helps you understand and debug latency issues that are specific to Spanner. Refer [here](about:invalid#zCSafez) for more information.\n\nTo configure end-to-end tracing.\n\n1. Opt in for end-to-end tracing. You can opt-in by either:\n \\* Setting the environment variable SPANNER_ENABLE_END_TO_END_TRACING=true before your application is started\n \\* In code, by setting observability_options.enable_end_to_end_tracing=true when creating each SpannerClient.\n\n2. Set the trace context propagation in OpenTelemetry.\n\n from opentelemetry.propagate import set_global_textmap\n from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator\n set_global_textmap(TraceContextTextMapPropagator())"]]