OpenTelemetry Tornado Instrumentation
This library provides instrumentation for the Tornado web framework within OpenTelemetry, capturing request flows and performance metrics for observability. It builds upon OpenTelemetry's WSGI middleware to track web requests. Currently, the library is in beta and designed to integrate with Tornado's asynchronous, high-performance architecture.
Warnings
- gotcha This instrumentation library is currently in beta. While generally functional, it may introduce breaking changes or performance issues and should be used with caution in production environments.
- gotcha When using multi-process or forking web servers (e.g., Gunicorn with multiple workers) with OpenTelemetry Python auto-instrumentation, metrics generation can become inconsistent. This is due to how forking interacts with background threads and locks in key OpenTelemetry SDK components.
- gotcha To capture specific HTTP request or response headers as span attributes, you must explicitly configure them via environment variables: `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST` and `OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE`. Header names in Tornado are case-insensitive for capture purposes.
- gotcha Paths can be excluded from automatic tracing using the `OTEL_PYTHON_TORNADO_EXCLUDED_URLS` environment variable (or `OTEL_PYTHON_EXCLUDED_URLS` for all instrumentations). Additionally, custom request attributes can be traced using `OTEL_PYTHON_TORNADO_TRACED_REQUEST_ATTRS`.
Install
-
pip install opentelemetry-instrumentation-tornado opentelemetry-sdk opentelemetry-exporter-otlp tornado
Imports
- TornadoInstrumentor
from opentelemetry.instrumentation.tornado import TornadoInstrumentor
Quickstart
import tornado.ioloop
import tornado.web
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
from opentelemetry.instrumentation.tornado import TornadoInstrumentor
# 1. Configure OpenTelemetry SDK
resource = Resource.create({"service.name": "tornado-app"})
provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
# 2. Instrument Tornado
TornadoInstrumentor().instrument()
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, Tornado OpenTelemetry!")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
print("Tornado server listening on http://localhost:8888")
print("Visit http://localhost:8888 to see traces in console.")
tornado.ioloop.IOLoop.current().start()