Skip to content

[BUG] Elastic APM — EF Core SQL Spans Missing #2735

@bftelman

Description

@bftelman

AddAllElasticApm() is documented as the recommended replacement for UseAllElasticApm(), but its DI-based lazy registration runs after app.Run(). Apps that use DbContext in startup code (before app.Run()) will permanently miss the EF Core DiagnosticListener because DiagnosticListener.AllListeners does not replay past emissions.

The bug - current behavior:

// AddElasticApm registers subscribers via a hosted service
services.AddSingleton(sp =>
{
Agent.Setup(...);
Agent.Instance.Subscribe(subscribers); // runs at app.Run() - too late
return Agent.Instance;
});
services.AddHostedService(); // only purpose: resolve IApmAgent above

// By the time ApmService starts at app.Run(),
// startup code has already triggered the EF Core DiagnosticListener.

Folowing is a code snippet from project i am working on:
app.Services.GetService().GetUserById(Guid.Empty); // ← first DbContext use
// → "Microsoft.EntityFrameworkCore" DiagnosticListener published to AllListeners
// → EfCoreDiagnosticsSubscriber subscribes 100ms later → misses it permanently
app.Run();


Proposed fix - subscribe via IStartupFilter instead:

// IStartupFilter runs synchronously during middleware pipeline construction,
// before any startup code executes DbContext operations
internal class ApmStartupFilter(IApmAgent agent, IDiagnosticsSubscriber[] subscribers)
: IStartupFilter
{
public Action Configure(Action next)
=> app =>
{
agent.Subscribe(subscribers); // ← fires before GetUserById, Synchronise, etc.
next(app);
};
}

// Registration:
services.AddSingleton(sp =>
new ApmStartupFilter(sp.GetRequiredService(), subscribers));

This matches the timing of UseAllElasticApm (synchronous, during pipeline build) without requiring the deprecated middleware API.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions