Beispiel #1
0
async def test_multiple_requests(tracer):
    with override_http_config("asgi", dict(trace_query_string=True)):
        app = TraceMiddleware(basic_app, tracer=tracer)
        async with httpx.AsyncClient(app=app) as client:
            responses = await asyncio.gather(
                client.get("http://testserver/", params={"sleep": True}),
                client.get("http://testserver/", params={"sleep": True}),
            )

    assert len(responses) == 2
    assert [r.status_code for r in responses] == [200] * 2
    assert [r.text for r in responses] == ["sleep"] * 2

    spans = tracer.writer.pop_traces()
    assert len(spans) == 2
    assert len(spans[0]) == 1
    assert len(spans[1]) == 1

    r1_span = spans[0][0]
    assert r1_span.name == "asgi.request"
    assert r1_span.span_type == "web"
    assert r1_span.get_tag("http.method") == "GET"
    assert r1_span.get_tag("http.url") == "http://testserver/"
    assert r1_span.get_tag("http.query.string") == "sleep=true"

    r2_span = spans[0][0]
    assert r2_span.name == "asgi.request"
    assert r2_span.span_type == "web"
    assert r2_span.get_tag("http.method") == "GET"
    assert r2_span.get_tag("http.url") == "http://testserver/"
    assert r2_span.get_tag("http.query.string") == "sleep=true"
Beispiel #2
0
async def test_query_string(scope, tracer):
    with override_http_config("asgi", dict(trace_query_string=True)):
        app = TraceMiddleware(basic_app, tracer=tracer)
        scope["query_string"] = "foo=bar"
        instance = ApplicationCommunicator(app, scope)
        await instance.send_input({"type": "http.request", "body": b""})
        response_start = await instance.receive_output(1)
        assert response_start == {
            "type": "http.response.start",
            "status": 200,
            "headers": [[b"Content-Type", b"text/plain"]],
        }
        response_body = await instance.receive_output(1)
        assert response_body == {
            "type": "http.response.body",
            "body": b"*",
        }

        spans = tracer.writer.pop_traces()
        assert len(spans) == 1
        assert len(spans[0]) == 1
        request_span = spans[0][0]
        assert request_span.name == "asgi.request"
        assert request_span.span_type == "web"
        assert request_span.error == 0
        assert request_span.get_tag("http.status_code") == "200"
        _check_span_tags(scope, request_span)
Beispiel #3
0
async def test_distributed_tracing(scope, tracer):
    app = TraceMiddleware(basic_app, tracer=tracer)
    headers = [
        (http_propagation.HTTP_HEADER_PARENT_ID.encode(), "1234".encode()),
        (http_propagation.HTTP_HEADER_TRACE_ID.encode(), "5678".encode()),
    ]
    scope["headers"] = headers
    instance = ApplicationCommunicator(app, scope)
    await instance.send_input({"type": "http.request", "body": b""})
    response_start = await instance.receive_output(1)
    assert response_start == {
        "type": "http.response.start",
        "status": 200,
        "headers": [[b"Content-Type", b"text/plain"]],
    }
    response_body = await instance.receive_output(1)
    assert response_body == {
        "type": "http.response.body",
        "body": b"*",
    }

    spans = tracer.writer.pop_traces()
    assert len(spans) == 1
    assert len(spans[0]) == 1
    request_span = spans[0][0]
    assert request_span.name == "asgi.request"
    assert request_span.span_type == "web"
    assert request_span.parent_id == 1234
    assert request_span.trace_id == 5678
    assert request_span.error == 0
    assert request_span.get_tag("http.status_code") == "200"
    _check_span_tags(scope, request_span)
Beispiel #4
0
async def test_double_callable_asgi(scope, tracer):
    app = TraceMiddleware(double_callable_app, tracer=tracer)
    instance = ApplicationCommunicator(app, scope)
    await instance.send_input({"type": "http.request", "body": b""})
    response_start = await instance.receive_output(1)
    assert response_start == {
        "type": "http.response.start",
        "status": 200,
        "headers": [[b"Content-Type", b"text/plain"]],
    }
    response_body = await instance.receive_output(1)
    assert response_body == {
        "type": "http.response.body",
        "body": b"*",
    }

    spans = tracer.writer.pop_traces()
    assert len(spans) == 1
    assert len(spans[0]) == 1
    request_span = spans[0][0]
    assert request_span.name == "asgi.request"
    assert request_span.span_type == "web"
    assert request_span.error == 0
    assert request_span.get_tag("http.status_code") == "200"
    _check_span_tags(scope, request_span)
Beispiel #5
0
def traced_get_asgi_application(django, pin, func, instance, args, kwargs):
    from ddtrace.contrib.asgi import TraceMiddleware

    def django_asgi_modifier(span, scope):
        span.name = "django.request"

    return TraceMiddleware(func(*args, **kwargs),
                           integration_config=config.django,
                           span_modifier=django_asgi_modifier)
Beispiel #6
0
async def test_asgi_500(scope, tracer):
    app = TraceMiddleware(error_handled_app, tracer=tracer)
    instance = ApplicationCommunicator(app, scope)

    await instance.send_input({"type": "http.request", "body": b""})
    await instance.receive_output(1)

    spans = tracer.writer.pop_traces()
    assert len(spans) == 1
    assert len(spans[0]) == 1
    request_span = spans[0][0]
    assert request_span.name == "asgi.request"
    assert request_span.error == 1
    assert request_span.get_tag("http.status_code") == "500"
Beispiel #7
0
async def test_asgi_error(scope, tracer):
    app = TraceMiddleware(error_app, tracer=tracer)
    instance = ApplicationCommunicator(app, scope)
    with pytest.raises(RuntimeError):
        await instance.send_input({"type": "http.request", "body": b""})
        await instance.receive_output(1)

    spans = tracer.writer.pop_traces()
    assert len(spans) == 1
    assert len(spans[0]) == 1
    request_span = spans[0][0]
    assert request_span.name == "asgi.request"
    assert request_span.error == 1
    assert request_span.get_tag("error.msg") == "Test"
    assert request_span.get_tag("error.type") == "builtins.RuntimeError"
    assert 'raise RuntimeError("Test")' in request_span.get_tag("error.stack")
    _check_span_tags(scope, request_span)
Beispiel #8
0
async def test_bad_headers(scope, tracer, test_spans):
    """
    When headers can't be decoded
        The middleware should not raise
    """

    app = TraceMiddleware(basic_app, tracer=tracer)
    headers = [(bytes.fromhex("c0"), "test")]
    scope["headers"] = headers

    instance = ApplicationCommunicator(app, scope)
    await instance.send_input({"type": "http.request", "body": b""})
    response_start = await instance.receive_output(1)
    assert response_start == {
        "type": "http.response.start",
        "status": 200,
        "headers": [[b"Content-Type", b"text/plain"]],
    }
    response_body = await instance.receive_output(1)
    assert response_body == {
        "type": "http.response.body",
        "body": b"*",
    }
Beispiel #9
0
async def test_asgi_error_custom(scope, tracer, test_spans):
    def custom_handle_exception_span(exc, span):
        span.set_tag("http.status_code", 501)

    app = TraceMiddleware(error_app,
                          tracer=tracer,
                          handle_exception_span=custom_handle_exception_span)
    instance = ApplicationCommunicator(app, scope)
    with pytest.raises(RuntimeError):
        await instance.send_input({"type": "http.request", "body": b""})
        await instance.receive_output(1)

    spans = test_spans.pop_traces()
    assert len(spans) == 1
    assert len(spans[0]) == 1
    request_span = spans[0][0]
    assert request_span.name == "asgi.request"
    assert request_span.span_type == "web"
    assert request_span.error == 1
    assert request_span.get_tag("http.status_code") == "501"
    assert request_span.get_tag("error.msg") == "Test"
    assert request_span.get_tag("error.type") == "builtins.RuntimeError"
    assert 'raise RuntimeError("Test")' in request_span.get_tag("error.stack")
    _check_span_tags(scope, request_span)
Beispiel #10
0
from django.core.asgi import get_asgi_application
from django.urls import re_path

from ddtrace.contrib.asgi import TraceMiddleware

application = get_asgi_application()


async def simple_asgi_app(scope, receive, send):
    await send({
        "type": "http.response.start",
        "status": 200,
        "headers": [(b"Content-Type", b"text/plain")]
    })
    await send({
        "type": "http.response.body",
        "body": b"Hello World. It's me simple asgi app"
    })


channels_application = ProtocolTypeRouter({
    "http":
    AuthMiddlewareStack(
        URLRouter([
            re_path(r"traced-simple-asgi-app/",
                    TraceMiddleware(simple_asgi_app)),
            re_path(r"simple-asgi-app/", simple_asgi_app),
            re_path(r"", application),
        ]), )
})
Beispiel #11
0
from django.core.asgi import get_asgi_application

from ddtrace.contrib.asgi import TraceMiddleware

application = TraceMiddleware(get_asgi_application())
Beispiel #12
0
async def test_get_asgi_span(tracer, test_spans):
    async def test_app(scope, receive, send):
        message = await receive()
        if message.get("type") == "http.request":
            asgi_span = span_from_scope(scope)
            assert asgi_span is not None
            assert asgi_span.name == "asgi.request"
            await send({
                "type": "http.response.start",
                "status": 200,
                "headers": [[b"Content-Type", b"text/plain"]]
            })
            await send({"type": "http.response.body", "body": b""})

    app = TraceMiddleware(test_app, tracer=tracer)
    async with httpx.AsyncClient(app=app) as client:
        response = await client.get("http://testserver/")
        assert response.status_code == 200

    with override_http_config("asgi", dict(trace_query_string=True)):
        app = TraceMiddleware(test_app, tracer=tracer)
        async with httpx.AsyncClient(app=app) as client:
            response = await client.get("http://testserver/")
            assert response.status_code == 200

    async def test_app(scope, receive, send):
        message = await receive()
        if message.get("type") == "http.request":
            root = tracer.current_root_span()
            assert root.name == "root"
            asgi_span = span_from_scope(scope)
            assert asgi_span is not None
            assert asgi_span.name == "asgi.request"
            await send({
                "type": "http.response.start",
                "status": 200,
                "headers": [[b"Content-Type", b"text/plain"]]
            })
            await send({"type": "http.response.body", "body": b""})

    app = TraceMiddleware(test_app, tracer=tracer)
    async with httpx.AsyncClient(app=app) as client:
        with tracer.trace("root"):
            response = await client.get("http://testserver/")
            assert response.status_code == 200

    async def test_app_no_middleware(scope, receive, send):
        message = await receive()
        if message.get("type") == "http.request":
            asgi_span = span_from_scope(scope)
            assert asgi_span is None
            await send({
                "type": "http.response.start",
                "status": 200,
                "headers": [[b"Content-Type", b"text/plain"]]
            })
            await send({"type": "http.response.body", "body": b""})

    async with httpx.AsyncClient(app=test_app_no_middleware) as client:
        response = await client.get("http://testserver/")
        assert response.status_code == 200
Beispiel #13
0
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
from ddtrace.contrib.asgi import TraceMiddleware  # import the middleware


async def homepage(request):
    return JSONResponse({'hello': 'world'})


routes = [Route("/", endpoint=homepage)]

app = Starlette(debug=True, routes=routes)

# wrap the app for tracing
app = TraceMiddleware(app)
Beispiel #14
0
import os

import django
from channels.routing import get_default_application
from ddtrace.contrib.asgi import TraceMiddleware

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "crossroads.settings.prod")
django.setup()

application = TraceMiddleware(get_default_application())