at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.Read(Span1 buffer) at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.Read(Span1 buffer)
at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamReader.ReadBuffer()
at System.IO.StreamReader.ReadToEnd()
at Elastic.Apm.AspNetCore.Extensions.HttpRequestExtensions.ExtractRequestBody(HttpRequest request, IApmLogger logger, IConfigSnapshot configSnapshot)
Latest version as of an hour ago, and .NET 5.
This is coming from request body capturing.
If you want to capture request body with the agent on ASP.NET Core, then you'll need to enable sync reading with:
public void ConfigureServices(IServiceCollection services)
{
// If using Kestrel:
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
// If using IIS:
services.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
}
Or, if this is not an option, you'll need to disable request body capturing (the default is off). It'd be ideal to enabling sync IO in the agent, but so far I haven't seen any feasible way to do so.
Why can't APM work with async?
Why can't APM work with async?
It can work async when we use a middleware. But once we move to diagnostic source based ASP.NET Core transaction capturing then it won't work, because diagnostic source is not async. Reason for moving away from the middleware approach is that we have a zero code change way to turn on the agent and with that setup it'd be very hard to enable a middleware, since the code that turns on the agent is triggered before any ASP.NET Core assembly is loaded.
In the latest release the middleware is still there, so technically we could still read the request body asynchronously. We discussed this in detail and we ended up not doing that, because it would be super confusing that depending on how you inject the agent you'll either have this problem or not.
APM can work with async, this is only about request body capturing and if this happens the request is still captured, but without the request body.
I looked more into this - I think maybe we can make this work. I'll do another iteration on this.
Most helpful comment
I looked more into this - I think maybe we can make this work. I'll do another iteration on this.