package com.sf.monitor.utils; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import com.sf.log.Logger; import com.sf.monitor.Config; import com.sf.monitor.Event; import com.sf.monitor.Resources; import com.sf.prometheus.PrometheusQueryService; import io.prometheus.client.metrics.Gauge; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class PrometheusUtils { private static final Logger log = new Logger(PrometheusUtils.class); private static final Map<String, Gauge> gauges = new HashMap<>(); private static Gauge getGauge(String name) { Gauge gauge = gauges.get(name); if (gauge != null) { return gauge; } synchronized (gauges) { gauge = Gauge.newBuilder().namespace(Config.config.prometheus.namespace).name(name).documentation( String.format( "mectric for %s model", name ) ).build(); gauges.put(name, gauge); } return gauge; } public static void saveEvents(String modelName, List<Event> events) { try { if (log.isDebugEnabled()) { log.debug("saveEvents, modelName: %s, events: %s", modelName, Resources.jsonMapper.writeValueAsString(events)); } } catch (Exception e) { } Gauge gauge = getGauge(modelName); for (Event event : events) { Gauge.Partial p = gauge.newPartial(); for (Map.Entry<String, String> e : event.tags.entrySet()) { p.labelPair(e.getKey(), e.getValue()); } p.labelPair("metricName", event.metricName); p.apply().set(event.metricValue); } } public static Map<String, List<Event>> getEvents( String modelName, Map<String, String> tags, DateTime start, DateTime end ) { String query = Config.config.prometheus.namespace + "_" + modelName; query += "{"; query += Joiner.on(",").join( Iterables.transform( tags.entrySet(), new Function<Map.Entry<String, String>, String>() { @Nullable @Override public String apply(Map.Entry<String, String> e) { return String.format("%s=\"%s\"", e.getKey(), e.getValue()); } } ) ); query += "}"; PrometheusQueryService.Result res = Resources.prometheusQuery.query(query, start.getMillis(), end.getMillis()); try { log.debug("getEvents, query: %s, res: %s", query, Resources.jsonMapper.writeValueAsString(res)); } catch (Exception e) { } if (!"success".equals(res.status)) { log.error("Prometheus query[%s] errorType: %s, error: %s", query, res.errorType, res.error); return Collections.emptyMap(); } Map<String, List<Event>> mappedEvents = new HashMap<>(); for (PrometheusQueryService.MetricItem item : res.data.result) { String metricName = item.metric.get("metricName"); if (StringUtils.isEmpty(metricName)) { continue; } List<Event> events = mappedEvents.get(metricName); if (events == null) { events = new ArrayList<>(); mappedEvents.put(metricName, events); } for (Object[] vs : item.values) { Event event = new Event(); event.metricName = metricName; event.timeStamp = (long) ((double) vs[0]) * 1000; event.metricValue = Double.valueOf((String) vs[1]); events.add(event); } } return mappedEvents; } }