Skip to content

Commit afb4141

Browse files
fix(tracing): disallow v0.5 api usage for windows machines (backports #4830 to 1.7) (#4837)
Backports: #4830 Co-authored-by: Brett Langdon <[email protected]>
1 parent 505fcd1 commit afb4141

File tree

3 files changed

+115
-2
lines changed

3 files changed

+115
-2
lines changed

ddtrace/internal/writer.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,26 @@ def __init__(
279279
if headers:
280280
self._headers.update(headers)
281281
self._timeout = timeout
282+
283+
# Default to v0.4 if we are on Windows since there is a known compatibility issue
284+
# https://github.com/DataDog/dd-trace-py/issues/4829
285+
# DEV: sys.platform on windows should be `win32` or `cygwin`, but using `startswith`
286+
# as a safety precaution.
287+
# https://docs.python.org/3/library/sys.html#sys.platform
288+
is_windows = sys.platform.startswith("win") or sys.platform.startswith("cygwin")
289+
default_api_version = "v0.4" if is_windows else "v0.5"
290+
282291
self._api_version = (
283-
api_version or os.getenv("DD_TRACE_API_VERSION") or ("v0.5" if priority_sampler is not None else "v0.3")
292+
api_version
293+
or os.getenv("DD_TRACE_API_VERSION")
294+
or (default_api_version if priority_sampler is not None else "v0.3")
284295
)
296+
if is_windows and self._api_version == "v0.5":
297+
raise RuntimeError(
298+
"There is a known compatibiltiy issue with v0.5 API and Windows, "
299+
"please see https://github.com/DataDog/dd-trace-py/issues/4829 for more details."
300+
)
301+
285302
try:
286303
Encoder = MSGPACK_ENCODERS[self._api_version]
287304
except KeyError:
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
---
22
upgrade:
33
- |
4-
tracing: upgrades the default trace API version to ``v0.5``. The ``v0.5`` trace API version generates
4+
tracing: upgrades the default trace API version to ``v0.5`` for non-Windows systems. The ``v0.5`` trace API version generates
55
smaller payloads, thus increasing the throughput to the Datadog agent especially with larger traces.
6+
- |
7+
tracing: configuring the ``v0.5`` trace API version on Windows machines will raise a ``RuntimeError``
8+
due to known compatibility issues. Please see https://github.com/DataDog/dd-trace-py/issues/4829 for more details.

tests/tracer/test_writer.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import contextlib
12
import os
23
import socket
4+
import sys
35
import tempfile
46
import threading
57
import time
@@ -20,12 +22,23 @@
2022
from ddtrace.internal.writer import LogWriter
2123
from ddtrace.internal.writer import Response
2224
from ddtrace.internal.writer import _human_size
25+
from ddtrace.sampler import RateByServiceSampler
2326
from ddtrace.span import Span
2427
from tests.utils import AnyInt
2528
from tests.utils import BaseTestCase
2629
from tests.utils import override_env
2730

2831

32+
@contextlib.contextmanager
33+
def mock_sys_platform(new_value):
34+
old_value = sys.platform
35+
try:
36+
sys.platform = new_value
37+
yield
38+
finally:
39+
sys.platform = old_value
40+
41+
2942
class DummyOutput:
3043
def __init__(self):
3144
self.entries = []
@@ -552,6 +565,86 @@ def test_writer_recreate_api_version(init_api_version, api_version, endpoint, en
552565
assert isinstance(writer._encoder, encoder_cls)
553566

554567

568+
@pytest.mark.parametrize(
569+
"sys_platform, api_version, ddtrace_api_version, priority_sampler, raises_error, expected",
570+
[
571+
# -- win32
572+
# Defaults on windows
573+
("win32", None, None, None, False, "v0.3"),
574+
# Default with priority sampler
575+
("win32", None, None, RateByServiceSampler(), False, "v0.4"),
576+
# Explicitly passed in API version is always used
577+
("win32", "v0.3", None, RateByServiceSampler(), False, "v0.3"),
578+
("win32", "v0.3", "v0.4", None, False, "v0.3"),
579+
("win32", "v0.3", "v0.4", RateByServiceSampler(), False, "v0.3"),
580+
# Env variable is used if explicit value is not given
581+
("win32", None, "v0.4", None, False, "v0.4"),
582+
("win32", None, "v0.4", RateByServiceSampler(), False, "v0.4"),
583+
# v0.5 is not supported on windows
584+
("win32", "v0.5", None, None, True, None),
585+
("win32", "v0.5", None, RateByServiceSampler(), True, None),
586+
("win32", "v0.5", "v0.4", RateByServiceSampler(), True, None),
587+
("win32", None, "v0.5", RateByServiceSampler(), True, None),
588+
# -- cygwin
589+
# Defaults on windows
590+
("cygwin", None, None, None, False, "v0.3"),
591+
# Default with priority sampler
592+
("cygwin", None, None, RateByServiceSampler(), False, "v0.4"),
593+
# Explicitly passed in API version is always used
594+
("cygwin", "v0.3", None, RateByServiceSampler(), False, "v0.3"),
595+
("cygwin", "v0.3", "v0.4", None, False, "v0.3"),
596+
("cygwin", "v0.3", "v0.4", RateByServiceSampler(), False, "v0.3"),
597+
# Env variable is used if explicit value is not given
598+
("cygwin", None, "v0.4", None, False, "v0.4"),
599+
("cygwin", None, "v0.4", RateByServiceSampler(), False, "v0.4"),
600+
# v0.5 is not supported on windows
601+
("cygwin", "v0.5", None, None, True, None),
602+
("cygwin", "v0.5", None, RateByServiceSampler(), True, None),
603+
("cygwin", "v0.5", "v0.4", RateByServiceSampler(), True, None),
604+
("cygwin", None, "v0.5", RateByServiceSampler(), True, None),
605+
# -- Non-windows
606+
# defaults
607+
("darwin", None, None, None, False, "v0.3"),
608+
# Default with priority sample
609+
("darwin", None, None, RateByServiceSampler(), False, "v0.5"),
610+
# Explicitly setting api version
611+
("darwin", "v0.4", None, RateByServiceSampler(), False, "v0.4"),
612+
# Explicitly set version takes precedence
613+
("darwin", "v0.4", "v0.5", RateByServiceSampler(), False, "v0.4"),
614+
# Via env variable
615+
("darwin", None, "v0.4", RateByServiceSampler(), False, "v0.4"),
616+
("darwin", None, "v0.5", RateByServiceSampler(), False, "v0.5"),
617+
],
618+
)
619+
def test_writer_api_version_selection(
620+
sys_platform, api_version, ddtrace_api_version, priority_sampler, raises_error, expected, monkeypatch
621+
):
622+
"""test to verify that we are unable to select v0.5 api version when on a windows machine.
623+
624+
https://docs.python.org/3/library/sys.html#sys.platform
625+
626+
The possible ``sys.platform`` values when on windows are ``win32`` or ``cygwin``.
627+
"""
628+
629+
# Mock the value of `sys.platform` to be a specific value
630+
with mock_sys_platform(sys_platform):
631+
632+
# If desired, set the DD_TRACE_API_VERSION env variable
633+
if ddtrace_api_version is not None:
634+
monkeypatch.setenv("DD_TRACE_API_VERSION", ddtrace_api_version)
635+
636+
try:
637+
# Create a new writer
638+
writer = AgentWriter(
639+
agent_url="http://dne:1234", api_version=api_version, priority_sampler=priority_sampler
640+
)
641+
assert writer._api_version == expected
642+
except RuntimeError:
643+
# If we were not expecting a RuntimeError, then cause the test to fail
644+
if not raises_error:
645+
pytest.fail("Raised RuntimeError when it was not expected")
646+
647+
555648
def test_writer_reuse_connections_envvar(monkeypatch):
556649
monkeypatch.setenv("DD_TRACE_WRITER_REUSE_CONNECTIONS", "false")
557650
writer = AgentWriter(agent_url="http://localhost:9126")

0 commit comments

Comments
 (0)