Example #1
0
    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)
Example #2
0
    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
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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)