Skip to content

Commit

Permalink
Disable crashtracking
Browse files Browse the repository at this point in the history
  • Loading branch information
sanchda committed Oct 2, 2024
1 parent 099ab94 commit b6d9eb7
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 27 deletions.
37 changes: 24 additions & 13 deletions ddtrace/internal/core/crashtracking.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,49 @@
from typing import Callable

from ddtrace import config
from ddtrace import version
from ddtrace.internal import agent
from ddtrace.internal.datadog.profiling import crashtracker
from ddtrace.internal.runtime import get_runtime_id
from ddtrace.internal.runtime import on_runtime_id_change
from ddtrace.settings.crashtracker import config as crashtracker_config


is_available: bool = crashtracker.is_available
failure_msg: str = crashtracker.failure_msg
is_started: Callable[[], bool] = crashtracker.is_started
is_enabled_and_available = False
if crashtracker_config.enabled:
try:
from ddtrace.internal.datadog.profiling import crashtracker

is_enabled_and_available = crashtracker.is_available
except ImportError:
is_enabled_and_available = False


# DEV crashtracker was once loaded and enabled by default everywhere, but due to consequences of running long-running
# child processes, it has been disabled by default. Hoping to reenable it soon. Pushing the module imports down
# into individual functions is not a design requirement, but rather a way to avoid loading the module until needed.


@on_runtime_id_change
def _update_runtime_id(runtime_id: str) -> None:
crashtracker.set_runtime_id(runtime_id)
if is_enabled_and_available:
from ddtrace.internal.datadog.profiling import crashtracker

crashtracker.set_runtime_id(runtime_id)


def add_tag(key: str, value: str) -> None:
if is_available:
if is_enabled_and_available:
from ddtrace.internal.datadog.profiling import crashtracker

crashtracker.set_tag(key, value)


def start() -> bool:
if not is_available:
if not is_enabled_and_available:
return False

import platform

from ddtrace.internal.datadog.profiling import crashtracker

crashtracker.set_url(crashtracker_config.debug_url or agent.get_trace_url())
crashtracker.set_service(config.service)
crashtracker.set_version(config.version)
Expand Down Expand Up @@ -57,7 +71,4 @@ def start() -> bool:
for key, value in crashtracker_config.tags.items():
add_tag(key, value)

# Only start if it is enabled
if crashtracker_config.enabled:
return crashtracker.start()
return False
return crashtracker.start()
32 changes: 18 additions & 14 deletions tests/internal/crashtracker/test_crashtracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_available():
import ddtrace.internal.datadog.profiling.crashtracker as crashtracker

assert crashtracker.is_available


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_config():
import pytest

Expand All @@ -29,7 +29,7 @@ def test_crashtracker_config():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_config_bytes():
import pytest

Expand Down Expand Up @@ -58,7 +58,7 @@ def test_crashtracker_config_bytes():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_started():
import pytest

Expand All @@ -79,7 +79,7 @@ def test_crashtracker_started():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_simple():
# This test does the following
# 1. Finds a random port in the range 10000-20000 it can bind to (5 retries)
Expand Down Expand Up @@ -122,7 +122,7 @@ def test_crashtracker_simple():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_simple_fork():
# This is similar to the simple test, except crashtracker initialization is done
# in the parent
Expand Down Expand Up @@ -158,7 +158,7 @@ def test_crashtracker_simple_fork():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_simple_sigbus():
# This is similar to the simple fork test, except instead of raising a SIGSEGV,
# it organically raises a real SIGBUS.
Expand Down Expand Up @@ -214,7 +214,7 @@ def test_crashtracker_simple_sigbus():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_raise_sigsegv():
import os
import signal
Expand Down Expand Up @@ -247,7 +247,7 @@ def test_crashtracker_raise_sigsegv():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_raise_sigbus():
import os
import signal
Expand Down Expand Up @@ -295,6 +295,7 @@ def test_crashtracker_preload_default(ddtrace_run_python_code_in_subprocess):
# Call the program
env = os.environ.copy()
env["DD_TRACE_AGENT_URL"] = "http://localhost:%d" % port
env["DD_CRASHTRACKING_ENABLED"] = "true"
stdout, stderr, exitcode, _ = ddtrace_run_python_code_in_subprocess(preload_code, env=env)

# Check for expected exit condition
Expand All @@ -320,7 +321,7 @@ def test_crashtracker_preload_disabled(ddtrace_run_python_code_in_subprocess):
# Call the program
env = os.environ.copy()
env["DD_TRACE_AGENT_URL"] = "http://localhost:%d" % port
env["DD_CRASHTRACKING_ENABLED"] = "false"
env["DD_CRASHTRACKING_ENABLED"] = "true"
stdout, stderr, exitcode, _ = ddtrace_run_python_code_in_subprocess(preload_code, env=env)

# Check for expected exit condition
Expand All @@ -342,14 +343,15 @@ def test_crashtracker_preload_disabled(ddtrace_run_python_code_in_subprocess):


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
def test_crashtracker_auto_default(run_python_code_in_subprocess):
def test_crashtracker_auto_enabled(run_python_code_in_subprocess):
# Setup the listening socket before we open ddtrace
port, sock = utils.crashtracker_receiver_bind()
assert sock

# Call the program
env = os.environ.copy()
env["DD_TRACE_AGENT_URL"] = "http://localhost:%d" % port
env["DD_CRASHTRACKING_ENABLED"] = "true"
stdout, stderr, exitcode, _ = run_python_code_in_subprocess(auto_code, env=env)

# Check for expected exit condition
Expand All @@ -376,6 +378,7 @@ def test_crashtracker_auto_nostack(run_python_code_in_subprocess):
env = os.environ.copy()
env["DD_TRACE_AGENT_URL"] = "http://localhost:%d" % port
env["DD_CRASHTRACKING_STACKTRACE_RESOLVER"] = "none"
env["DD_CRASHTRACKING_ENABLED"] = "true"
stdout, stderr, exitcode, _ = run_python_code_in_subprocess(auto_code, env=env)

# Check for expected exit condition
Expand Down Expand Up @@ -415,7 +418,7 @@ def test_crashtracker_auto_disabled(run_python_code_in_subprocess):


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_tags_required():
# Tests tag ingestion in the core API
import ctypes
Expand Down Expand Up @@ -462,6 +465,7 @@ def test_crashtracker_user_tags_envvar(run_python_code_in_subprocess):
# Call the program
env = os.environ.copy()
env["DD_TRACE_AGENT_URL"] = "http://localhost:%d" % port
env["DD_CRASHTRACKING_ENABLED"] = "true"

# Injecting tags, but since the way we validate them is with a raw-data string search, we make things unique
tag_prefix = "cryptocrystalline"
Expand Down Expand Up @@ -490,7 +494,7 @@ def test_crashtracker_user_tags_envvar(run_python_code_in_subprocess):


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_user_tags_profiling():
# Tests tag ingestion in the backend API (which is currently out of profiling)
import ctypes
Expand Down Expand Up @@ -536,7 +540,7 @@ def test_crashtracker_user_tags_profiling():


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
@pytest.mark.subprocess()
@pytest.mark.subprocess(env={"DD_CRASHTRACKING_ENABLED": "true"})
def test_crashtracker_user_tags_core():
# Tests tag ingestion in the core API
import ctypes
Expand Down

0 comments on commit b6d9eb7

Please sign in to comment.