AppMetrics: MetricsEndpointMiddleware doesn't satisfy AllowSynchronousIO option of Kestrel server
Recently we started migration to the prometheus engine to store our metrics, so we used the /metrics endpoint processed by this library. Also we have configured it with prometheus formatter.
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost
.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseMetrics()
.UseMetricsEndpoints(options =>
{
options.MetricsEndpointOutputFormatter = new MetricsPrometheusTextOutputFormatter();
})
.UseKestrel(o => o.AllowSynchronousIO = false);
}
There is an option in kestrel server which disable synchronous api in order to prevent potential blocking of threads. So what we observing is if AllowSynchronousIO == false, the formatters of library throw since they use synchronous methods when writing to the stream:
System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Write(String value)
at App.Metrics.Formatters.Prometheus.Internal.AsciiFormatter.WriteSimpleValue(StreamWriter writer, String family, Double value, IEnumerable`1 labels, String namePostfix) in C:\projects\prometheus\src\App.Metrics.Formatters.Prometheus\Internal\AsciiFormatter.cs:line 115
at App.Metrics.Formatters.Prometheus.Internal.AsciiFormatter.WriteMetric(StreamWriter streamWriter, MetricFamily family, Metric metric) in C:\projects\prometheus\src\App.Metrics.Formatters.Prometheus\Internal\AsciiFormatter.cs:line 110
at App.Metrics.Formatters.Prometheus.Internal.AsciiFormatter.WriteFamily(StreamWriter streamWriter, MetricFamily metricFamily) in C:\projects\prometheus\src\App.Metrics.Formatters.Prometheus\Internal\AsciiFormatter.cs:line 58
at App.Metrics.Formatters.Prometheus.Internal.AsciiFormatter.Write(Stream destination, IEnumerable`1 metrics, NewLineFormat newLine) in C:\projects\prometheus\src\App.Metrics.Formatters.Prometheus\Internal\AsciiFormatter.cs:line 36
at App.Metrics.Formatters.Prometheus.MetricsPrometheusTextOutputFormatter.WriteAsync(Stream output, MetricsDataValueSource metricsData, CancellationToken cancellationToken) in C:\projects\prometheus\src\App.Metrics.Formatters.Prometheus\MetricsPrometheusTextOutputFormatter.cs:line 47
at App.Metrics.AspNetCore.Endpoints.Middleware.MetricsEndpointMiddleware.Invoke(HttpContext context) in C:\projects\aspnetcore\src\App.Metrics.AspNetCore.Endpoints\Middleware\MetricsEndpointMiddleware.cs:line 41
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
As for now we have to set AllowSynchronousIO == true, but I think the library must be async all the way. The same behavior observed with default output formatter, and with /metrics-text default output formater. Checked with 2.0 and 3.0 versions of app.metrics, and with aspnetcore 2.1 and 2.2.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 15 (1 by maintainers)
Commits related to this issue
- #396 #496 metrics text formatting async — committed to AppMetrics/AppMetrics by alhardy 5 years ago
- #500 #496 #396 async updates and using system.text.json for core json formatting — committed to AppMetrics/AppMetrics by alhardy 5 years ago
- #396 fix await async json serialization of metrics — committed to AppMetrics/AppMetrics by alhardy 5 years ago
- #396 #396 removing allow sync io from sample apps — committed to AppMetrics/AppMetrics by alhardy 5 years ago
- Features/4.0.0 (#503) * #494 Decommissiong health check functionality due to microsoft implementation * #496 bumping package versions for netcore3 * Features/buildupdate (#498) * #496 using ... — committed to AppMetrics/AppMetrics by alhardy 5 years ago
- stable 4.0.0 release (#555) * updating app metrics version in global build ref * #494 Decommissiong health check functionality due to microsoft implementation * #496 bumping package versions fo... — committed to AppMetrics/AppMetrics by alhardy 4 years ago
Any news about this? I think this one will become popular, as people are starting to migrate to core 3.0 now it’s officialy released.
As @stukselbax said here: https://github.com/AppMetrics/AppMetrics/pull/507#issuecomment-581852762
There’s more work to be done, synchronous
Writecalls which need to be switched toWriteAsyncetcGoing to start picking up core 3.0 related work, no ETA, any help appreciated, there’s a new features/4.0.0 branch
It seems that
Newtonsoft.Json.JsonWriterisn’t async, called fromApp.Metrics.Health.Formatters.Json.HealthStatusJsonOutputFormatter.WriteAsync:InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.`
Just ran into this issue while migrating to .net core 3
I know this is not the answer you’d like, but you should move away from OpenMetrics towards Opet Telemetry, at least for new projects.