500 Errors showing as 200 in /metrics on ASP.NET Core 2.2
See original GitHub issueI have an ASP.NET Core 2.2 project with one controller that works like this:
- Get() method = 200
- Post() method = 500 (throws exception)
- Put() method = 400 (returns bad request)
When testing I am confirming the Post method returns a 500 via CURL, but in /metrics it shows up as a 200 for the ValuesController Post method.
Output of /metrics:
http_request_duration_seconds_sum{code="200",method="POST",controller="Values",action="Post"} 0.1010758
http_request_duration_seconds_count{code="200",method="POST",controller="Values",action="Post"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.001"} 0
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.002"} 2
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.004"} 2
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.008"} 2
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.016"} 2
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.032"} 2
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.064"} 2
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.128"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.256"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="0.512"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="1.024"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="2.048"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="4.096"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="8.192"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="16.384"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="32.768"} 3
http_request_duration_seconds_bucket{code="200",method="POST",controller="Values",action="Post",le="+Inf"} 3
Controller:
// GET api/values
[HttpGet()]
public ActionResult Get()
{
Ok();
}
[HttpPost()]
public ActionResult<IEnumerable<string>> Post(string text)
{
_exceptionCount++;
throw new Exception($"I am exception number {_exceptionCount}");
}
[HttpPut()]
public ActionResult Put()
{
return BadRequest();
}
Curl example shows 500 error:
C02XX041JGH7:~ lin.meyer$ echo '{"text": "Hello **world**!"}' | curl -X POST -d @- --verbose http://localhost:5000/api/values
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 5000 (#0)
> POST /api/values HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 28
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 28 out of 28 bytes
< HTTP/1.1 500 Internal Server Error
< Date: Mon, 15 Jul 2019 17:47:06 GMT
< Server: Kestrel
< Content-Length: 0
<
* Connection #0 to host localhost left intact
Startup:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHttpMetrics(); // Adds basic HTTP metrics to Prometheus /metrics (must be before UseMvc)
app.UseMetricServer();
app.UseHealthChecks("/health");
app.UseMvc();
}
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (3 by maintainers)
Top Results From Across the Web
Prometheus reports 200 but Response is actually 500
The logs and Postman clearly show a 500 response, so I am trying to understand why Prometheus doesn't record the status correctly.
Read more >What is the solution to resolve the HTTP 500 Internal ...
NET 7 and deploying it on IIS with Windows 2019, I encounter the error 500. However, when using Core 2.2, the platform runs...
Read more >Untitled
Asp.net core return internal server error 500 WebDec 20, 2022 · HTTP/1.1 500 Internal Server Error ... 500 Errors showing as 200 in...
Read more >Using the Microsoft.AspNetCore.HealthChecks Package
Typically you will return a status code of 200 if everything is good, and any non-2xx code means something went wrong. For example,...
Read more >Excluding health check endpoints from Serilog request ...
You can set up a simple, dumb, health check that returns a 200 OK response to every request, to let Kubernetes know your...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I always use the ExceptionHandlerMiddleware after prometheus-net and I don’t see this behaviour
And prometheus-net seems to report the proper thing. Do I miss something ?
If you use an explicit exception handler middleware and configure it after the metrics middleware, that’s fine. However, the problem occurs when you either configure the exception handler before metrics or when you do not configure one at all (and let ASP.NET fallback to its default logic, which emits a 500).
After doing some digging in the ASP.NET Core source, I have not found a meaningful way to improve the behavior here, so I will fall back to documenting this aspect. In the end, ASP.NET Core is a pipeline and the nature of the pipelined processing must be understood for actual behavior to match expected behavior. This situation is one of the sufficiently nontrivial ones where it starts to matter.