package com.sf.prometheus; import com.google.common.base.Charsets; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.io.CharStreams; import com.google.common.io.Closeables; import com.squareup.okhttp.OkHttpClient; import retrofit.ErrorHandler; import retrofit.RestAdapter; import retrofit.RetrofitError; import retrofit.client.OkClient; import retrofit.client.Response; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; public class PrometheusQuery { private static final int MaxPoints = 800; private static class MyErrorHandler implements ErrorHandler { @Override public Throwable handleError(final RetrofitError cause) { Response r = cause.getResponse(); if (r != null && r.getStatus() >= 400) { InputStreamReader reader = null; try { reader = new InputStreamReader(r.getBody().in(), Charsets.UTF_8); return new RuntimeException(CharStreams.toString(reader)); } catch (IOException e) { e.printStackTrace(); } finally { Closeables.closeQuietly(reader); } } return cause; } } private PrometheusQueryService agent; public PrometheusQuery(String url) throws RuntimeException { Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "The URL may not be null or empty."); try { String hostPart = new URI(url).getHost(); // Validate the url. InetAddress.getByName(hostPart); } catch (URISyntaxException e) { throw new IllegalArgumentException("The given URI is not valid " + e.getMessage()); } catch (UnknownHostException e) { throw new IllegalArgumentException("The given URI is not valid " + e.getMessage()); } OkHttpClient okHttpClient = new OkHttpClient(); RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(url) .setErrorHandler(new MyErrorHandler()) .setClient(new OkClient(okHttpClient)) .build(); this.agent = restAdapter.create(PrometheusQueryService.class); } public PrometheusQueryService.Result query(String query, long startMS, long endMS) { long period = endMS - startMS; long step = 5; // default 5 seconds. if (period / 1000 >= MaxPoints) { step = period / 1000 / MaxPoints; } return agent.query( query, String.valueOf(startMS / 1000), String.valueOf(endMS / 1000), String.format("%ds", step) ); } }