1import os
2
3from django.conf import settings as django_settings
4from django.test.signals import setting_changed
5
6DEFAULTS = {
7    'AWS_XRAY_DAEMON_ADDRESS': '127.0.0.1:2000',
8    'AUTO_INSTRUMENT': True,
9    'AWS_XRAY_CONTEXT_MISSING': 'RUNTIME_ERROR',
10    'PLUGINS': (),
11    'SAMPLING': True,
12    'SAMPLING_RULES': None,
13    'SAMPLER': None,
14    'AWS_XRAY_TRACING_NAME': None,
15    'DYNAMIC_NAMING': None,
16    'STREAMING_THRESHOLD': None,
17    'MAX_TRACE_BACK': None,
18    'STREAM_SQL': True,
19    'PATCH_MODULES': [],
20    'AUTO_PATCH_PARENT_SEGMENT_NAME': None,
21    'IGNORE_MODULE_PATTERNS': [],
22}
23
24XRAY_NAMESPACE = 'XRAY_RECORDER'
25
26SUPPORTED_ENV_VARS = ('AWS_XRAY_DAEMON_ADDRESS',
27                      'AWS_XRAY_CONTEXT_MISSING',
28                      'AWS_XRAY_TRACING_NAME',
29                      )
30
31
32class XRaySettings(object):
33    """
34    A object of Django settings to easily modify certain fields.
35    The precedence for configurations at different places is as follows:
36    environment variables > user settings in settings.py > default settings
37    """
38    def __init__(self, user_settings=None):
39
40        self.defaults = DEFAULTS
41
42        if user_settings:
43            self._user_settings = user_settings
44
45    @property
46    def user_settings(self):
47
48        if not hasattr(self, '_user_settings'):
49            self._user_settings = getattr(django_settings, XRAY_NAMESPACE, {})
50
51        return self._user_settings
52
53    def __getattr__(self, attr):
54
55        if attr not in self.defaults:
56            raise AttributeError('Invalid setting: %s' % attr)
57
58        if self.user_settings.get(attr, None) is not None:
59            if attr in SUPPORTED_ENV_VARS:
60                return os.getenv(attr, self.user_settings[attr])
61            else:
62                return self.user_settings[attr]
63        elif attr in SUPPORTED_ENV_VARS:
64            return os.getenv(attr, self.defaults[attr])
65        else:
66            return self.defaults[attr]
67
68
69settings = XRaySettings()
70
71
72def reload_settings(*args, **kwargs):
73    """
74    Reload X-Ray user settings upon Django server hot restart
75    """
76    global settings
77    setting, value = kwargs['setting'], kwargs['value']
78    if setting == XRAY_NAMESPACE:
79        settings = XRaySettings(value)
80
81
82setting_changed.connect(reload_settings)
83