gRPC OpenTracing Interceptors
grpcio-opentracing provides Python OpenTracing Extensions for gRPC, enabling distributed tracing by offering gRPC server and client interceptors. Its current version is 1.1.4. The library is part of the `grpc-ecosystem` but has not seen active development since 2019, reflecting the OpenTracing standard's status as largely superseded by OpenTelemetry.
Common errors
-
ModuleNotFoundError: No module named 'opentracing'
cause The core OpenTracing API library is not installed, which is a required peer dependency for `grpcio-opentracing` to function.fixInstall the `opentracing` package: `pip install opentracing`. -
grpc._channel._MultiThreadedRendezvous: <_Rendezvous of RPC that terminated with: status = StatusCode.UNKNOWN details = 'Tracer not set for OpenTracing interceptor'
cause The `grpcio-opentracing` interceptor could not find an `opentracing.Tracer` instance, either because the global tracer was not set or no tracer was explicitly passed to the interceptor.fixInitialize and set a global tracer (e.g., `opentracing.set_global_tracer(my_tracer)`) or pass a `tracer` object directly to the `OpenTracingServerInterceptor` or `OpenTracingClientInterceptor` constructor. -
TypeError: 'NoneType' object is not callable
cause This typically occurs when a tracer object is expected (e.g., `tracer.start_span()`), but the variable holding the tracer is `None`. This can happen if `opentracing.set_global_tracer()` was not called or a `None` value was passed to the interceptor.fixEnsure that a valid `opentracing.Tracer` instance is initialized and accessible (globally or explicitly passed) before any gRPC calls are made and before interceptors are configured.
Warnings
- breaking The OpenTracing project is officially deprecated in favor of OpenTelemetry. This library, `grpcio-opentracing`, has not seen active development since 2019, making it a legacy solution for distributed tracing.
- gotcha The interceptors require an `opentracing.Tracer` instance to be configured, either globally via `opentracing.set_global_tracer()` or passed directly to the interceptor constructor (`tracer=my_tracer`). If no tracer is found, tracing will not occur and may lead to `NoneType` errors or silent failures.
- gotcha Due to the lack of recent maintenance, `grpcio-opentracing` might have untested or unstable compatibility with newer versions of `grpcio` or Python. This could lead to unexpected behavior or runtime errors.
Install
-
pip install grpcio-opentracing opentracing -
pip install grpcio-opentracing opentracing jaeger-client
Imports
- OpenTracingServerInterceptor
from grpc_opentracing.server_interceptor import OpenTracingServerInterceptor
- OpenTracingClientInterceptor
from grpc_opentracing.client_interceptor import OpenTracingClientInterceptor
- set_global_tracer
from opentracing import set_global_tracer
import opentracing opentracing.set_global_tracer(...)
Quickstart
import grpc
from grpc_opentracing.server_interceptor import OpenTracingServerInterceptor
from grpc_opentracing.client_interceptor import OpenTracingClientInterceptor
import opentracing
from opentracing.mocktracer import MockTracer # For demonstration
# 1. Initialize an OpenTracing-compliant tracer (e.g., Jaeger, MockTracer)
mock_tracer = MockTracer()
# 2. Set the global tracer (optional, but common for simplicity)
opentracing.set_global_tracer(mock_tracer)
# 3. Create a server interceptor
server_interceptor = OpenTracingServerInterceptor(tracer=mock_tracer)
# To apply: server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[server_interceptor])
# 4. Create a client interceptor
client_interceptor = OpenTracingClientInterceptor(tracer=mock_tracer)
# To apply: channel = grpc.intercept_channel(grpc.insecure_channel('localhost:50051'), client_interceptor)
print("OpenTracing interceptors created successfully.")
print("Ensure a tracer is configured, either globally or passed explicitly to the interceptor.")