Have a question regarding Prometheus metrics in Tapir and ZIO. I have a simple code:
val metrics = PrometheusMetrics.default[Task]()
val options: ZioHttpServerOptions[Any] = ZioHttpServerOptions
.customiseInterceptors
.metricsInterceptor(metrics.metricsInterceptor())
.options
and it works correct when I call localhost:8080/metrics, I see metrics.
But when I added default error handler:
val metrics = PrometheusMetrics.default[Task]()
def failureResponse(msg: String): ValuedEndpointOutput[_]=
ValuedEndpointOutput(jsonBody[MyFailure], MyFailure(msg))
val options: ZioHttpServerOptions[Any] = ZioHttpServerOptions
.customiseInterceptors
.metricsInterceptor(metrics.metricsInterceptor())
.defaultHandlers(failureResponse, notFoundWhenRejected = true)
.options
It doesn't work. Instead of metrics I see now error (404) which was caught during request to localhost:8080/metrics. Honestly, don't know why. Is it possible to fix it somehow and keep error handler along with metrics interceptor?
EDIT: Metrics endpoint:
def metricsEndpoint = ZioHttpInterpreter(options).toHttp(metrics.metricsEndpoint)
This problem is most probably due to separately interpreting the "main" endpoints and the metrics endpoint as ZIO Http's
Httpvalue.Consider the following:
If the
notFoundWhenRejected = trueoption is used, when the request/metricscomes in, it is first handled bymainHttp. However, that value doesn't know how to handle this request - hence it is rejected. But as we specified the mentioned option, rejections are turned into 404s, hence the answer.The default value for that option is
false. In this situation, the/metricsrequest is rejected by themainHttpvalue, but this isn't converted into a 404 response, instead processing continues withmetricsHttp.The proper solution, to have both
/metricsworking, and thenotFoundWhenRejected = trueoption, is to interpret all endpoints at once. Then, the 404 will be returned only when none of the endpoint (neither the main, nor the metrics one) matches the request: