def test_header_encoding(self): # The test is for detecting the encoding compatibility issue in # Python2 and Python3 and what sanic does for encoding the headers. # This test case is expected to fail at the check_trace_id method # in SpanContext because it cannot match the pattern for trace_id, # And a new trace_id will generate for the context. sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = "你好" span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context( path='/', headers={sanic_trace_header: sanic_trace_id}) with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { '/http/url': u'http://localhost/', '/http/method': 'GET', } self.assertEqual(span.attributes, expected_attributes) assert isinstance(span.parent_span, base.NullContextManager) span_context = tracer.span_context self.assertNotEqual(span_context.trace_id, trace_id)
def test__do_trace_request(self): from qubit.opencensus.trace import asyncio_context sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = mock.Mock(config={}) sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context( path='/', headers={sanic_trace_header: sanic_trace_id}) with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { '/http/url': u'http://localhost/', '/http/method': 'GET', } self.assertEqual(span.attributes, expected_attributes) self.assertEqual(span.parent_span.span_id, span_id) span_context = tracer.span_context self.assertEqual(span_context.trace_id, trace_id)
async def wrap_execute(wrapped, instance, args, kwargs): """Wrap the session function to trace it.""" command = args[0] _tracer = asyncio_context.get_opencensus_tracer() if _tracer is None or isinstance(_tracer, NoopTracer): return await wrapped(*args, **kwargs) parent_span = _tracer.current_span() _span = parent_span.span(name='[aioredis] {}'.format(command)) _span.add_attribute('redis.db', instance.db) _span.add_attribute('redis.address', instance.address[0]) _span.add_attribute('redis.port', instance.address[1]) _span.add_attribute('redis.encoding', str(instance.encoding)) if len(args) > 1: _span.add_attribute('redis.key', args[1]) # Add the requests url to attributes try: _span.start() result = await wrapped(*args, **kwargs) if isinstance(result, bytes): _span.add_attribute('redis.resposne.size', len(result)) else: _span.add_attribute('redis.resposne.size', 0) return result except Exception as e: _span.add_attribute('error', True) _span.add_attribute('error.message', str(e)) raise (e) finally: _span.finish()
async def call(*args, **kwargs): _tracer = asyncio_context.get_opencensus_tracer() if _tracer is None or isinstance(_tracer, NoopTracer): return await aiohttp_func(*args, **kwargs) parent_span = _tracer.current_span() _span = parent_span.span(name='[aiohttp] {}'.format(args[1])) _span.add_attribute('aiohttp/method', str(args[1])) _span.add_attribute('aiohttp/url', str(args[2])) span_context = _tracer.span_context if propagator is not None: headers = propagator.to_headers(span_context) if 'headers' not in kwargs: kwargs['headers'] = {} for k, v in headers.items(): kwargs['headers'][k] = v try: _span.start() response = await aiohttp_func(*args, **kwargs) _span.add_attribute('aiohttp/status_code', str(response.status)) _span.add_attribute('aiohttp/status_reason', str(response.reason)) if response.status >= 500: _span.add_attribute('error', True) return response except Exception as e: _span.add_attribute('error', True) _span.add_attribute('error.message', str(e)) raise e finally: _span.finish()
async def root(req): tracer = asyncio_context.get_opencensus_tracer() with tracer.span(name='span1') as span1: with tracer.span(name='span2') as span2: async with aiohttp.ClientSession() as session: response = await req.app.conn.execute("get", "foobar") response = await session.get("https://ifconfig.co") return json({"hello": "world"})
async def __aexit__(self, exc_type, exc, tb): _tracer = asyncio_context.get_opencensus_tracer() if exc: _tracer.add_attribute_to_current_span('error', True) _tracer.add_attribute_to_current_span('error.message', str(exc)) _tracer.end_span() raise exc else: _tracer.end_span()
async def root(req): conn = await aioredis.create_connection('redis://localhost', loop=loop) tracer = asyncio_context.get_opencensus_tracer() with tracer.span(name='span1') as span1: with tracer.span(name='span2') as span2: async with aiohttp.ClientSession() as session: result = await session.get("http://localhost:8080") result2 = await session.get("http://localhost:8080") return json({"hello": await somefunc()})
async def __aenter__(self): _tracer = self.tracer if callable(_tracer): _tracer = _tracer() if not _tracer: _tracer = asyncio_context.get_opencensus_tracer() else: asyncio_context.set_opencensus_tracer(_tracer) _span = _tracer.start_span() _span.name = self.name if self.name is not None else ( "[func] " + self.function.__name__) return _span
async def helper(*args, **params): _tracer = asyncio_context.get_opencensus_tracer() _span = _tracer.start_span() _span.name = name if name is not None else ("[func] " + func.__name__) try: result = await process(func, *args, **params) _tracer.end_span() return result except Exception as e: _tracer.add_attribute_to_current_span('error', True) _tracer.add_attribute_to_current_span('error.message', str(e)) _tracer.end_span() raise e
def test__after_request_blacklist(self): sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() sanic_middleware.SanicMiddleware(app=app) request, response = app.test_client.get( '/_ah/health', headers={sanic_trace_header: sanic_trace_id}) tracer = asyncio_context.get_opencensus_tracer() self.assertEqual(response.status, 200) assert isinstance(tracer, noop_tracer.NoopTracer)
def test_header_is_none(self): app = self.create_app() sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context(path='/') with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() self.assertIsNotNone(tracer) span = tracer.current_span() expected_attributes = { '/http/url': u'http://localhost/', '/http/method': 'GET', } self.assertEqual(span.attributes, expected_attributes) assert isinstance(span.parent_span, base.NullContextManager)
def test__before_request_blacklist(self): sanic_trace_header = 'X_CLOUD_TRACE_CONTEXT' trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' sanic_trace_id = '{}/{}'.format(trace_id, span_id) app = self.create_app() sanic_middleware.SanicMiddleware(app=app) context = app.test_request_context( path='/_ah/health', headers={sanic_trace_header: sanic_trace_id}) with context: app.preprocess_request() tracer = asyncio_context.get_opencensus_tracer() assert isinstance(tracer, noop_tracer.NoopTracer) span = tracer.current_span() assert isinstance(span, base.NullContextManager)