io.prometheus.client.bridge.Graphite Maven / Gradle / Ivy
Show all versions of simpleclient_graphite_bridge Show documentation
package io.prometheus.client.bridge;
import io.prometheus.client.Collector;
import io.prometheus.client.CollectorRegistry;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Export metrics in the Graphite plaintext format.
*
*
* {@code
* Graphite g = new Graphite("localhost", 2003);
* // Push the default registry once.
* g.push(CollectorRegistry.defaultRegistry);
*
* // Push the default registry every 60 seconds.
* Thread thread = g.start(CollectorRegistry.defaultRegistry, 60);
* // Stop pushing.
* thread.interrupt();
* thread.join();
* }
*
*
*/
public class Graphite {
private static final Logger logger = Logger.getLogger(Graphite.class.getName());
private final String host;
private final int port;
private static final Pattern INVALID_GRAPHITE_CHARS = Pattern.compile("[^a-zA-Z0-9_-]");
/**
* Construct a Graphite Bridge with the given host:port.
*/
public Graphite(String host, int port) {
this.host = host;
this.port = port;
}
/**
* Push samples from the given registry to Graphite.
*/
public void push(CollectorRegistry registry) throws IOException {
Socket s = new Socket(host, port);
BufferedWriter writer = new BufferedWriter(new PrintWriter(s.getOutputStream()));
Matcher m = INVALID_GRAPHITE_CHARS.matcher("");
long now = System.currentTimeMillis() / 1000;
for (Collector.MetricFamilySamples metricFamilySamples: Collections.list(registry.metricFamilySamples())) {
for (Collector.MetricFamilySamples.Sample sample: metricFamilySamples.samples) {
m.reset(sample.name);
writer.write(m.replaceAll("_"));
for (int i = 0; i < sample.labelNames.size(); ++i) {
m.reset(sample.labelValues.get(i));
writer.write("." + sample.labelNames.get(i) + "." + m.replaceAll("_"));
}
writer.write(" " + sample.value + " " + now + "\n");
}
}
writer.close();
s.close();
}
/**
* Push samples from the given registry to Graphite every minute.
*/
public Thread start(CollectorRegistry registry) {
return start(registry, 60);
}
/**
* Push samples from the given registry to Graphite at the given interval.
*/
public Thread start(CollectorRegistry registry, int intervalSeconds) {
Thread thread = new PushThread(registry, intervalSeconds);
thread.setDaemon(true);
thread.start();
return thread;
}
private class PushThread extends Thread {
private final CollectorRegistry registry;
private final int intervalSeconds;
PushThread(CollectorRegistry registry, int intervalSeconds) {
this.registry = registry;
this.intervalSeconds = intervalSeconds;
}
public void run() {
long waitUntil = System.currentTimeMillis();
while (true) {
try {
push(registry);
} catch (IOException e) {
logger.log(Level.WARNING, "Exception " + e + " pushing to " + host + ":" + port, e);
}
long now = System.currentTimeMillis();
// We may skip some pushes if we're falling behind.
while (now >= waitUntil) {
waitUntil += intervalSeconds * 1000;
}
try {
Thread.sleep(waitUntil - now);
} catch (InterruptedException e) {
return;
}
}
}
}
}