merge DD_VERSION and DD_ENV with "dd.trace.global.tags"#1393
Conversation
1cfd922 to
48402c4
Compare
There was a problem hiding this comment.
Thanks for all the additional tests.
I wonder if all the tags should be merged into a single map. @mar-kolya what do you think?
48402c4 to
5e66734
Compare
b82171f to
baae569
Compare
| { | ||
| final Map<String, String> tagsPreMap = getMapSettingFromEnvironment(TAGS, null); | ||
| if (tagsPreMap != null && !tagsPreMap.isEmpty()) { | ||
| // we only populate this tags if we use 'dd.tags'. If we don't use it: we populate this tags | ||
| // to 'dd.trace.global.tags' and globalTags field | ||
| tags = getMapWithPropertiesDefinedByEnvironment(tagsPreMap, ENV, VERSION); | ||
| } else { | ||
| tags = Collections.emptyMap(); | ||
| } | ||
| } | ||
| globalTags = | ||
| getMapWithPropertiesDefinedByEnvironment( | ||
| getMapSettingFromEnvironment(GLOBAL_TAGS, null), ENV, VERSION); | ||
|
|
There was a problem hiding this comment.
Do you think it would simplify things to reduce the distinction between tags and global tags and combine them into a single map as soon as possible? (End result being just a single tags field.)
There was a problem hiding this comment.
+1 I think this idea makes sense too. We just need to be careful about the order of precedence for updating the single map.
E.g.,
- Look for
DD_prefixed env var first for env/service/version. - Then look at JMX flags.
| then: | ||
| config.mergedSpanTags == [a: "1", c: "3"] | ||
| config.mergedJmxTags == [a: "1", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName] | ||
| config.mergedSpanTags == [a: "1", c: "3", (Config.ENV) : "eu-east", (Config.VERSION) : "43"] |
There was a problem hiding this comment.
When you've implemented merging of the tags/global tags, this should also have b:2, right?
There was a problem hiding this comment.
if you want me to merge them. It might break existing backward compatibility because we already have several versions where dd.tags exclude dd.trace.global.tags is it ok ?
There was a problem hiding this comment.
yeah, let's merge them into a single map inside Config. Any edge cases where this would be problematic?
There was a problem hiding this comment.
yeah, let's merge them into a single map inside
Config. Any edge cases where this would be problematic?
@jdgumz ?
There was a problem hiding this comment.
The only thing I can think of is a hard-coded service tag existing in some Dockerfile or build config that goes unnoticed. If someone adds DD_SERVICE elsewhere and the value is different, it might be a surprise.
But I think as long as we call out the order of precedence very clearly in our release notes, folks should be able to triage the issue. I don't think we can support differing service values - there has to be one.
jdgumz
left a comment
There was a problem hiding this comment.
Thanks for adding the cases for service. Although I'm not sure I understand the precedence at play.
| { | ||
| final Map<String, String> tagsPreMap = getMapSettingFromEnvironment(TAGS, null); | ||
| if (tagsPreMap != null && !tagsPreMap.isEmpty()) { | ||
| // we only populate this tags if we use 'dd.tags'. If we don't use it: we populate this tags | ||
| // to 'dd.trace.global.tags' and globalTags field | ||
| tags = getMapWithPropertiesDefinedByEnvironment(tagsPreMap, ENV, VERSION); | ||
| } else { | ||
| tags = Collections.emptyMap(); | ||
| } | ||
| } | ||
| globalTags = | ||
| getMapWithPropertiesDefinedByEnvironment( | ||
| getMapSettingFromEnvironment(GLOBAL_TAGS, null), ENV, VERSION); | ||
|
|
There was a problem hiding this comment.
+1 I think this idea makes sense too. We just need to be careful about the order of precedence for updating the single map.
E.g.,
- Look for
DD_prefixed env var first for env/service/version. - Then look at JMX flags.
| 'service.version' : 'my-svc-vers'] | ||
| } | ||
|
|
||
| def "DD_SERVICE ignored when 'dd.service.name' java property is set; 'dd.service.name' overwrites DD_SERVICE_NAME"() { |
There was a problem hiding this comment.
DD_SERVICE should not be ignored - it should have the highest precedence.
There was a problem hiding this comment.
In our codebase, we have a different order of precedence. System Properties, defined on the command line have a higher precedence than environment variables.
There was a problem hiding this comment.
@tylerbenson here @jdgumz wants java property(env var) dd.service(DD_SERVICE) take precedence over dd.service.name(DD_SERVICE_NAME). That's another potentially backward incompatible change which might affect some deployments where we have both of them already. It looks like previous change where we introduced tags which overwrite old existing global.tags : https://github.com/DataDog/dd-trace-java/pull/1263/files#diff-43038f0f76f33bbf93ca377b0f77ff7aR707
|
|
||
| then: | ||
| config.serviceName == "dd-service-env-var" | ||
| config.mergedSpanTags == [service:'service-tag-in-dd-trace-global-tags-java-property','service.version' : 'my-svc-vers'] |
There was a problem hiding this comment.
I'm not sure I understand. Why are we using the service:service-tag-in-dd-trace-global-tags-java-property still? I think it'd be confusing to see a different service in the span metadata from the one that should be used (the value of DD_SERVICE).
There was a problem hiding this comment.
I assume service would get removed from the metadata before being reported to the agent, but I'm wondering if the part that does that would then replace the env-var service name since the rules for processing tags happen at a different place. This might be a problem and mean we need to pull those tags out earlier.
There was a problem hiding this comment.
service name will be overwritten for span with the check above
There was a problem hiding this comment.
The point of this and some other tests to show: that we can have service tag in tags, which will be later ignored and FOR SURE will be overwritten by some other things up to default service name. That's behaviour is different from env and version tags, which will not be overwritten unless corresponding java property or env var is set.
There was a problem hiding this comment.
Gotcha. One other question: it seems like DD_SERVICE overrides the value of service even when there's a service tag in the global system property. This seems inconsistent with dd.service as a system property overriding the env var DD_SERVICE? It sounded like we wanted to maintain the highest precedence for system properties?
There was a problem hiding this comment.
we have precedence of
- java system properties
- environment variables
- property file
before, and implications of this might be more unpredictable for many other deployment. Of we want to change this precedence order, let's address it in a separate PR
baae569 to
f50a487
Compare
f50a487 to
2bab077
Compare
jdgumz
left a comment
There was a problem hiding this comment.
I think most of the test cases make sense - just have a few more questions.
| Config.get().serviceName == DEFAULT_SERVICE_NAME | ||
| } | ||
|
|
||
| def "default service name is not affected by tags, nor env variables"() { |
There was a problem hiding this comment.
I'm not sure I understand this case. If we have a service somewhere (global tags, or even DD_SERVICE) shouldn't that be used?
There was a problem hiding this comment.
It should not. It will be ignored. That's requirement we have now. You can't define service name through tags. If you try to do so: it will be overwritten later
There was a problem hiding this comment.
While this is true from the config perspective, we may have a problem with this when it is actually applied to a span. Spans have decorators that are applied to tags. Specifically ServiceNameDecorator may be problematic. I think we want to update SpanDecoratorTest to validate this.
|
|
||
| then: | ||
| config.serviceName == "dd-service-env-var" | ||
| config.mergedSpanTags == [service:'service-tag-in-dd-trace-global-tags-java-property','service.version' : 'my-svc-vers'] |
There was a problem hiding this comment.
Gotcha. One other question: it seems like DD_SERVICE overrides the value of service even when there's a service tag in the global system property. This seems inconsistent with dd.service as a system property overriding the env var DD_SERVICE? It sounded like we wanted to maintain the highest precedence for system properties?
| 'service.version' : 'my-svc-vers'] | ||
| } | ||
|
|
||
| def "DD_SERVICE precedence over 'dd.service.name' java property is set; 'dd.service' overwrites DD_SERVICE"() { |
There was a problem hiding this comment.
Wait - don't we have it set up to allow DD_ENV and DD_VERSION to override dd.trace.global.tags?
I'm guessing this is a different case because dd.service already existed and generally system properties take the highest precedent?
There was a problem hiding this comment.
Wait - don't we have it set up to allow
DD_ENVandDD_VERSIONto overridedd.trace.global.tags?
we don't have to, but if we set these 2 env vars they override corresponding tags. Here is a test for it:
https://github.com/DataDog/dd-trace-java/pull/1393/files#diff-19302d05d6472f1ef9c915823a88f122R1323
I'm guessing this is a different case because
dd.servicealready existed and generally system properties take the highest precedent?
correct
tylerbenson
left a comment
There was a problem hiding this comment.
Approving with the assumption the mentioned edgecase (service tag set overriding the configured service name in an actual span due to decorator interaction) is handled in a separate PR.
This change introduces merging of explicitly defined span properties and properties defined in "dd.trace.global.tags".
I ) For every property we have 3 levels of defining it:
We take next one only if it's not defined the previous one. Eg. So we look into linux environment variables only
II ) We have special container properties
tagsandglobal.tagswhich allow to aggregate other properties inside it.dd.tags(DD_TAGS) has precedence overdd.trace.global.tags. It will be merging of tags.III ) The result
servicetag in span is set up bydd.service(DD_SERVICE) first.dd.service(DD_SERVICE) is not set the resultservicetag is set bydd.service.name(DD_SERVICE_NAME)servicetag is set by default integration name or just default nameservicetag through tags