dd-trace-java
dd-trace-java copied to clipboard
Incomplete support for the Tag interface
It seems like the OTSpan implementation doesn't fully support the Tag interface for adding tags of custom types to a span. Specifically, Tag#set is not called to allow a tag implementation to add additional tags to a span aside from the initial value.
Tag#getKey() is called here and then the tag implementation is lost and seems to not be used again.
https://github.com/DataDog/dd-trace-java/blob/78bfb6f2c4de93acf7049522befe27413fd5d87c/dd-trace-ot/src/main/java/datadog/opentracing/OTSpan.java#L89-L93
For reference, if we look at opentracing's implementation of MockSpan, they use Tag#set and pass in this for the span instance so the tag implementation can appropriately tag the span.
@Override
public <T> MockSpan setTag(Tag<T> tag, T value) {
tag.set(this, value);
return this;
}
A specific use-case:
I want to have a MapTag implementation. This implementation would iterate the key-value pairs of the map and check the value types and act accordingly. This would allow me to recursively descend a map by calling Span#setTag from within Tag#set and pass it another MapTag with a composite key. Below is an example implementation that should work, but does not because it never gets called.
public final class MapTag implements Tag<Map<String, Object>> {
private final String prefix;
public MapTag(String prefix) {
this.prefix = prefix;
}
@Override
public String getKey() {
return this.prefix;
}
@Override
public void set(Span span, Map<String, Object> map) {
map.forEach((k, v) -> {
String compositeKey = this.prefix + "." + k;
if (v instanceof Boolean b) {
span.setTag(compositeKey, b);
} else if (v instanceof Number n) {
span.setTag(compositeKey, n);
} else if (v instanceof Map<?, ?> m) {
span.setTag(new MapTag(compositeKey), (Map<String, Object>) m);
} else if (v != null) {
span.setTag(compositeKey, v.toString());
}
});
}
}