async def __aenter__(self) -> 'Connection': if self._db is None or self._db._pool is None: # noqa raise UserWarning pspan = ctx_span_get() if pspan is None: span: OraSpan = self._db.app.logger.span_new( # type: ignore OraSpan.NAME_ACQUIRE, cls=OraSpan, ) else: span = pspan.new_child( # type: ignore OraSpan.NAME_ACQUIRE, cls=OraSpan, ) self._span = span span.set_name4adapter(self._db.app.logger.ADAPTER_PROMETHEUS, OraSpan.P8S_NAME_ACQUIRE) self._ctx_token = ctx_span_set(span) span.start() try: # todo acquire_timeout self._conn = await self._db.loop.run_in_executor( None, self._db._pool.acquire) span.annotate(OraSpan.ANN_ACQUIRE, '') except BaseException as err: span.finish(exception=err) ctx_span_reset(self._ctx_token) raise else: return self._db._connection_factory(self._db, self._conn)
def __enter__(self) -> 'Span': self.start() wrap = misc.ctx_span_trap_get() if wrap is not None: for item in wrap: item._set_span(self) self._ctx_token = misc.ctx_span_set(self) return self
async def _async_on_message_callback( self, cb: Callable[ [bytes, pika.spec.Basic.Deliver, pika.spec.BasicProperties], Awaitable[None], ], _unused_channel: pika.channel.Channel, basic_deliver: pika.spec.Basic.Deliver, properties: pika.spec.BasicProperties, body: bytes, ) -> None: _fix_properties(properties) headers = dict(properties.headers or {}) with self.amqp.app.logger.span_from_headers(headers, cls=AmqpInSpan) as span: span.name = AmqpSpan.NAME_MESSAGE span.kind = AmqpSpan.KIND_SERVER span.tag(AmqpSpan.TAG_URL, self._conn.pika._masked_url) span.tag( AmqpSpan.TAG_CHANNEL_NUMBER, str(_unused_channel.channel_number), ) span.tag(AmqpSpan.TAG_EXCHANGE, basic_deliver.exchange) span.tag(AmqpSpan.TAG_ROUTING_KEY, basic_deliver.routing_key) if self.amqp.cfg.log_in_props: span.annotate(AmqpSpan.ANN_IN_PROPS, props2ann(properties)) span.annotate4adapter( self.amqp.app.logger.ADAPTER_ZIPKIN, AmqpSpan.ANN_IN_PROPS, self._json_encode({ "properties": repr({ k: v for k, v in properties.__dict__.items() if v is not None }) }), ) if self.amqp.cfg.log_in_body: _body = decode_bytes(body) span.annotate(AmqpSpan.ANN_IN_BODY, _body) span.annotate4adapter( self.amqp.app.logger.ADAPTER_ZIPKIN, AmqpSpan.ANN_IN_BODY, self._json_encode({"message": _body}), ) token = ctx_span_set(span) try: await cb(body, basic_deliver, properties) except BaseException: raise finally: ctx_span_reset(token)
async def __call__( self, scope: dict, receive: Callable[..., Awaitable], send: Callable[..., Awaitable], ) -> None: span_token: Optional[Token] = None headers: Dict[str, str] = {} url: Optional[URL] = None host: Optional[str] = None method: Optional[str] = None path: Optional[str] = None if scope['type'] == 'http': headers = {h[0].decode(): h[1].decode() for h in scope['headers']} host = ':'.join([str(s) for s in scope['server']]) path = scope['raw_path'].decode() if scope['query_string']: path += '?' + scope['query_string'].decode() url = URL('%s://%s%s' % (scope['scheme'], host, path)) try: span: HttpSpan = self.uvicorn.app.logger.span_from_headers( # type: ignore headers, cls=ServerHttpSpan ) span.name, span_tags = self._get_route_details(scope) for tag_name, tag_value in span_tags.items(): span.tag(tag_name, tag_value) span_token = ctx_span_set(span) with span: span.kind = HttpSpan.KIND_SERVER if host is not None: span.tag(HttpSpan.TAG_HTTP_HOST, host) if path is not None: span.tag(HttpSpan.TAG_HTTP_PATH, path) if method is not None: span.tag(HttpSpan.TAG_HTTP_METHOD, method) if url is not None: span.tag(HttpSpan.TAG_HTTP_URL, self._mask_url(url)) try: await self.app( scope, partial(self.receive_wraper, receive), partial(self.send_wraper, send), ) except Exception as err: self.uvicorn.app.log_err(err) span.error(err) except Exception as err: self.uvicorn.app.log_err(err) raise finally: if span_token: ctx_span_reset(span_token)
async def _req_wrapper( self, request: web.Request, handler: Callable[[web.Request], Awaitable[web.StreamResponse]], ) -> Union[web.Response, web.FileResponse]: span_token: Optional[Token] = None request_token: Optional[Token] = None try: span: HttpSpan = self.app.logger.span_from_headers( # type: ignore request.headers, cls=ServerHttpSpan) span_token = ctx_span_set(span) request_token = ctx_request_set(request) with span: ts1 = time.time() span.kind = HttpSpan.KIND_SERVER span.tag(HttpSpan.TAG_HTTP_HOST, request.host) span.tag(HttpSpan.TAG_HTTP_PATH, request.raw_path) span.tag(HttpSpan.TAG_HTTP_METHOD, request.method.upper()) span.tag(HttpSpan.TAG_HTTP_URL, self._mask_url(request.url)) if self.cfg.log_req_hdrs: self._span_annotate_req_hdrs(span, request.headers, ts=ts1) if self.cfg.log_req_body: self._span_annotate_req_body( span, await request.read(), ts=ts1, encoding=request.charset, ) if request.match_info.route.resource is not None: route = request.match_info.route.resource.canonical span.tag(HttpSpan.TAG_HTTP_ROUTE, route) ts2: float try: resp = await handler(request) ts2 = time.time() except Exception as err: self.app.log_err(err) span.error(err) try: resp = await self.handler.error_handler(request, err) ts2 = time.time() except Exception as err2: self.app.log_err(err2) span.error(err2) if isinstance(err2, web.Response): resp = err2 ts2 = time.time() if not isinstance(resp, (web.Response, web.FileResponse)): raise UserWarning('Invalid response: %s' % resp) if 'Server' not in resp.headers: resp.headers['Server'] = SERVER span.tag(HttpSpan.TAG_HTTP_STATUS_CODE, str(resp.status)) if self.cfg.log_resp_hdrs: self._span_annotate_resp_hdrs(span, resp.headers, ts=ts2) if self.cfg.log_resp_body and isinstance(resp, web.Response): if resp.body is not None: if isinstance(resp.body, Payload): body = ('--- payload %s ---' '' % resp.body.__class__.__name__).encode() else: body = resp.body self._span_annotate_resp_body(span, body, ts=ts2, encoding=resp.charset) return resp finally: if request_token: ctx_request_reset(request_token) if span_token: ctx_span_reset(span_token)