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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions instana/instrumentation/aiohttp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ async def stan_middleware(request, handler):
response.headers['Server-Timing'] = "intid;desc=%s" % scope.span.context.trace_id

return response
except Exception:
except Exception as e:
logger.debug("aiohttp stan_middleware", exc_info=True)
if scope is not None:
scope.span.set_tag("http.status_code", 500)
scope.span.log_exception(e)
raise
finally:
if scope is not None:
scope.close()
Expand All @@ -62,7 +66,7 @@ async def stan_middleware(request, handler):
@wrapt.patch_function_wrapper('aiohttp.web','Application.__init__')
def init_with_instana(wrapped, instance, argv, kwargs):
if "middlewares" in kwargs:
kwargs["middlewares"].append(stan_middleware)
kwargs["middlewares"].insert(0, stan_middleware)
else:
kwargs["middlewares"] = [stan_middleware]

Expand Down
7 changes: 6 additions & 1 deletion tests/apps/app_aiohttp.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import asyncio
from aiohttp import web
Expand All @@ -22,6 +22,10 @@ def five_hundred(request):
return web.HTTPInternalServerError(reason="I must simulate errors.", text="Simulated server error.")


def raise_exception(request):
raise Exception("Simulated exception")


def run_server():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
Expand All @@ -30,6 +34,7 @@ def run_server():
app.add_routes([web.get('/', say_hello)])
app.add_routes([web.get('/401', four_hundred_one)])
app.add_routes([web.get('/500', five_hundred)])
app.add_routes([web.get('/exception', raise_exception)])

runner = web.AppRunner(app)
loop.run_until_complete(runner.setup())
Expand Down
52 changes: 51 additions & 1 deletion tests/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,6 @@ async def test():
assert("Server-Timing" in response.headers)
self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId)


def test_server_custom_header_capture(self):
async def test():
with async_tracer.start_active_span('test'):
Expand Down Expand Up @@ -703,3 +702,54 @@ async def test():
assert("Server-Timing" in response.headers)
self.assertEqual(response.headers["Server-Timing"], "intid;desc=%s" % traceId)


def test_server_get_exception(self):
async def test():
with async_tracer.start_active_span('test'):
async with aiohttp.ClientSession() as session:
return await self.fetch(session, testenv["aiohttp_server"] + "/exception")

response = self.loop.run_until_complete(test())

spans = self.recorder.queued_spans()
self.assertEqual(3, len(spans))

aioserver_span = spans[0]
aioclient_span = spans[1]
test_span = spans[2]

self.assertIsNone(async_tracer.active_span)

# Same traceId
traceId = test_span.t
self.assertEqual(traceId, aioclient_span.t)
self.assertEqual(traceId, aioserver_span.t)

# Parent relationships
self.assertEqual(aioclient_span.p, test_span.s)
self.assertEqual(aioserver_span.p, aioclient_span.s)

# Error logging
self.assertFalse(test_span.error)
self.assertIsNone(test_span.ec)
self.assertTrue(aioclient_span.error)
self.assertEqual(aioclient_span.ec, 1)
self.assertTrue(aioserver_span.error)
self.assertEqual(aioserver_span.ec, 1)

self.assertEqual("aiohttp-server", aioserver_span.n)
self.assertEqual(500, aioserver_span.data.http.status)
self.assertEqual(testenv["aiohttp_server"] + "/exception", aioserver_span.data.http.url)
self.assertEqual("GET", aioserver_span.data.http.method)
self.assertIsNotNone(aioserver_span.stack)
self.assertTrue(type(aioserver_span.stack) is list)
self.assertTrue(len(aioserver_span.stack) > 1)

self.assertEqual("aiohttp-client", aioclient_span.n)
self.assertEqual(500, aioclient_span.data.http.status)
self.assertEqual(testenv["aiohttp_server"] + "/exception", aioclient_span.data.http.url)
self.assertEqual("GET", aioclient_span.data.http.method)
self.assertEqual('Internal Server Error', aioclient_span.data.http.error)
self.assertIsNotNone(aioclient_span.stack)
self.assertTrue(type(aioclient_span.stack) is list)
self.assertTrue(len(aioclient_span.stack) > 1)