diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index 28f9e39c710..ba88574b375 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -72,6 +72,7 @@ import datadog.trace.bootstrap.instrumentation.api.ProfilingContextIntegration; import datadog.trace.bootstrap.instrumentation.api.SpanAttributes; import datadog.trace.bootstrap.instrumentation.api.SpanLink; +import datadog.trace.bootstrap.instrumentation.api.SpanPrototype; import datadog.trace.bootstrap.instrumentation.api.TagContext; import datadog.trace.bootstrap.instrumentation.api.Tags; import datadog.trace.civisibility.interceptor.CiVisibilityApmProtocolInterceptor; @@ -1038,6 +1039,24 @@ public CoreSpanBuilder buildSpan( return createMultiSpanBuilder(instrumentationName, operationName); } + /** + * Seeds identity (instrumentation name, operation, span type) and tags from a prototype. + * + *
TODO(follow-up): eager-sets identity from the proto today, which is fine while
+ * {@code buildSpan(proto)} is the only proto entry point. When a builder value and a proto value
+ * can coexist, resolve via helpers (builder-explicit wins, proto is the fallback) in the build
+ * path and make this carry-only — no reach-in to {@code builder.spanType}/{@code spanPrototype}.
+ */
+ public CoreSpanBuilder buildSpan(final SpanPrototype prototype) {
+ CoreSpanBuilder builder =
+ createMultiSpanBuilder(prototype.instrumentationName(), prototype.operationName());
+ builder.spanPrototype = prototype;
+ if (prototype.spanType() != null) {
+ builder.spanType = prototype.spanType();
+ }
+ return builder;
+ }
+
MultiSpanBuilder createMultiSpanBuilder(
final String instrumentationName, final CharSequence operationName) {
return new MultiSpanBuilder(this, instrumentationName, operationName);
@@ -1583,6 +1602,7 @@ public abstract static class CoreSpanBuilder implements AgentTracer.SpanBuilder
// Builder attributes
// Make sure any fields added here are also reset properly in ReusableSingleSpanBuilder.reset
protected TagMap.Ledger tagLedger;
+ protected SpanPrototype spanPrototype = SpanPrototype.NONE;
protected long timestampMicro;
protected AgentSpanContext parent;
protected String serviceName;
@@ -1621,6 +1641,7 @@ protected static final DDSpan buildSpan(
boolean errorFlag,
CharSequence spanType,
TagMap.Ledger tagLedger,
+ SpanPrototype spanPrototype,
List