У нас есть приложение Micronaut, в котором я хотел бы иметь некоторые дополнительные метрики. Мы добавили фильтр
@Filter("/**")
class MetricsHttpRequestFilter(private val meterRegistry: MeterRegistry) :
OncePerRequestHttpServerFilter(), HttpServerFilter {
//...
}
чтобы достичь этого. В этом фильтре я хотел бы прочитать Content-Length
ответа, чтобы иметь возможность создавать гистограммы по размеру ответа. У меня есть рабочий код, который правильно читает размеры ответов, но сомневаюсь, что это правильный способ хранения вещей.
немного глубже в коде:
private fun success(httpResponse: HttpResponse<*>, httpMethod: String, requestPath: String) {
val tags = getTags(httpResponse, httpMethod, requestPath)
// TODO use content length header instead
val size = if (httpResponse.getBody(ByteArray::class.java).isPresent()) {
httpResponse.getBody(ByteArray::class.java).get().size
} else {
0
}
DistributionSummary.builder(metricName)
.description("the response sizes of http requests")
.tags(tags)
.baseUnit("bytes")
.maximumExpectedValue(1000000)
.register(meterRegistry)
.record(size.toDouble())
}
Мы хотели использовать httpResponse.contentLength
напрямую, но тот всегда возвращает -1
, хотя в конце ответа есть заголовок Content-Length
с заданным правильным размером (при использовании curl на остальном интерфейсе).
Я сомневаюсь, что это хорошая идея - получить тело в виде байтового массива, так как у нас есть некоторые конечные точки, которые работают с издателями, и среда обычно (насколько я понимаю) реактивна, что может означать, что ответ на самом деле еще не полностью обработан, когда Заголовки отправляются. Мы в порядке, так как в этих случаях мы не получаем размер ответа.
Изменение порядка фильтров не помогло получить длину контента. Есть идеи? Также помогут подсказки о том, как / где создается заголовок Content-Length
в Micronaut!