open-telemetry / open-telemetry/opentelemetry-java
Allow overwriting/modyfing span resource in SpanProcessor
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 2.5k
- Forks
- 1k
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 58
Description
Is your feature request related to a problem? Please describe.
I'm using OTEL with DataDog (DD), and it would greatly help visibility if I could overwrite the service name for some operations (spans).
DD doesn't properly understand the semantics of OTEL, and the problem is extra visible when some services are instrumented using OTEL, and some are instrumented using the native DD agent. DD creates a separate "service" for database calls, HTTP calls, etc - basically, everything that "leaves" the service and that's super useful, because then the time spent in DB or HTTP calls really pops out and becomes super visible.
Describe the solution you'd like
Basically I'd like to be able to modify the resource of a span. Right now the resource field is final and ReadWriteSpan cannot modify it.
Describe alternatives you've considered
Currently, I'm experimenting with hacking it using reflection, but I would like to avoid having to use that in the PROD... but as a prototype, it works really well...
OverrideServiceNameSpanProcessor
public class OverrideServiceNameSpanProcessor implements SpanProcessor
{
private static final Class<?> SDK_SPAN_CLASS;
private static final Field SDK_SPAN_RESOURCE_FIELD;
static {
try {
SDK_SPAN_CLASS = Class.forName("io.opentelemetry.sdk.trace.SdkSpan");
SDK_SPAN_RESOURCE_FIELD = SDK_SPAN_CLASS.getDeclaredField("resource");
SDK_SPAN_RESOURCE_FIELD.setAccessible(true);
} catch (ClassNotFoundException | NoSuchFieldException e) {
throw new IllegalStateException(e);
}
}
private static final Map<String, String> SCOPE_TO_SERVICE_NAME_SUFFIX = Map.ofEntries(
Map.entry("io.opentelemetry.jdbc", "jdbc"),
Map.entry("io.opentelemetry.apache-httpclient-5.0", "httpclient"),
Map.entry("io.opentelemetry.http-url-connection", "httpclient"),
Map.entry("io.opentelemetry.aws-sdk-1.11", "aws")
);
@Override
public void onStart(final Context parentContext, final ReadWriteSpan span)
{
if (!SDK_SPAN_CLASS.isInstance(span)) {
return; // noop
}
InstrumentationScopeInfo instrumentationInfo = span.getInstrumentationScopeInfo();
@Nullable String resourceServiceNameSuffix = SCOPE_TO_SERVICE_NAME_SUFFIX.get(instrumentationInfo.getName());
if (resourceServiceNameSuffix == null) {
return; // noop
}
try {
var resource = (Resource) SDK_SPAN_RESOURCE_FIELD.get(span);
Resource updatedResource = resource.toBuilder()
.put(ResourceAttributes.SERVICE_NAME, "%s-%s".formatted(
resource.getAttribute(ResourceAttributes.SERVICE_NAME),
resourceServiceNameSuffix
))
.build();
SDK_SPAN_RESOURCE_FIELD.set(span, updatedResource);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
// the rest is not important
}
Additional context
You have to zoom in a little, but then you can see that the e.g. redis, pdo, mongo, etc. are shown as separate services - these spans are obviously part of the app that is calling them, but the native DD agent renames the single span's service name.
It makes a lot of sense if you think about it for a bit - my database is obviously not instrumented with OTEL (maybe in the future?), so I don't have any spans from it - but I have the spans in my app that are calling the database and that is as close as I'll get in the near future to having the database calls rendered as a separate service.
The example image is not mine it's from some article - but it illustrates it nicely.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the ReadWriteSpan and SdkSpan APIs, especially the resource field, and review how SpanProcessor receives spans and how Resource is represented. The issue does not name a test or file beyond these entry points; done means defining and validating a supported way for processors to modify a span resource without reflection.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- observability-sre
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100
