示例#1
0
 def test_get_env(self):
     # ensure `get_env` returns a default value if environment variables
     # are not set
     value = get_env('django', 'distributed_tracing')
     ok_(value is None)
     value = get_env('django', 'distributed_tracing', False)
     ok_(value is False)
示例#2
0
 def test_get_env(self):
     # ensure `get_env` returns a default value if environment variables
     # are not set
     value = get_env("django", "distributed_tracing")
     self.assertIsNone(value)
     value = get_env("django", "distributed_tracing", default=False)
     self.assertFalse(value)
示例#3
0
 def test_get_env(self):
     # ensure `get_env` returns a default value if environment variables
     # are not set
     value = get_env('django', 'distributed_tracing')
     ok_(value is None)
     value = get_env('django', 'distributed_tracing', False)
     ok_(value is False)
示例#4
0
def get_stats_url():
    # type: () -> str
    return get_env("dogstatsd",
                   "url",
                   default="udp://{}:{}".format(
                       get_hostname(),
                       get_stats_port()))  # type: ignore[return-value]
示例#5
0
def get_trace_agent_timeout():
    # type: () -> float
    return float(
        get_env("trace",
                "agent",
                "timeout",
                "seconds",
                default=DEFAULT_TIMEOUT))  # type: ignore[arg-type]
示例#6
0
 def test_get_env_found_legacy(self):
     # ensure `get_env` returns a value if legacy environment variables
     # are used, raising a Deprecation warning
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter('always')
         os.environ['DATADOG_REQUESTS_DISTRIBUTED_TRACING'] = '1'
         value = get_env('requests', 'distributed_tracing')
         eq_(value, '1')
         ok_(len(w) == 1)
         ok_(issubclass(w[-1].category, DeprecationWarning))
         ok_('Use `DD_` prefix instead' in str(w[-1].message))
示例#7
0
 def test_get_env_found_legacy(self):
     # ensure `get_env` returns a value if legacy environment variables
     # are used, raising a Deprecation warning
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter('always')
         os.environ['DATADOG_REQUESTS_DISTRIBUTED_TRACING'] = '1'
         value = get_env('requests', 'distributed_tracing')
         eq_(value, '1')
         ok_(len(w) == 1)
         ok_(issubclass(w[-1].category, DeprecationWarning))
         ok_('Use `DD_` prefix instead' in str(w[-1].message))
示例#8
0
 def test_get_env_found_legacy(self):
     # ensure `get_env` returns a value if legacy environment variables
     # are used, raising a Deprecation warning
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter("always")
         os.environ["DATADOG_REQUESTS_DISTRIBUTED_TRACING"] = "1"
         value = get_env("requests", "distributed_tracing")
         self.assertEqual(value, "1")
         self.assertEqual(len(w), 1)
         self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
         self.assertTrue("Use `DD_` prefix instead" in str(w[-1].message))
示例#9
0
def get_stats_url():
    # type: () -> str
    user_supplied_host = get_stats_hostname(None) is not None
    user_supplied_port = get_stats_port(None) is not None

    url = get_env("dogstatsd", "url", default=None)

    if not url:
        if user_supplied_host or user_supplied_port:
            url = "udp://{}:{}".format(get_stats_hostname(), get_stats_port())
        elif os.path.exists("/var/run/datadog/dsd.socket"):
            url = "unix://%s" % (DEFAULT_UNIX_DSD_PATH)
        else:
            url = "udp://{}:{}".format(get_stats_hostname(), get_stats_port())
    return url
示例#10
0
 def test_get_env_key_priority(self):
     # ensure `get_env` use `DD_` with highest priority
     os.environ['DD_REQUESTS_DISTRIBUTED_TRACING'] = 'highest'
     os.environ['DATADOG_REQUESTS_DISTRIBUTED_TRACING'] = 'lowest'
     value = get_env('requests', 'distributed_tracing')
     self.assertEqual(value, 'highest')
示例#11
0
 def test_get_env_long(self):
     os.environ['DD_SOME_VERY_LONG_TEST_KEY'] = '1'
     value = get_env('some', 'very', 'long', 'test', 'key', default='2')
     assert value == '1'
示例#12
0
 def test_get_env_found(self):
     # ensure `get_env` returns a value if the environment variable is set
     os.environ['DD_REQUESTS_DISTRIBUTED_TRACING'] = '1'
     value = get_env('requests', 'distributed_tracing')
     self.assertEqual(value, '1')
示例#13
0
from ddtrace import Pin
from ddtrace import config
from ddtrace.contrib.dbapi import TracedConnection
from ddtrace.ext import db
from ddtrace.ext import net
from ddtrace.utils.formats import asbool
from ddtrace.utils.formats import get_env
from ddtrace.utils.wrappers import unwrap
from ddtrace.vendor import wrapt

config._add(
    "mariadb",
    dict(
        trace_fetch_methods=asbool(
            get_env("mariadb", "trace_fetch_methods", default=False)),
        _default_service="mariadb",
    ),
)


def patch():
    if getattr(mariadb, "_datadog_patch", False):
        return
    setattr(mariadb, "_datadog_patch", True)
    wrapt.wrap_function_wrapper("mariadb", "connect", _connect)


def unpatch():
    if getattr(mariadb, "_datadog_patch", False):
        setattr(mariadb, "_datadog_patch", False)
示例#14
0
from ddtrace.internal.logger import get_logger
from ddtrace.propagation.http import HTTPPropagator
from ddtrace.utils.formats import asbool, get_env
from ddtrace.utils.wrappers import unwrap, iswrapped

from .compat import get_resolver, user_is_authenticated
from . import utils, conf

wrap = wrapt.wrap_function_wrapper
log = get_logger(__name__)

config._add(
    "django",
    dict(
        service_name=config._get_service(default="django"),
        cache_service_name=get_env("django", "cache_service_name") or "django",
        database_service_name_prefix=get_env("django",
                                             "database_service_name_prefix",
                                             default=""),
        distributed_tracing_enabled=True,
        instrument_middleware=asbool(
            get_env("django", "instrument_middleware", default=True)),
        instrument_databases=True,
        instrument_caches=True,
        analytics_enabled=
        None,  # None allows the value to be overridden by the global config
        analytics_sample_rate=None,
        trace_query_string=None,  # Default to global config
        include_user_name=True,
    ),
)
示例#15
0
 def test_get_env_found(self):
     # ensure `get_env` returns a value if the environment variable is set
     os.environ["DD_REQUESTS_DISTRIBUTED_TRACING"] = "1"
     value = get_env("requests", "distributed_tracing")
     self.assertEqual(value, "1")
示例#16
0
try:
    from ddtrace import tracer

    # Respect DATADOG_* environment variables in global tracer configuration
    # TODO: these variables are deprecated; use utils method and update our documentation
    # correct prefix should be DD_*
    hostname = os.environ.get("DD_AGENT_HOST",
                              os.environ.get("DATADOG_TRACE_AGENT_HOSTNAME"))
    port = os.environ.get("DATADOG_TRACE_AGENT_PORT")
    priority_sampling = os.environ.get("DATADOG_PRIORITY_SAMPLING")
    profiling = asbool(os.environ.get("DD_PROFILING_ENABLED", False))

    if profiling:
        import ddtrace.profiling.auto  # noqa: F401

    if asbool(get_env("runtime_metrics", "enabled")):
        RuntimeWorker.enable()

    opts = {}

    if asbool(os.environ.get("DATADOG_TRACE_ENABLED", True)):
        patch = True
    else:
        patch = False
        opts["enabled"] = False

    if hostname:
        opts["hostname"] = hostname
    if port:
        opts["port"] = int(port)
    if priority_sampling:
示例#17
0
import logging

import wrapt

from ddtrace import Pin
from ddtrace.ext import AppTypes, sql
from ddtrace.settings import config
from ddtrace.utils.formats import asbool, get_env

log = logging.getLogger(__name__)

config._add(
    'dbapi2',
    dict(trace_fetch_methods=asbool(
        get_env('dbapi2', 'trace_fetch_methods', 'false')), ))


class TracedCursor(wrapt.ObjectProxy):
    """ TracedCursor wraps a psql cursor and traces it's queries. """
    def __init__(self, cursor, pin):
        super(TracedCursor, self).__init__(cursor)
        pin.onto(self)
        name = pin.app or 'sql'
        self._self_datadog_name = '{}.query'.format(name)
        self._self_last_execute_operation = None

    def _trace_method(self, method, name, resource, extra_tags, *args,
                      **kwargs):
        """
        Internal function to trace the call to the underlying cursor method
示例#18
0
from ddtrace.vendor import wrapt

from . import conf
from . import utils
from .. import trace_utils
from .compat import get_resolver
from .compat import user_is_authenticated


log = get_logger(__name__)

config._add(
    "django",
    dict(
        _default_service="django",
        cache_service_name=get_env("django", "cache_service_name") or "django",
        database_service_name_prefix=get_env("django", "database_service_name_prefix", default=""),
        database_service_name=get_env("django", "database_service_name", default=""),
        trace_fetch_methods=asbool(get_env("django", "trace_fetch_methods", default=False)),
        distributed_tracing_enabled=True,
        instrument_middleware=asbool(get_env("django", "instrument_middleware", default=True)),
        instrument_databases=True,
        instrument_caches=True,
        analytics_enabled=None,  # None allows the value to be overridden by the global config
        analytics_sample_rate=None,
        trace_query_string=None,  # Default to global config
        include_user_name=True,
        use_handler_resource_format=asbool(get_env("django", "use_handler_resource_format", default=False)),
        use_legacy_resource_format=asbool(get_env("django", "use_legacy_resource_format", default=False)),
    ),
)
示例#19
0
 def test_get_env_key_priority(self):
     # ensure `get_env` use `DD_` with highest priority
     os.environ["DD_REQUESTS_DISTRIBUTED_TRACING"] = "highest"
     os.environ["DATADOG_REQUESTS_DISTRIBUTED_TRACING"] = "lowest"
     value = get_env("requests", "distributed_tracing")
     self.assertEqual(value, "highest")
示例#20
0
from ddtrace.internal.logger import get_logger
from ddtrace.propagation.http import HTTPPropagator
from ddtrace.propagation.utils import from_wsgi_header
from ddtrace.utils.formats import asbool, get_env

from .. import trace_utils
from .compat import get_resolver, user_is_authenticated
from . import utils, conf

log = get_logger(__name__)

config._add(
    "django",
    dict(
        _default_service="django",
        cache_service_name=get_env("django", "cache_service_name") or "django",
        database_service_name_prefix=get_env("django",
                                             "database_service_name_prefix",
                                             default=""),
        database_service_name=get_env("django",
                                      "database_service_name",
                                      default=""),
        distributed_tracing_enabled=True,
        instrument_middleware=asbool(
            get_env("django", "instrument_middleware", default=True)),
        instrument_databases=True,
        instrument_caches=True,
        analytics_enabled=
        None,  # None allows the value to be overridden by the global config
        analytics_sample_rate=None,
        trace_query_string=None,  # Default to global config
示例#21
0
"""
Bootstrapping code that is run when using the `ddtrace-run` Python entrypoint
Add all monkey-patching that needs to run by default here
"""

import os
import imp
import sys
import logging

from ddtrace.utils.formats import asbool, get_env

logs_injection = asbool(get_env('logs', 'injection'))
DD_LOG_FORMAT = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] {}- %(message)s'.format(
    '[dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] '
    if logs_injection else '')

debug = os.environ.get("DATADOG_TRACE_DEBUG")

# Set here a default logging format for basicConfig

# DEV: Once basicConfig is called here, future calls to it cannot be used to
# change the formatter since it applies the formatter to the root handler only
# upon initializing it the first time.
# See https://github.com/python/cpython/blob/112e4afd582515fcdcc0cde5012a4866e5cfda12/Lib/logging/__init__.py#L1550
if debug and debug.lower() == "true":
    logging.basicConfig(level=logging.DEBUG, format=DD_LOG_FORMAT)
else:
    logging.basicConfig(format=DD_LOG_FORMAT)

log = logging.getLogger(__name__)
示例#22
0
def get_stats_port(default=DEFAULT_STATS_PORT):
    # type: (Union[T, int]) -> Union[T,int]
    v = get_env("dogstatsd", "port", default=None)
    if v is not None:
        return int(v)
    return default
示例#23
0
 def test_get_env_key_priority(self):
     # ensure `get_env` use `DD_` with highest priority
     os.environ['DD_REQUESTS_DISTRIBUTED_TRACING'] = 'highest'
     os.environ['DATADOG_REQUESTS_DISTRIBUTED_TRACING'] = 'lowest'
     value = get_env('requests', 'distributed_tracing')
     eq_(value, 'highest')
示例#24
0
from ddtrace.propagation.http import HTTPPropagator
from ddtrace.utils import get_argument_value
from ddtrace.utils.formats import asbool
from ddtrace.utils.formats import get_env
from ddtrace.utils.wrappers import unwrap as _u
from ddtrace.vendor.wrapt import wrap_function_wrapper as _w


if typing.TYPE_CHECKING:
    from ddtrace import Span
    from ddtrace.vendor.wrapt import BoundFunctionWrapper

config._add(
    "httpx",
    {
        "distributed_tracing": asbool(get_env("httpx", "distributed_tracing", default=True)),
        "split_by_domain": asbool(get_env("httpx", "split_by_domain", default=False)),
    },
)


def _url_to_str(url):
    # type: (httpx.URL) -> str
    """
    Helper to convert the httpx.URL parts from bytes to a str
    """
    scheme, host, port, raw_path = url.raw
    url = scheme + b"://" + host
    if port is not None:
        url += b":" + ensure_binary(str(port))
    url += raw_path
"""
Bootstrapping code that is run when using the `ddtrace-run` Python entrypoint
Add all monkey-patching that needs to run by default here
"""

import os
import imp
import sys
import logging

from ddtrace.utils.formats import asbool, get_env
from ddtrace.internal.logger import get_logger
from ddtrace import constants

logs_injection = asbool(get_env("logs", "injection"))
DD_LOG_FORMAT = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] {}- %(message)s".format(
    "[dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] "
    if logs_injection else "")

if logs_injection:
    # immediately patch logging if trace id injected
    from ddtrace import patch

    patch(logging=True)

debug = os.environ.get("DATADOG_TRACE_DEBUG")

# Set here a default logging format for basicConfig

# DEV: Once basicConfig is called here, future calls to it cannot be used to
# change the formatter since it applies the formatter to the root handler only
示例#26
0
 def test_get_env_long(self):
     os.environ["DD_SOME_VERY_LONG_TEST_KEY"] = "1"
     value = get_env("some", "very", "long", "test", "key", default="2")
     assert value == "1"
"""
Bootstrapping code that is run when using the `ddtrace-run` Python entrypoint
Add all monkey-patching that needs to run by default here
"""

import os
import imp
import sys
import logging

from ddtrace.utils.formats import asbool, get_env
from ddtrace.internal.logger import get_logger
from ddtrace import constants

logs_injection = asbool(get_env('logs', 'injection'))
DD_LOG_FORMAT = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] {}- %(message)s'.format(
    '[dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] ' if logs_injection else ''
)

if logs_injection:
    # immediately patch logging if trace id injected
    from ddtrace import patch
    patch(logging=True)

debug = os.environ.get('DATADOG_TRACE_DEBUG')

# Set here a default logging format for basicConfig

# DEV: Once basicConfig is called here, future calls to it cannot be used to
# change the formatter since it applies the formatter to the root handler only
# upon initializing it the first time.
示例#28
0
from ddtrace.propagation.http import HTTPPropagator
from ddtrace.utils.formats import get_env
from ddtrace.utils.wrappers import unwrap, iswrapped

from .compat import get_resolver, user_is_authenticated
from . import utils, conf

wrap = wrapt.wrap_function_wrapper
log = get_logger(__name__)

config._add(
    "django",
    dict(
        service_name=os.environ.get("DD_SERVICE_NAME")
        or os.environ.get("DATADOG_SERVICE_NAME") or "django",
        cache_service_name=get_env("django", "cache_service_name") or "django",
        database_service_name_prefix=get_env("django",
                                             "database_service_name_prefix",
                                             default=""),
        distributed_tracing_enabled=True,
        instrument_databases=True,
        instrument_caches=True,
        analytics_enabled=
        None,  # None allows the value to be overridden by the global config
        analytics_sample_rate=None,
        trace_query_string=None,  # Default to global config
    ),
)

propagator = HTTPPropagator()
示例#29
0
 def test_get_env_found(self):
     # ensure `get_env` returns a value if the environment variable is set
     os.environ['DD_REQUESTS_DISTRIBUTED_TRACING'] = '1'
     value = get_env('requests', 'distributed_tracing')
     eq_(value, '1')
示例#30
0
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)
示例#31
0
def get_stats_port():
    # type: () -> int
    return int(get_env("dogstatsd", "port",
                       default=DEFAULT_STATS_PORT))  # type: ignore[arg-type]
示例#32
0
    if profiling:
        import ddtrace.profiling.auto  # noqa: F401

    opts = {}

    if enabled and enabled.lower() == "false":
        opts["enabled"] = False
        patch = False
    if hostname:
        opts["hostname"] = hostname
    if port:
        opts["port"] = int(port)
    if priority_sampling:
        opts["priority_sampling"] = asbool(priority_sampling)

    opts["collect_metrics"] = asbool(get_env("runtime_metrics", "enabled"))

    if opts:
        tracer.configure(**opts)

    if patch:
        update_patched_modules()
        from ddtrace import patch_all

        patch_all(**EXTRA_PATCHED_MODULES)

    if "DATADOG_ENV" in os.environ:
        tracer.set_tags({constants.ENV_KEY: os.environ["DATADOG_ENV"]})

    if "DD_TRACE_GLOBAL_TAGS" in os.environ:
        env_tags = os.getenv("DD_TRACE_GLOBAL_TAGS")
示例#33
0
import redis
from ddtrace.vendor import wrapt

# project
from ddtrace import config
from ddtrace.utils.formats import get_env
from ...constants import ANALYTICS_SAMPLE_RATE_KEY, SPAN_MEASURED_KEY
from ...pin import Pin
from ...ext import SpanTypes, redis as redisx
from ...utils.wrappers import unwrap
from ... import utils
from .util import format_command_args, _extract_conn_tags

config._add(
    "redis",
    dict(service=get_env("redis", "service") or redisx.DEFAULT_SERVICE, ))


def patch():
    """Patch the instrumented methods

    This duplicated doesn't look nice. The nicer alternative is to use an ObjectProxy on top
    of Redis and StrictRedis. However, it means that any "import redis.Redis" won't be instrumented.
    """
    if getattr(redis, "_datadog_patch", False):
        return
    setattr(redis, "_datadog_patch", True)

    _w = wrapt.wrap_function_wrapper

    if redis.VERSION < (3, 0, 0):