Skip to content

Commit 04b6b9b

Browse files
committed
reorder config precedence to align with all other agents (#261)
refs elastic/apm-agent-nodejs#287 closes #255 closes #261 Signed-off-by: Benjamin Wohlwend <[email protected]>
1 parent 429efcf commit 04b6b9b

File tree

7 files changed

+64
-28
lines changed

7 files changed

+64
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
[Check the diff](https://github.com/elastic/apm-agent-python/compare/v2.2.1...master)
66

77
- **BREAKING**: dropped support for Python 3.3 (#242)
8+
- **BREAKING**: changed order of precedence when evaluating configuration (#255, #261)
89
- **BREAKING**: changed default value of `span_frames_min_duration` setting
910
from `-1` (always collect) to `5` (only collect for spans longer than 5 ms) (#243)
1011
- added instrumentation for pymssql (#241)
12+
- added instrumentation for pyodbc (#238)
1113

1214
## v2.2.1
1315

docs/configuration.asciidoc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,35 @@
44
To adapt the Elastic APM agent to your needs, you can configure it using environment variables, or framework specific
55
configuration.
66

7+
You can either configure the agent by setting environment variables:
8+
[source,bash]
9+
----
10+
ELASTIC_APM_SERVICE_NAME=foo python manage.py runserver
11+
----
12+
13+
or with inline configuration:
14+
15+
[source,python]
16+
----
17+
apm_client = Client(service_name="foo")
18+
----
19+
20+
or by using framework specific configuration e.g. in your Django `settings.py` file:
21+
22+
[source,python]
23+
----
24+
ELASTIC_APM = {
25+
"SERVICE_NAME": "foo",
26+
}
27+
----
28+
29+
The precedence is as follows:
30+
31+
* environment variables
32+
* inline configuration
33+
* framework specific configuration
34+
* default value
35+
736
[float]
837
[[django-configuration]]
938
=== Django

elasticapm/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class Client(object):
9999
"""
100100
logger = logging.getLogger('elasticapm')
101101

102-
def __init__(self, config=None, **defaults):
102+
def __init__(self, config=None, **inline):
103103
# configure loggers first
104104
cls = self.__class__
105105
self.logger = logging.getLogger('%s.%s' % (cls.__module__, cls.__name__))
@@ -113,7 +113,7 @@ def __init__(self, config=None, **defaults):
113113
self._transports = {}
114114
self._service_info = None
115115

116-
self.config = Config(config, default_dict=defaults)
116+
self.config = Config(config, inline_dict=inline)
117117
if self.config.errors:
118118
for msg in self.config.errors.values():
119119
self.error_logger.error(msg)

elasticapm/conf/__init__.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,28 @@ def __set__(self, instance, value):
9797
class _ConfigBase(object):
9898
_NO_VALUE = object() # sentinel object
9999

100-
def __init__(self, config_dict=None, env_dict=None, default_dict=None):
100+
def __init__(self, config_dict=None, env_dict=None, inline_dict=None):
101101
self._values = {}
102102
self._errors = {}
103103
if config_dict is None:
104104
config_dict = {}
105105
if env_dict is None:
106106
env_dict = os.environ
107-
if default_dict is None:
108-
default_dict = {}
107+
if inline_dict is None:
108+
inline_dict = {}
109109
for field, config_value in self.__class__.__dict__.items():
110110
if not isinstance(config_value, _ConfigValue):
111111
continue
112112
new_value = self._NO_VALUE
113-
# check config dictionary first
114-
if config_value.dict_key in config_dict:
115-
new_value = config_dict[config_value.dict_key]
116-
# then check environment
117-
elif config_value.env_key and config_value.env_key in env_dict:
113+
# first check environment
114+
if config_value.env_key and config_value.env_key in env_dict:
118115
new_value = env_dict[config_value.env_key]
119-
# finally, if no value is set, check the client-provided defaults
120-
elif field in default_dict:
121-
new_value = default_dict[field]
116+
# check the inline config
117+
elif field in inline_dict:
118+
new_value = inline_dict[field]
119+
# finally, check config dictionary
120+
elif config_value.dict_key in config_dict:
121+
new_value = config_dict[config_value.dict_key]
122122
# only set if new_value changed. We'll fall back to the field default if not.
123123
if new_value is not self._NO_VALUE:
124124
try:

elasticapm/contrib/django/client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ def get_client(client=None):
6060
class DjangoClient(Client):
6161
logger = logging.getLogger('elasticapm.errors.client.django')
6262

63-
def __init__(self, config=None, **defaults):
63+
def __init__(self, config=None, **inline):
6464
if config is None:
6565
config = getattr(django_settings, 'ELASTIC_APM', {})
66-
if 'framework_name' not in defaults:
67-
defaults['framework_name'] = 'django'
68-
defaults['framework_version'] = django.get_version()
69-
super(DjangoClient, self).__init__(config, **defaults)
66+
if 'framework_name' not in inline:
67+
inline['framework_name'] = 'django'
68+
inline['framework_version'] = django.get_version()
69+
super(DjangoClient, self).__init__(config, **inline)
7070

7171
def get_user_info(self, request):
7272
user_info = {}

tests/config/tests.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def test_config_environment():
6565
assert config.auto_log_stacks == False
6666

6767

68-
def test_config_defaults_dict():
69-
config = Config(default_dict={
68+
def test_config_inline_dict():
69+
config = Config(inline_dict={
7070
'service_name': 'foo',
7171
'secret_token': 'bar',
7272
'server_url': 'http://example.com:1234',
@@ -84,17 +84,22 @@ def test_config_defaults_dict():
8484

8585

8686
def test_config_precedence():
87-
# precendece order: config dict, environment, default dict
87+
# precedence order: environment, inline dict, config dict
8888
with mock.patch.dict('os.environ', {
8989
'ELASTIC_APM_SERVICE_NAME': 'bar',
90-
'ELASTIC_APM_SECRET_TOKEN': 'secret'
9190
}):
9291
config = Config({
9392
'SERVICE_NAME': 'foo',
94-
}, default_dict={'secret_token': 'notsecret'})
95-
96-
assert config.service_name == 'foo'
97-
assert config.secret_token == 'secret'
93+
'SECRET_TOKEN': 'secret',
94+
'COLLECT_LOCAL_VARIABLES': 'all'
95+
}, inline_dict={
96+
'secret_token': 'notsecret',
97+
'service_name': 'baz'
98+
})
99+
100+
assert config.service_name == 'bar'
101+
assert config.secret_token == 'notsecret'
102+
assert config.collect_local_variables == 'all'
98103

99104

100105
def test_list_config_value():

tests/fixtures.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ def sending_elasticapm_client(request, validating_httpserver):
134134

135135

136136
class TempStoreClient(Client):
137-
def __init__(self, **defaults):
137+
def __init__(self, **inline):
138138
self.events = []
139-
super(TempStoreClient, self).__init__(**defaults)
139+
super(TempStoreClient, self).__init__(**inline)
140140

141141
def send(self, url, **kwargs):
142142
self.events.append(kwargs)

0 commit comments

Comments
 (0)