예제 #1
0
def _get_default_url(
    tracer,  # type: Optional[ddtrace.Tracer]
    api_key,  # type: str
):
    # type: (...) -> str
    """Get default profiler exporter URL.

    If an API key is not specified, the URL will default to the agent location configured via the environment variables.

    If an API key is specified, the profiler goes into agentless mode and uses `DD_SITE` to upload directly to Datadog
    backend.

    :param api_key: The API key provided by the user.
    :param tracer: The tracer object to use to find default URL.
    """
    # Default URL changes if an API_KEY is provided in the env
    if api_key is None:
        if tracer is None:
            return agent.get_trace_url()
        else:
            # Only use the tracer writer URL if it has been modified by the user.
            if tracer.writer.agent_url != agent.get_trace_url() and tracer.writer.agent_url != agent.DEFAULT_TRACE_URL:
                return tracer.writer.agent_url
            else:
                return agent.get_trace_url()
    # Agentless mode
    legacy = os.environ.get("DD_PROFILING_API_URL")
    if legacy:
        deprecation.deprecation("DD_PROFILING_API_URL", "Use DD_SITE")
        return legacy
    site = os.environ.get("DD_SITE", "datadoghq.com")
    return ENDPOINT_TEMPLATE.format(site)
예제 #2
0
def test_trace_url(monkeypatch):
    assert agent.get_trace_url() == "http://localhost:8126"
    monkeypatch.setenv("DD_TRACE_AGENT_PORT", "1235")
    assert agent.get_trace_url() == "http://localhost:1235"
    monkeypatch.setenv("DD_AGENT_HOST", "mars")
    assert agent.get_trace_url() == "http://mars:1235"

    monkeypatch.setenv("DD_TRACE_AGENT_URL", "http://saturn:1111")
    assert agent.get_trace_url() == "http://saturn:1111"
예제 #3
0
def test_payload_too_large(encoding, monkeypatch):
    SIZE = 1 << 12  # 4KB
    monkeypatch.setenv("DD_TRACE_API_VERSION", encoding)
    monkeypatch.setenv("DD_TRACE_WRITER_BUFFER_SIZE_BYTES", str(SIZE))
    monkeypatch.setenv("DD_TRACE_WRITER_MAX_PAYLOAD_SIZE_BYTES", str(SIZE))

    t = Tracer()
    assert t.writer._max_payload_size == SIZE
    assert t.writer._buffer_size == SIZE
    # Make sure a flush doesn't happen partway through.
    t.configure(
        writer=AgentWriter(agent.get_trace_url(), processing_interval=1000))
    with mock.patch("ddtrace.internal.writer.log") as log:
        for i in range(100000 if encoding == "v0.5" else 1000):
            with t.trace("operation") as s:
                s.set_tag(str(i), "b" * 190)
                s.set_tag(str(i), "a" * 190)

        t.shutdown()
        calls = [
            mock.call(
                "trace buffer (%s traces %db/%db) cannot fit trace of size %db, dropping",
                AnyInt(),
                AnyInt(),
                AnyInt(),
                AnyInt(),
            )
        ]
        log.warning.assert_has_calls(calls)
        log.error.assert_not_called()
예제 #4
0
 def _assert_bad_trace_refused_by_agent(self, mock_log):
     """Assert that agent refused a bad trace via log call."""
     calls = [
         mock.call(
             "failed to send traces to Datadog Agent at %s: HTTP error status %s, reason %s",
             agent.get_trace_url(),
             400,
             "Bad Request",
         )
     ]
     mock_log.error.assert_has_calls(calls)
예제 #5
0
def test_flush_log(caplog):
    caplog.set_level(logging.INFO)

    writer = AgentWriter(agent.get_trace_url())

    with mock.patch("ddtrace.internal.writer.log") as log:
        writer.write([])
        writer.flush_queue(raise_exc=True)
        calls = [
            mock.call(logging.DEBUG, "sent %s in %.5fs", AnyStr(), AnyFloat())
        ]
        log.log.assert_has_calls(calls)
예제 #6
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,
            ),
        ]
예제 #7
0
def test_flush_log(caplog, encoding, monkeypatch):
    monkeypatch.setenv("DD_TRACE_API_VERSION", encoding)

    caplog.set_level(logging.INFO)

    writer = AgentWriter(agent.get_trace_url())

    with mock.patch("ddtrace.internal.writer.log") as log:
        writer.write([])
        writer.flush_queue(raise_exc=True)
        calls = [
            mock.call(
                logging.DEBUG,
                "sent %s in %.5fs to %s",
                AnyStr(),
                AnyFloat(),
                writer.agent_url,
            )
        ]
        log.log.assert_has_calls(calls)
예제 #8
0
def test_payload_too_large():
    t = Tracer()
    # Make sure a flush doesn't happen partway through.
    t.configure(writer=AgentWriter(agent.get_trace_url(), processing_interval=1000))
    with mock.patch("ddtrace.internal.writer.log") as log:
        for i in range(100000):
            with t.trace("operation") as s:
                s.set_tag(str(i), "b" * 190)
                s.set_tag(str(i), "a" * 190)

        t.shutdown()
        calls = [
            mock.call(
                "trace buffer (%s traces %db/%db) cannot fit trace of size %db, dropping",
                AnyInt(),
                AnyInt(),
                AnyInt(),
                AnyInt(),
            )
        ]
        log.warning.assert_has_calls(calls)
        log.error.assert_not_called()
예제 #9
0
def test_flush_log(caplog, encoding, monkeypatch):
    monkeypatch.setenv("DD_TRACE_API_VERSION", encoding)

    caplog.set_level(logging.INFO)

    writer = AgentWriter(agent.get_trace_url())

    with mock.patch("ddtrace.internal.writer.log") as log:
        writer.write([])
        writer.flush_queue(raise_exc=True)
        # for latest agent, default to v0.3 since no priority sampler is set
        expected_encoding = "v0.3" if AGENT_VERSION == "v5" else (encoding
                                                                  or "v0.3")
        calls = [
            mock.call(
                logging.DEBUG,
                "sent %s in %.5fs to %s",
                AnyStr(),
                AnyFloat(),
                "{}/{}/traces".format(writer.agent_url, expected_encoding),
            )
        ]
        log.log.assert_has_calls(calls)
예제 #10
0
def test_trace_url(monkeypatch, mocker):
    mock_exists = mocker.patch("os.path.exists")

    # with nothing set by user, and the default UDS available, we choose UDS
    mock_exists.return_value = True
    assert agent.get_trace_url() == "unix:///var/run/datadog/apm.socket"
    mock_exists.assert_called_once_with("/var/run/datadog/apm.socket")
    mock_exists.reset_mock()

    # with nothing set by user, and the default UDS unavailable, we choose default http address
    mock_exists.return_value = False
    assert agent.get_trace_url() == "http://localhost:8126"
    mock_exists.assert_called_once_with("/var/run/datadog/apm.socket")
    mock_exists.reset_mock()

    # with port set by user, and default UDS unavailable, we choose user settings
    with monkeypatch.context() as m:
        m.setenv("DD_TRACE_AGENT_PORT", "1235")
        assert agent.get_trace_url() == "http://localhost:1235"
        mock_exists.assert_not_called()

    # with host set by user, and default UDS unavailable, we choose user settings
    with monkeypatch.context() as m:
        m.setenv("DD_AGENT_HOST", "mars")
        assert agent.get_trace_url() == "http://mars:8126"
        mock_exists.assert_not_called()

    # with host and port set by user, and default UDS unavailable, we choose user settings
    with monkeypatch.context() as m:
        m.setenv("DD_TRACE_AGENT_PORT", "1235")
        m.setenv("DD_AGENT_HOST", "mars")
        assert agent.get_trace_url() == "http://mars:1235"
        mock_exists.assert_not_called()

    # with port set by user, and default UDS available, we choose user settings
    mock_exists.return_value = True

    with monkeypatch.context() as m:
        m.setenv("DD_TRACE_AGENT_PORT", "1235")
        assert agent.get_trace_url() == "http://localhost:1235"
        mock_exists.assert_not_called()

    # with host set by user, and default UDS available, we choose user settings
    with monkeypatch.context() as m:
        m.setenv("DD_AGENT_HOST", "mars")
        assert agent.get_trace_url() == "http://mars:8126"
        mock_exists.assert_not_called()

    # with host and port set by user, and default UDS available, we choose user settings
    with monkeypatch.context() as m:
        m.setenv("DD_TRACE_AGENT_PORT", "1235")
        m.setenv("DD_AGENT_HOST", "mars")
        assert agent.get_trace_url() == "http://mars:1235"
        mock_exists.assert_not_called()

    # with port, host, and url set by user, and default UDS available, we choose url
    with monkeypatch.context() as m:
        m.setenv("DD_TRACE_AGENT_PORT", "1235")
        m.setenv("DD_AGENT_HOST", "mars")
        m.setenv("DD_TRACE_AGENT_URL", "http://saturn:1111")
        assert agent.get_trace_url() == "http://saturn:1111"
        mock_exists.assert_not_called()

    # with port, host, and url set by user, and default UDS unavailable, we choose url
    mock_exists.return_value = False

    with monkeypatch.context() as m:
        m.setenv("DD_TRACE_AGENT_PORT", "1235")
        m.setenv("DD_AGENT_HOST", "mars")
        m.setenv("DD_TRACE_AGENT_URL", "http://saturn:1111")
        assert agent.get_trace_url() == "http://saturn:1111"
        mock_exists.assert_not_called()