Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ endif::[]

* Fix return for `opentelemetry.Span.is_recording()` {pull}1530[#1530]
* Fix error logging for bad SERVICE_NAME config {pull}1546[#1546]
* Do not instrument old versions of Tornado > 6.0 due to incompatibility {pull}1566[#1566]


[[release-notes-6.x]]
Expand Down
22 changes: 19 additions & 3 deletions elasticapm/instrumentation/packages/tornado.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,25 @@
from elasticapm.instrumentation.packages.asyncio.base import AbstractInstrumentedModule, AsyncAbstractInstrumentedModule
from elasticapm.traces import capture_span
from elasticapm.utils.disttracing import TraceParent
from elasticapm.utils.logging import get_logger

logger = get_logger("elasticapm.instrument")

class TornadoRequestExecuteInstrumentation(AsyncAbstractInstrumentedModule):

class TornadoBaseInstrumentedModule(AbstractInstrumentedModule):
def instrument(self):
try:
import tornado

if tornado.version_info[0] < 6:
logger.debug("Skipping instrumentation of %s. Tornado is only supported with version 6.0+", self.name)
return
except ImportError:
pass
super().instrument()


class TornadoRequestExecuteInstrumentation(TornadoBaseInstrumentedModule, AsyncAbstractInstrumentedModule):
name = "tornado_request_execute"
creates_transactions = True
instrument_list = [("tornado.web", "RequestHandler._execute")]
Expand Down Expand Up @@ -78,7 +94,7 @@ async def call(self, module, method, wrapped, instance, args, kwargs):
return ret


class TornadoHandleRequestExceptionInstrumentation(AbstractInstrumentedModule):
class TornadoHandleRequestExceptionInstrumentation(TornadoBaseInstrumentedModule):
name = "tornado_handle_request_exception"

instrument_list = [("tornado.web", "RequestHandler._handle_request_exception")]
Expand Down Expand Up @@ -115,7 +131,7 @@ def call(self, module, method, wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)


class TornadoRenderInstrumentation(AbstractInstrumentedModule):
class TornadoRenderInstrumentation(TornadoBaseInstrumentedModule):
name = "tornado_render"

instrument_list = [("tornado.web", "RequestHandler.render")]
Expand Down
27 changes: 27 additions & 0 deletions tests/contrib/asyncio/tornado/tornado_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
from elasticapm.conf import constants
from elasticapm.contrib.tornado import ElasticAPM
from elasticapm.utils.disttracing import TraceParent
from elasticapm.utils.wrapt import BoundFunctionWrapper
from tests.utils import assert_any_record_contains

pytestmark = pytest.mark.tornado

Expand Down Expand Up @@ -254,3 +256,28 @@ async def test_tornado_transaction_ignore_urls(app, base_url, http_client):

response = await http_client.fetch(base_url + "/render")
assert len(elasticapm_client.events[constants.TRANSACTION]) == 1


def test_old_tornado_not_instrumented(caplog):
with mock.patch("tornado.version_info", (5, 11, 0)):
try:
with caplog.at_level("DEBUG"):
elasticapm.instrument()
from tornado.web import RequestHandler

assert not isinstance(RequestHandler._execute, BoundFunctionWrapper)
assert not isinstance(RequestHandler._handle_request_exception, BoundFunctionWrapper)
assert not isinstance(RequestHandler.render, BoundFunctionWrapper)
finally:
elasticapm.uninstrument()
assert_any_record_contains(
caplog.records, "Skipping instrumentation of tornado_render. Tornado is only supported with version 6.0+"
)
assert_any_record_contains(
caplog.records,
"Skipping instrumentation of tornado_handle_request_exception. Tornado is only supported with version 6.0+",
)
assert_any_record_contains(
caplog.records,
"Skipping instrumentation of tornado_request_execute. Tornado is only supported with version 6.0+",
)