def test_debug_post_configure(): tracer = ddtrace.Tracer() tracer.configure( hostname="0.0.0.0", port=1234, priority_sampling=True, ) f = debug.collect(tracer) agent_url = f.get("agent_url") assert agent_url == "http://0.0.0.0:1234" assert f.get("is_global_tracer") is False assert f.get("tracer_enabled") is True agent_error = f.get("agent_error") # Error code can differ between Python version assert re.match("^Agent not reachable.*Connection refused", agent_error) # Tracer doesn't support re-configure()-ing with a UDS after an initial # configure with normal http settings. So we need a new tracer instance. tracer = ddtrace.Tracer() tracer.configure(uds_path="/file.sock") f = debug.collect(tracer) agent_url = f.get("agent_url") assert agent_url == "unix:///file.sock" agent_error = f.get("agent_error") assert re.match("^Agent not reachable.*No such file or directory", agent_error)
def test_startup_logs_sampling_rules(): tracer = ddtrace.Tracer() sampler = ddtrace.sampler.DatadogSampler(rules=[ddtrace.sampler.SamplingRule(sample_rate=1.0)]) tracer.configure(sampler=sampler) f = debug.collect(tracer) assert f.get("sampler_rules") == ["SamplingRule(sample_rate=1.0, service='NO_RULE', name='NO_RULE')"] sampler = ddtrace.sampler.DatadogSampler( rules=[ddtrace.sampler.SamplingRule(sample_rate=1.0, service="xyz", name="abc")] ) tracer.configure(sampler=sampler) f = debug.collect(tracer) assert f.get("sampler_rules") == ["SamplingRule(sample_rate=1.0, service='xyz', name='abc')"]
def test_partial_flush_log(run_python_code_in_subprocess): tracer = ddtrace.Tracer() tracer.configure( partial_flush_enabled=True, partial_flush_min_spans=300, ) f = debug.collect(tracer) partial_flush_enabled = f.get("partial_flush_enabled") partial_flush_min_spans = f.get("partial_flush_min_spans") assert partial_flush_enabled is True assert partial_flush_min_spans == 300 partial_flush_min_spans = "2" env = os.environ.copy() env["DD_TRACER_PARTIAL_FLUSH_ENABLED"] = "true" env["DD_TRACER_PARTIAL_FLUSH_MIN_SPANS"] = partial_flush_min_spans out, err, status, pid = run_python_code_in_subprocess( """ from ddtrace import tracer print(tracer._partial_flush_enabled) assert tracer._partial_flush_enabled == True assert tracer._partial_flush_min_spans == 2 """, env=env, ) assert status == 0, (out, err)
def test_partial_flush_log(): tracer = ddtrace.Tracer() tracer.configure( partial_flush_enabled=True, partial_flush_min_spans=300, ) f = debug.collect(tracer) partial_flush_enabled = f.get("partial_flush_enabled") partial_flush_min_spans = f.get("partial_flush_min_spans") assert partial_flush_enabled is True assert partial_flush_min_spans == 300
def test_env_config(self): f = debug.collect(ddtrace.tracer) assert f.get("agent_url") == "http://0.0.0.0:4321" assert f.get("analytics_enabled") is True assert f.get("health_metrics_enabled") is True assert f.get("log_injection_enabled") is True assert f.get("priority_sampling_enabled") is True assert f.get("env") == "prod" assert f.get("dd_version") == "123456" assert f.get("service") == "service" assert f.get("global_tags") == "k1:v1,k2:v2" assert f.get("tracer_tags") in ["k1:v1,k2:v2", "k2:v2,k1:v1"] assert f.get("tracer_enabled") is True icfg = f.get("integrations") assert icfg["django"] == "N/A"
def test_custom_writer(): tracer = ddtrace.Tracer() class CustomWriter(TraceWriter): def recreate(self): # type: () -> TraceWriter return self def stop(self, timeout=None): # type: (Optional[float]) -> None pass def write(self, spans=None): # type: (Optional[List[Span]]) -> None pass tracer.writer = CustomWriter() info = debug.collect(tracer) assert info.get("agent_url") == "CUSTOM"
def main(): parser = argparse.ArgumentParser( description=USAGE, prog="ddtrace-run", usage="ddtrace-run <your usual python command>", formatter_class=argparse.RawTextHelpFormatter, ) parser.add_argument("command", nargs=argparse.REMAINDER, type=str, help="Command string to execute.") parser.add_argument("-d", "--debug", help="enable debug mode (disabled by default)", action="store_true") parser.add_argument("-i", "--info", help="print library info useful for debugging", action="store_true") parser.add_argument("-p", "--profiling", help="enable profiling (disabled by default)", action="store_true") parser.add_argument("-v", "--version", action="version", version="%(prog)s " + ddtrace.__version__) args = parser.parse_args() if args.profiling: os.environ["DD_PROFILING_ENABLED"] = "true" debug_mode = args.debug or asbool(get_env("trace", "debug", default=False)) if debug_mode: logging.basicConfig(level=logging.DEBUG) os.environ["DD_TRACE_DEBUG"] = "true" if args.info: # Inline imports for performance. import pprint from ddtrace.internal.debug import collect pprint.pprint(collect(ddtrace.tracer)) sys.exit(0) root_dir = os.path.dirname(ddtrace.__file__) log.debug("ddtrace root: %s", root_dir) bootstrap_dir = os.path.join(root_dir, "bootstrap") log.debug("ddtrace bootstrap: %s", bootstrap_dir) _add_bootstrap_to_pythonpath(bootstrap_dir) log.debug("PYTHONPATH: %s", os.environ["PYTHONPATH"]) log.debug("sys.path: %s", sys.path) if not args.command: parser.print_help() sys.exit(1) # Find the executable path executable = spawn.find_executable(args.command[0]) if not executable: print("ddtrace-run: failed to find executable '%s'.\n" % args.command[0]) parser.print_usage() sys.exit(1) log.debug("program executable: %s", executable) if os.path.basename(executable) == "uwsgi": print(( "ddtrace-run has known compatibility issues with uWSGI where the " "tracer is not started properly in uWSGI workers which can cause " "broken behavior. It is recommended you remove ddtrace-run and " "update your uWSGI configuration following " "https://ddtrace.readthedocs.io/en/stable/advanced_usage.html#uwsgi." )) try: # Raises OSError for permissions errors in Python 2 # PermissionError for Python 3 os.execl(executable, executable, *args.command[1:]) except (OSError, PermissionError): print( "ddtrace-run: executable '%s' does not have executable permissions.\n" % executable) parser.print_usage() sys.exit(1) sys.exit(0)
def test_standard_tags(): f = debug.collect(ddtrace.tracer) date = f.get("date") assert isinstance(date, str) if sys.version_info >= (3, 7, 0): # Try to parse the date-time, only built-in way to parse # available in Python 3.7+ date = datetime.fromisoformat(date) os_name = f.get("os_name") assert isinstance(os_name, str) os_version = f.get("os_version") assert isinstance(os_version, str) is_64_bit = f.get("is_64_bit") assert isinstance(is_64_bit, bool) arch = f.get("architecture") assert isinstance(arch, str) vm = f.get("vm") assert isinstance(vm, str) pip_version = f.get("pip_version") assert isinstance(pip_version, str) version = f.get("version") assert isinstance(version, str) lang = f.get("lang") assert lang == "python" in_venv = f.get("in_virtual_env") assert in_venv is True lang_version = f.get("lang_version") if sys.version_info == (3, 7, 0): assert "3.7" in lang_version elif sys.version_info == (3, 6, 0): assert "3.6" in lang_version elif sys.version_info == (2, 7, 0): assert "2.7" in lang_version agent_url = f.get("agent_url") assert agent_url == "http://localhost:8126" assert "agent_error" in f agent_error = f.get("agent_error") assert agent_error is None assert f.get("env") == "" assert f.get("is_global_tracer") is True assert f.get("tracer_enabled") is True assert f.get("sampler_type") == "DatadogSampler" assert f.get("priority_sampler_type") == "RateByServiceSampler" assert f.get("service") == "" assert f.get("dd_version") == "" assert f.get("debug") is False assert f.get("enabled_cli") is False assert f.get("analytics_enabled") is False assert f.get("log_injection_enabled") is False assert f.get("health_metrics_enabled") is False assert f.get("priority_sampling_enabled") is True assert f.get("global_tags") == "" assert f.get("tracer_tags") == "" icfg = f.get("integrations") assert icfg["django"] == "N/A" assert icfg["flask"] == "N/A"
def test_different_samplers(): tracer = ddtrace.Tracer() tracer.configure(sampler=ddtrace.sampler.RateSampler()) info = debug.collect(tracer) assert info.get("sampler_type") == "RateSampler"
def test_agentless(monkeypatch): monkeypatch.setenv("AWS_LAMBDA_FUNCTION_NAME", "something") tracer = ddtrace.Tracer() info = debug.collect(tracer) assert info.get("agent_url") == "AGENTLESS"
def test_to_json(): info = debug.collect(ddtrace.tracer) json.dumps(info)
def test_trace_agent_url(self): f = debug.collect(ddtrace.tracer) assert f.get("agent_url") == "http://0.0.0.0:1234"