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.
AddAllElasticApm()is documented as the recommended replacement forUseAllElasticApm(), but its DI-based lazy registration runs afterapp.Run(). Apps that useDbContextin startup code (beforeapp.Run()) will permanently miss the EF CoreDiagnosticListenerbecauseDiagnosticListener.AllListenersdoes 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.