com.yahoo.container.handler.metrics.PrometheusV1Handler Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.handler.metrics;
import ai.vespa.util.http.hc5.VespaHttpClientBuilder;
import com.yahoo.component.annotation.Inject;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.restapi.Path;
import com.yahoo.restapi.StringResponse;
import com.yahoo.yolean.Exceptions;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.logging.Level;
import static com.yahoo.container.handler.metrics.MetricsV2Handler.consumerQuery;
import static com.yahoo.jdisc.Response.Status.INTERNAL_SERVER_ERROR;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
/**
* @author Oracien
*/
public class PrometheusV1Handler extends HttpHandlerBase {
public static final String V1_PATH = "/prometheus/v1";
static final String VALUES_PATH = V1_PATH + "/values";
private static final int HTTP_CONNECT_TIMEOUT = 5000;
private static final int HTTP_SOCKET_TIMEOUT = 30000;
private final String metricsProxyUri;
private final CloseableHttpClient httpClient = createHttpClient();
@Inject
public PrometheusV1Handler(Executor executor,
MetricsProxyApiConfig config) {
super(executor);
metricsProxyUri = "http://localhost:" + config.metricsPort() + config.prometheusApiPath();
}
@Override
protected Optional doHandle(URI requestUri, Path apiPath, String consumer) {
if (apiPath.matches(V1_PATH)) return Optional.of(resourceListResponse(requestUri, List.of(VALUES_PATH)));
if (apiPath.matches(VALUES_PATH)) return Optional.of(valuesResponse(consumer));
return Optional.empty();
}
private HttpResponse valuesResponse(String consumer) {
try {
String uri = metricsProxyUri + consumerQuery(consumer);
String prometheusText = httpClient.execute(new HttpGet(uri), new BasicHttpClientResponseHandler());
return new StringResponse(prometheusText);
} catch (IOException e) {
log.warning("Unable to retrieve metrics from " + metricsProxyUri + ": " + Exceptions.toMessageString(e));
return new ErrorResponse(INTERNAL_SERVER_ERROR, e.getMessage());
}
}
private static CloseableHttpClient createHttpClient() {
return VespaHttpClientBuilder.custom().connectTimeout(HTTP_CONNECT_TIMEOUT, MILLISECONDS).apacheBuilder()
.setUserAgent("application-prometheus-receiver")
.setDefaultRequestConfig(RequestConfig.custom()
.setResponseTimeout(HTTP_SOCKET_TIMEOUT, MILLISECONDS)
.build())
.build();
}
@Override
public void destroy(){
super.destroy();
try {
httpClient.close();
}
catch (IOException e) {
log.log(Level.WARNING, "Failed closing http client", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy