예제 #1
0
def test_get_tags_override(monkeypatch):
    monkeypatch.setenv("DD_PROFILING_TAGS", "mytag:foobar")
    tags = http.PprofHTTPExporter()._get_tags("foobar")
    assert len(tags) == 8
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["mytag"] == b"foobar"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")

    monkeypatch.setenv("DD_PROFILING_TAGS", "mytag:foobar,author:jd")
    tags = http.PprofHTTPExporter()._get_tags("foobar")
    assert len(tags) == 9
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["mytag"] == b"foobar"
    assert tags["author"] == b"jd"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")

    monkeypatch.setenv("DD_PROFILING_TAGS", "")
    tags = http.PprofHTTPExporter()._get_tags("foobar")
    assert len(tags) == 7
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")

    monkeypatch.setenv("DD_PROFILING_TAGS",
                       "foobar:baz,service:mycustomservice")
    tags = http.PprofHTTPExporter()._get_tags("foobar")
    assert len(tags) == 8
    assert tags["service"] == b"mycustomservice"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foobar"] == b"baz"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")

    monkeypatch.setenv("DD_PROFILING_TAGS", "foobar:baz,service:🤣")
    tags = http.PprofHTTPExporter()._get_tags("foobar")
    assert len(tags) == 8
    assert tags["service"] == u"🤣".encode("utf-8")
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foobar"] == b"baz"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
예제 #2
0
def test_get_tags_legacy(monkeypatch):
    monkeypatch.setenv("DD_PROFILING_TAGS", "mytag:baz")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert tags["mytag"] == b"baz"

    # precedence
    monkeypatch.setenv("DD_TAGS", "mytag:val1,ddtag:hi")
    monkeypatch.setenv("DD_PROFILING_TAGS", "mytag:val2,ddptag:lo")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert tags["mytag"] == b"val2"
    assert tags["ddtag"] == b"hi"
    assert tags["ddptag"] == b"lo"
예제 #3
0
def test_export_tracer_base_path(endpoint_test_server):
    # Base path is prepended to the endpoint path because
    # it does not start with a slash.
    exp = http.PprofHTTPExporter(_ENDPOINT + "/profiling/",
                                 _API_KEY,
                                 endpoint_path="v1/input")
    exp.export(test_pprof.TEST_EVENTS, 0, compat.time_ns())
예제 #4
0
    def _build_default_exporters(
            tracer,  # type: Optional[ddtrace.Tracer]
            url,  # type: Optional[str]
            service,  # type: Optional[str]
            env,  # type: Optional[str]
            version,  # type: Optional[str]
    ):
        # type: (...) -> List[exporter.Exporter]
        _OUTPUT_PPROF = os.environ.get("DD_PROFILING_OUTPUT_PPROF")
        if _OUTPUT_PPROF:
            return [
                file.PprofFileExporter(_OUTPUT_PPROF),
            ]

        api_key = _get_api_key()

        if api_key is None:
            # Agent mode
            endpoint_path = "/profiling/v1/input"
        else:
            endpoint_path = "/v1/input"

        endpoint = _get_default_url(tracer, api_key) if url is None else url

        return [
            http.PprofHTTPExporter(
                service=service,
                env=env,
                version=version,
                api_key=api_key,
                endpoint=endpoint,
                endpoint_path=endpoint_path,
            ),
        ]
예제 #5
0
def test_export_404_agent(endpoint_test_unknown_server):
    exp = http.PprofHTTPExporter(_UNKNOWN_ENDPOINT)
    with pytest.raises(exporter.ExportError) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    assert str(t.value) == (
        "Datadog Agent is not accepting profiles. "
        "Agent-based profiling deployments require Datadog Agent >= 7.20")
예제 #6
0
def test_export_server_down():
    exp = http.PprofHTTPExporter("http://localhost:2", _API_KEY)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
        e = t.exception
        assert isinstance(e, (IOError, OSError))
        assert e.errno == errno.ECONNREFUSED
예제 #7
0
    def _build_default_exporters(service, env, version):
        _OUTPUT_PPROF = os.environ.get("DD_PROFILING_OUTPUT_PPROF")
        if _OUTPUT_PPROF:
            return [
                file.PprofFileExporter(_OUTPUT_PPROF),
            ]

        api_key = _get_api_key()
        if api_key:
            # Agentless mode
            endpoint = _get_endpoint()
        else:
            hostname = os.environ.get(
                "DD_AGENT_HOST",
                os.environ.get("DATADOG_TRACE_AGENT_HOSTNAME", "localhost"))
            port = int(os.environ.get("DD_TRACE_AGENT_PORT", 8126))
            endpoint = os.environ.get("DD_TRACE_AGENT_URL", "http://%s:%d" %
                                      (hostname, port)) + "/profiling/v1/input"

        return [
            http.PprofHTTPExporter(service=service,
                                   env=env,
                                   version=version,
                                   api_key=api_key,
                                   endpoint=endpoint),
        ]
예제 #8
0
def test_export_timeout(endpoint_test_timeout_server):
    exp = http.PprofHTTPExporter(_TIMEOUT_ENDPOINT, _API_KEY, timeout=1, max_retry_delay=2)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.last_attempt.exception()
    assert isinstance(e, socket.timeout)
    assert str(t.value) == "timed out"
예제 #9
0
def test_export_server_down():
    exp = http.PprofHTTPExporter("http://localhost:2", _API_KEY, max_retry_delay=2)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.last_attempt.exception()
    assert isinstance(e, (IOError, OSError))
    assert str(t.value).startswith("[Errno ")
예제 #10
0
def test_export_tracer_base_path_agent_less(endpoint_test_server):
    # Base path is ignored by the profiling HTTP exporter
    # because the endpoint path starts with a slash.
    exp = http.PprofHTTPExporter(_ENDPOINT + "/profiling/",
                                 _API_KEY,
                                 endpoint_path="/profiling/v1/input")
    exp.export(test_pprof.TEST_EVENTS, 0, compat.time_ns())
예제 #11
0
def test_export_server_down():
    exp = http.PprofHTTPExporter("http://localhost:2", _API_KEY, max_retry_delay=10)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.exception
    assert isinstance(e, error.URLError)
    assert isinstance(e.reason, (IOError, OSError))
    assert e.reason.errno in (errno.ECONNREFUSED, errno.EADDRNOTAVAIL)
예제 #12
0
def test_wrong_api_key(endpoint_test_server):
    # This is mostly testing our test server, not the exporter
    exp = http.PprofHTTPExporter(_ENDPOINT,
                                 "this is not the right API key",
                                 max_retry_delay=2)
    with pytest.raises(exporter.ExportError) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    assert str(t.value) == "Server returned 400, check your API key"
예제 #13
0
def test_get_malformed(monkeypatch):
    monkeypatch.setenv("DD_TAGS", "mytagfoobar")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 7
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")

    monkeypatch.setenv("DD_TAGS", "mytagfoobar,")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 7
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")

    monkeypatch.setenv("DD_TAGS", ",")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 7
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")

    monkeypatch.setenv("DD_TAGS", "foo:bar,")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 8
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foo"] == b"bar"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
예제 #14
0
def test_default_from_env(monkeypatch):
    monkeypatch.setenv("DD_PROFILING_API_KEY", "123")
    exp = http.PprofHTTPExporter()
    assert exp.api_key == "123"
    assert exp.endpoint == "https://intake.profile.datadoghq.com/v1/input"

    monkeypatch.setenv("DD_PROFILING_API_URL", "foobar")
    exp = http.PprofHTTPExporter()
    assert exp.endpoint == "foobar"

    monkeypatch.setenv("DD_SITE", "datadoghq.eu")
    exp = http.PprofHTTPExporter()
    assert exp.endpoint == "foobar"

    monkeypatch.delenv("DD_PROFILING_API_URL")
    exp = http.PprofHTTPExporter()
    assert exp.endpoint == "https://intake.profile.datadoghq.eu/v1/input"

    monkeypatch.setenv("DD_API_KEY", "456")
    exp = http.PprofHTTPExporter()
    assert exp.api_key == "123"

    monkeypatch.delenv("DD_PROFILING_API_KEY")
    exp = http.PprofHTTPExporter()
    assert exp.api_key == "456"

    monkeypatch.setenv("DD_SERVICE", "myservice")
    exp = http.PprofHTTPExporter()
    assert exp.service_name == "myservice"
예제 #15
0
def test_get_tags():
    tags = http.PprofHTTPExporter()._get_tags("foobar")
    assert len(tags) == 7
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
예제 #16
0
def test_wrong_api_key(endpoint_test_server):
    # This is mostly testing our test server, not the exporter
    exp = http.PprofHTTPExporter(_ENDPOINT, "this is not the right API key", max_retry_delay=10)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.exception
    assert isinstance(e, error.HTTPError)
    assert e.code == 400
    assert e.reason == "Wrong API Key"
예제 #17
0
def test_wrong_api_key(endpoint_test_server):
    # This is mostly testing our test server, not the exporter
    exp = http.PprofHTTPExporter(_ENDPOINT, "this is not the right API key")
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
        e = t.exception
        assert isinstance(e, http.RequestFailed)
        assert e.response.status == 400
        assert e.content == b"Wrong API Key\n"
예제 #18
0
def test_export_reset(endpoint_test_reset_server):
    exp = http.PprofHTTPExporter(_RESET_ENDPOINT, _API_KEY, timeout=1)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.exception
    if six.PY3:
        assert isinstance(e, ConnectionResetError)
    else:
        assert isinstance(e, http_client.BadStatusLine)
예제 #19
0
def test_export_reset(endpoint_test_reset_server):
    exp = http.PprofHTTPExporter(_RESET_ENDPOINT, _API_KEY, timeout=1, max_retry_delay=2)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.last_attempt.exception()
    if six.PY3:
        assert isinstance(e, ConnectionResetError)
    else:
        assert isinstance(e, http_client.BadStatusLine)
        assert str(e) == "No status line received - the server has closed the connection"
예제 #20
0
def test_export_404_agent(endpoint_test_unknown_server):
    exp = http.PprofHTTPExporter(_UNKNOWN_ENDPOINT)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.exception
    assert isinstance(e, error.HTTPError)
    assert e.code == 404
    assert str(t.value) == (
        "Unable to upload profile: Datadog Agent is not accepting profiles. "
        "Agent-based profiling deployments require Datadog Agent >= 7.20")
예제 #21
0
def test_get_tags():
    tags = http.PprofHTTPExporter(env="foobar")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 8
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["env"] == b"foobar"
    assert tags["runtime"] == b"CPython"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert "version" not in tags
예제 #22
0
def _build_default_exporters():
    exporters = []
    if "DD_PROFILING_API_KEY" in os.environ or "DD_API_KEY" in os.environ:
        exporters.append(http.PprofHTTPExporter())

    _OUTPUT_PPROF = os.environ.get("DD_PROFILING_OUTPUT_PPROF")
    if _OUTPUT_PPROF:
        exporters.append(file.PprofFileExporter(_OUTPUT_PPROF))

    if not exporters:
        LOG.warning("No exporters are configured, no profile will be output")

    return exporters
예제 #23
0
def test_export_404_agentless(endpoint_test_unknown_server):
    exp = http.PprofHTTPExporter(_UNKNOWN_ENDPOINT, api_key="123", timeout=1)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.exception
    assert isinstance(e, error.HTTPError)
    assert e.code == 404
    if six.PY2:
        assert str(
            t.value
        ) == "Unable to upload profile: HTTPError: HTTP Error 404: Argh\n"
    else:
        assert str(
            t.value
        ) == "Unable to upload profile: urllib.error.HTTPError: HTTP Error 404: Argh\n"
예제 #24
0
    def _build_default_exporters(url, service, env, version):
        _OUTPUT_PPROF = os.environ.get("DD_PROFILING_OUTPUT_PPROF")
        if _OUTPUT_PPROF:
            return [
                file.PprofFileExporter(_OUTPUT_PPROF),
            ]

        api_key = _get_api_key()
        endpoint = _get_default_url(api_key) if url is None else url

        return [
            http.PprofHTTPExporter(service=service,
                                   env=env,
                                   version=version,
                                   api_key=api_key,
                                   endpoint=endpoint),
        ]
예제 #25
0
    def _build_default_exporters(self):
        # type: (...) -> List[exporter.Exporter]
        _OUTPUT_PPROF = os.environ.get("DD_PROFILING_OUTPUT_PPROF")
        if _OUTPUT_PPROF:
            return [
                file.PprofFileExporter(_OUTPUT_PPROF),
            ]

        if self.url is not None:
            endpoint = self.url
        elif self.agentless:
            LOG.warning(
                "Agentless uploading is currently for internal usage only and not officially supported. "
                "You should not enable it unless somebody at Datadog instructed you to do so."
            )
            endpoint = self.ENDPOINT_TEMPLATE.format(
                os.environ.get("DD_SITE", "datadoghq.com"))
        else:
            if isinstance(self.tracer.writer, writer.AgentWriter):
                endpoint = self.tracer.writer.agent_url
            else:
                endpoint = agent.get_trace_url()

        if self.agentless:
            endpoint_path = "/v1/input"
        else:
            # Agent mode
            # path is relative because it is appended
            # to the agent base path.
            endpoint_path = "profiling/v1/input"

        return [
            http.PprofHTTPExporter(
                service=self.service,
                env=self.env,
                tags=self.tags,
                version=self.version,
                api_key=self.api_key,
                endpoint=endpoint,
                endpoint_path=endpoint_path,
            ),
        ]
예제 #26
0
def test_export_no_endpoint(endpoint_test_server):
    exp = http.PprofHTTPExporter(endpoint="")
    with pytest.raises(http.InvalidEndpoint):
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
예제 #27
0
def test_get_tags_override(monkeypatch):
    monkeypatch.setenv("DD_TAGS", "mytag:foobar")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 8
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["mytag"] == b"foobar"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert "version" not in tags

    monkeypatch.setenv("DD_TAGS", "mytag:foobar,author:jd")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 9
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["mytag"] == b"foobar"
    assert tags["author"] == b"jd"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert "version" not in tags

    monkeypatch.setenv("DD_TAGS", "")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 7
    assert tags["service"] == b"foobar"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert "version" not in tags

    monkeypatch.setenv("DD_TAGS", "foobar:baz,service:mycustomservice")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 8
    assert tags["service"] == b"mycustomservice"
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foobar"] == b"baz"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert "version" not in tags

    monkeypatch.setenv("DD_TAGS", "foobar:baz,service:�不")
    tags = http.PprofHTTPExporter(endpoint="")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 8
    assert tags["service"] == u"�不".encode("utf-8")
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foobar"] == b"baz"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert "version" not in tags

    tags = http.PprofHTTPExporter(endpoint="",
                                  version="123")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 9
    assert tags["service"] == u"�不".encode("utf-8")
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foobar"] == b"baz"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert tags["version"] == b"123"
    assert "env" not in tags

    tags = http.PprofHTTPExporter(endpoint="", version="123",
                                  env="prod")._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 10
    assert tags["service"] == u"�不".encode("utf-8")
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foobar"] == b"baz"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert tags["version"] == b"123"
    assert tags["env"] == b"prod"

    tags = http.PprofHTTPExporter(endpoint="",
                                  version="123",
                                  env="prod",
                                  tags={
                                      "mytag": "123"
                                  })._get_tags("foobar")
    _check_tags_types(tags)
    assert len(tags) == 11
    assert tags["service"] == u"�不".encode("utf-8")
    assert len(tags["host"])
    assert len(tags["runtime-id"])
    assert tags["language"] == b"python"
    assert tags["runtime"] == b"CPython"
    assert tags["foobar"] == b"baz"
    assert tags["profiler_version"] == ddtrace.__version__.encode("utf-8")
    assert tags["version"] == b"123"
    assert tags["env"] == b"prod"
    assert tags["mytag"] == b"123"
예제 #28
0
def test_export_timeout(endpoint_test_timeout_server):
    exp = http.PprofHTTPExporter(_TIMEOUT_ENDPOINT, _API_KEY, timeout=1)
    with pytest.raises(http.UploadFailed) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    e = t.value.exception
    assert isinstance(e, socket.timeout)
예제 #29
0
def test_export_404_agentless(endpoint_test_unknown_server):
    exp = http.PprofHTTPExporter(_UNKNOWN_ENDPOINT, api_key="123", timeout=1)
    with pytest.raises(exporter.ExportError) as t:
        exp.export(test_pprof.TEST_EVENTS, 0, 1)
    assert str(t.value) == "HTTP Error 404"
예제 #30
0
def test_export(endpoint_test_server):
    exp = http.PprofHTTPExporter(_ENDPOINT, _API_KEY)
    exp.export(test_pprof.TEST_EVENTS, 0, compat.time_ns())