org.jmxtrans.agent.LibratoWriter Maven / Gradle / Ivy
/*
* Copyright (c) 2010-2013 the original author or authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package org.jmxtrans.agent;
import org.jmxtrans.agent.util.ConfigurationUtils;
import org.jmxtrans.agent.util.StandardCharsets2;
import org.jmxtrans.agent.util.StringUtils2;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
/**
* OutputWriter for Librato.
*/
public class LibratoWriter extends AbstractOutputWriter implements OutputWriter {
public static final String DEFAULT_LIBRATO_API_URL = "https://metrics-api.librato.com/v1/metrics";
public static final String SETTING_USERNAME = "username";
public static final String SETTING_TOKEN = "token";
private String username;
private String basicAuthentication;
private String httpUserAgent;
private URL url;
private final AtomicInteger exceptionCounter = new AtomicInteger();
@Override
public synchronized void postConstruct(Map settings) {
final String username = ConfigurationUtils.getString(settings, SETTING_USERNAME);
final String token = ConfigurationUtils.getString(settings, SETTING_TOKEN);
if (username == null || token == null) {
throw new RuntimeException("Username and/or token cannot be null");
}
this.username = username;
basicAuthentication = DatatypeConverter.printBase64Binary((username + ":" + token).getBytes(StandardCharsets2.US_ASCII));
httpUserAgent = "jmxtrans-agent/2 " + "(" +
System.getProperty("java.vm.name") + "/" + System.getProperty("java.version") + "; " +
System.getProperty("os.name") + "-" + System.getProperty("os.arch") + "/" + System.getProperty("os.version")
+ ")";
try {
url = new URL(DEFAULT_LIBRATO_API_URL);
} catch (MalformedURLException e) {
logger.info("Malformed url");
}
logger.info(String.format("LibratoWriter[username=%s, token=***]", username));
}
@Override
public void postCollect() throws IOException {
}
@Override
public void writeInvocationResult(String invocationName, Object value) throws IOException {
writeQueryResult(invocationName, null, value);
}
@Override
public synchronized void writeQueryResult(String metricName, String metricType, Object value) throws IOException {
HttpURLConnection urlConnection;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("content-type", "application/json; charset=utf-8");
urlConnection.setRequestProperty("Authorization", "Basic " + basicAuthentication);
urlConnection.setRequestProperty("User-Agent", httpUserAgent);
Writer out = new OutputStreamWriter(urlConnection.getOutputStream(), StandardCharsets2.UTF_8);
writeQueryResult(metricName, metricType, value, out);
out.flush();
out.close();
int responseCode = urlConnection.getResponseCode();
if (responseCode != 200) {
exceptionCounter.incrementAndGet();
logger.info(String.format("Failure %d:'%s' to send result to Librato server '%s', username %s", responseCode, urlConnection.getResponseMessage(), url, username));
}
} catch (RuntimeException e) {
exceptionCounter.incrementAndGet();
logger.info(String.format("Failure to send result to Librato server '%s' username %s", url, username));
}
}
protected void writeQueryResult(String metricName, String metricType, Object value, Writer out) throws IOException {
String libratoMetricsType = "gauge".equalsIgnoreCase(metricType) || "g".equalsIgnoreCase(metricType) ? "gauges" : "counters";
out.write("{");
out.write("\"" + libratoMetricsType + "\": [");
out.write("{");
out.write("\"name\": \"" + metricName + "\"");
out.write(",");
out.write("\"value\":");
if (value == null) {
out.write("null");
} else if (value instanceof Number) {
out.write(value.toString());
} else if (value instanceof String) {
out.write("\"" + ((String) value).replaceAll("\"", "\\\"") + "\"");
} else {
String valueAsString = value.toString();
if (logger.isLoggable(Level.FINE)) {
logger.warning("warning: no converter found for metric \"" + metricName + "\" with value type \"" + value.getClass() + "\". Use toString() on \"" + StringUtils2.abbreviate(valueAsString, 20) + "\"");
}
out.write(valueAsString);
}
out.write("}");
out.write("]");
out.write("}");
}
public int getExceptionCounter() {
return exceptionCounter.get();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy