mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-08-01 09:13:23 +08:00
164 lines
5.1 KiB
Python
164 lines
5.1 KiB
Python
"""
|
|
Settings for Datadog tracer are all namespaced in the DATADOG_TRACE setting.
|
|
For example your project's `settings.py` file might look like this::
|
|
|
|
DATADOG_TRACE = {
|
|
'TRACER': 'myapp.tracer',
|
|
}
|
|
|
|
This module provides the `setting` object, that is used to access
|
|
Datadog settings, checking for user settings first, then falling
|
|
back to the defaults.
|
|
"""
|
|
from __future__ import unicode_literals
|
|
|
|
import os
|
|
import importlib
|
|
|
|
from django.conf import settings as django_settings
|
|
|
|
from ...internal.logger import get_logger
|
|
|
|
|
|
log = get_logger(__name__)
|
|
|
|
# List of available settings with their defaults
|
|
DEFAULTS = {
|
|
'AGENT_HOSTNAME': 'localhost',
|
|
'AGENT_PORT': 8126,
|
|
'AUTO_INSTRUMENT': True,
|
|
'INSTRUMENT_CACHE': True,
|
|
'INSTRUMENT_DATABASE': True,
|
|
'INSTRUMENT_TEMPLATE': True,
|
|
'DEFAULT_DATABASE_PREFIX': '',
|
|
'DEFAULT_SERVICE': 'django',
|
|
'DEFAULT_CACHE_SERVICE': '',
|
|
'ENABLED': True,
|
|
'DISTRIBUTED_TRACING': True,
|
|
'ANALYTICS_ENABLED': None,
|
|
'ANALYTICS_SAMPLE_RATE': True,
|
|
'TRACE_QUERY_STRING': None,
|
|
'TAGS': {},
|
|
'TRACER': 'ddtrace.tracer',
|
|
}
|
|
|
|
# List of settings that may be in string import notation.
|
|
IMPORT_STRINGS = (
|
|
'TRACER',
|
|
)
|
|
|
|
# List of settings that have been removed
|
|
REMOVED_SETTINGS = ()
|
|
|
|
|
|
def import_from_string(val, setting_name):
|
|
"""
|
|
Attempt to import a class from a string representation.
|
|
"""
|
|
try:
|
|
# Nod to tastypie's use of importlib.
|
|
parts = val.split('.')
|
|
module_path, class_name = '.'.join(parts[:-1]), parts[-1]
|
|
module = importlib.import_module(module_path)
|
|
return getattr(module, class_name)
|
|
except (ImportError, AttributeError) as e:
|
|
msg = 'Could not import "{}" for setting "{}". {}: {}.'.format(
|
|
val,
|
|
setting_name,
|
|
e.__class__.__name__,
|
|
e,
|
|
)
|
|
|
|
raise ImportError(msg)
|
|
|
|
|
|
class DatadogSettings(object):
|
|
"""
|
|
A settings object, that allows Datadog settings to be accessed as properties.
|
|
For example:
|
|
|
|
from ddtrace.contrib.django.conf import settings
|
|
|
|
tracer = settings.TRACER
|
|
|
|
Any setting with string import paths will be automatically resolved
|
|
and return the class, rather than the string literal.
|
|
"""
|
|
def __init__(self, user_settings=None, defaults=None, import_strings=None):
|
|
if user_settings:
|
|
self._user_settings = self.__check_user_settings(user_settings)
|
|
|
|
self.defaults = defaults or DEFAULTS
|
|
if os.environ.get('DATADOG_ENV'):
|
|
self.defaults['TAGS'].update({'env': os.environ.get('DATADOG_ENV')})
|
|
if os.environ.get('DATADOG_SERVICE_NAME'):
|
|
self.defaults['DEFAULT_SERVICE'] = os.environ.get('DATADOG_SERVICE_NAME')
|
|
|
|
host = os.environ.get('DD_AGENT_HOST', os.environ.get('DATADOG_TRACE_AGENT_HOSTNAME'))
|
|
if host:
|
|
self.defaults['AGENT_HOSTNAME'] = host
|
|
|
|
port = os.environ.get('DD_TRACE_AGENT_PORT', os.environ.get('DATADOG_TRACE_AGENT_PORT'))
|
|
if port:
|
|
# if the agent port is a string, the underlying library that creates the socket
|
|
# stops working
|
|
try:
|
|
port = int(port)
|
|
except ValueError:
|
|
log.warning('DD_TRACE_AGENT_PORT is not an integer value; default to 8126')
|
|
else:
|
|
self.defaults['AGENT_PORT'] = port
|
|
|
|
self.import_strings = import_strings or IMPORT_STRINGS
|
|
|
|
@property
|
|
def user_settings(self):
|
|
if not hasattr(self, '_user_settings'):
|
|
self._user_settings = getattr(django_settings, 'DATADOG_TRACE', {})
|
|
|
|
# TODO[manu]: prevents docs import errors; provide a better implementation
|
|
if 'ENABLED' not in self._user_settings:
|
|
self._user_settings['ENABLED'] = not django_settings.DEBUG
|
|
return self._user_settings
|
|
|
|
def __getattr__(self, attr):
|
|
if attr not in self.defaults:
|
|
raise AttributeError('Invalid setting: "{}"'.format(attr))
|
|
|
|
try:
|
|
# Check if present in user settings
|
|
val = self.user_settings[attr]
|
|
except KeyError:
|
|
# Otherwise, fall back to defaults
|
|
val = self.defaults[attr]
|
|
|
|
# Coerce import strings into classes
|
|
if attr in self.import_strings:
|
|
val = import_from_string(val, attr)
|
|
|
|
# Cache the result
|
|
setattr(self, attr, val)
|
|
return val
|
|
|
|
def __check_user_settings(self, user_settings):
|
|
SETTINGS_DOC = 'http://pypi.datadoghq.com/trace/docs/#module-ddtrace.contrib.django'
|
|
for setting in REMOVED_SETTINGS:
|
|
if setting in user_settings:
|
|
raise RuntimeError(
|
|
'The "{}" setting has been removed, check "{}".'.format(setting, SETTINGS_DOC)
|
|
)
|
|
return user_settings
|
|
|
|
|
|
settings = DatadogSettings(None, DEFAULTS, IMPORT_STRINGS)
|
|
|
|
|
|
def reload_settings(*args, **kwargs):
|
|
"""
|
|
Triggers a reload when Django emits the reloading signal
|
|
"""
|
|
global settings
|
|
setting, value = kwargs['setting'], kwargs['value']
|
|
if setting == 'DATADOG_TRACE':
|
|
settings = DatadogSettings(value, DEFAULTS, IMPORT_STRINGS)
|