apm-agent-dotnet
apm-agent-dotnet copied to clipboard
Allow controlling the transaction name
Summary
When the .NET APM agent bridges OpenTelemetry Activity, transactions without a meaningful DisplayName fall back to "unknown". In desktop or background apps (WinForms/WPF, console, services) you want to stay within the Activity API surface entirely—no direct calls into Elastic.APM—yet still be able to assign descriptive transaction names.
Current Behavior
- The agent’s
ElasticActivityListenercreates transactions fromActivity.DisplayName, defaulting to"unknown"if none is set. - There is no hook for users to influence the name without touching
Agent.Traceror other Elastic-specific APIs. - As a result, UI-driven or batch-job
Activitys often show up as"unknown"in APM.
Desired Behavior
-
Respect a well-known
Activitytag
If anActivitycarries a tag like"otel.elastic.transaction_name", use its value as the transaction name. -
Allow a naming delegate in options
Expose, via configuration, aFunc<Activity, string?>that runs before transaction creation—so users can customize names purely in terms ofActivity. -
Fallback to
Kindwhen appropriate
When noDisplayNameor custom tag is present, fall back toActivity.Kind.ToString()rather than"unknown".
Rationale
- Zero Elastic API dependency: Instruments built around
ActivitySourceremain free of Elastic-specific calls. - Uniform tracing model: Desktop, background, and web apps can all use the same
Activity-based naming strategy. - Better observability: Eliminates
"unknown"transactions and surfaces meaningful names without boilerplate.
Example Configuration
// During agent initialization:
Agent.Setup(new AgentComponents
{
TelemetryConfiguration = new TelemetryConfiguration
{
// Called whenever an Activity would spawn a transaction
ActivityNameFormatter = activity =>
activity.GetTagValue("otel.elastic.transaction_name")
as string
?? activity.DisplayName
?? activity.Kind.ToString()
}
});
// In your WinForms code, you only need to set a tag:
var activity = ActivitySource.StartActivity("SomeOp", ActivityKind.Internal);
activity?.SetTag("otel.elastic.transaction_name", "LoadCustomerDetails");
// … some logic …
activity?.Stop();
Thanks for putting some thought into this and raising this issue, @alexanderpino.
The proposal seems reasonable. However, we now recommend the (recently GA'd) Elastic Distribution of OpenTelemetry (EDOT) for an OTel-native experience in .NET. If you do not need/want to interact with the Elastic APM APIs, the EDOT is likely a better fit for a richer OTel experience with the .NET Activity APIs. Our focus for engineering effort is on improving the EDOT and the experience of using OTel-native tools with Elastic Observability.
I'm curious, were you aware of the EDOT, and if so, have you given it a try?
Closing as unplanned.