org.jmxtrans.agent.GraphiteUdpOutputWriter 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 static org.jmxtrans.agent.graphite.GraphiteOutputWriterCommonSettings.*;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.jmxtrans.agent.graphite.GraphiteMetricMessageBuilder;
import org.jmxtrans.agent.util.net.HostAndPort;
import org.jmxtrans.agent.util.time.Clock;
import org.jmxtrans.agent.util.time.SystemCurrentTimeMillisClock;
/**
* Output writer for writing to Graphite using UDP.
*
* @author Kristoffer Erlandsson
*/
public class GraphiteUdpOutputWriter extends AbstractOutputWriter {
final static Charset CHARSET_FOR_UDP_PACKET = Charset.forName("UTF-8");
private HostAndPort graphiteServerHostAndPort;
private UdpMessageSender messageSender;
private Clock clock;
private GraphiteMetricMessageBuilder messageBuilder;
@Override
public void postConstruct(Map settings) {
super.postConstruct(settings);
graphiteServerHostAndPort = getHostAndPort(settings);
messageBuilder = new GraphiteMetricMessageBuilder(getConfiguredMetricPrefixOrNull(settings));
messageSender = new UdpMessageSender(graphiteServerHostAndPort);
clock = new SystemCurrentTimeMillisClock();
logger.log(getInfoLevel(), "GraphiteUdpOutputWriter is configured with " + graphiteServerHostAndPort
+ ", metricPathPrefix=" + messageBuilder.getPrefix());
}
@Override
public void writeInvocationResult(String invocationName, Object value) throws IOException {
writeQueryResult(invocationName, null, value);
}
@Override
public void writeQueryResult(String metricName, String metricType, Object value) throws IOException {
String msg = messageBuilder.buildMessage(metricName, value, TimeUnit.SECONDS.convert(clock.getCurrentTimeMillis(), TimeUnit.MILLISECONDS));
logMessageIfTraceLoggable(msg);
tryWriteMsg(msg + "\n");
}
private void logMessageIfTraceLoggable(String msg) {
if (logger.isLoggable(getTraceLevel())) {
logger.log(getTraceLevel(), "Send '" + msg + "' to " + graphiteServerHostAndPort);
}
}
private void tryWriteMsg(String msg) throws IOException {
try {
messageSender.send(msg);
} catch (IOException e) {
logger.log(Level.WARNING, "Exception sending '" + msg + "' to " + graphiteServerHostAndPort, e);
throw e;
}
}
@Override
public void preDestroy() {
super.preDestroy();
if (messageSender != null) {
messageSender.close();
}
}
@Override
public String toString() {
return "GraphiteUdpOutputWriter{" +
", " + graphiteServerHostAndPort +
", metricPathPrefix='" + messageBuilder.getPrefix() + "'" +
"}";
}
/** Test hook */
void setClock(Clock clock) {
this.clock = clock;
}
private static class UdpMessageSender {
private final DatagramSocket clientSocket;
private final HostAndPort hostAndPort;
public UdpMessageSender(HostAndPort hostAndPort) {
this.hostAndPort = hostAndPort;
try {
clientSocket = new DatagramSocket();
} catch (SocketException e) {
throw new RuntimeException("Failed to create DatagramSocket", e);
}
}
public void send(String msg) throws IOException {
DatagramPacket packetToSend = createUdpPacket(msg);
clientSocket.send(packetToSend);
}
private DatagramPacket createUdpPacket(String msg) throws SocketException {
byte[] messageBytes = msg.getBytes(CHARSET_FOR_UDP_PACKET);
InetSocketAddress adress = new InetSocketAddress(hostAndPort.getHost(), hostAndPort.getPort());
return new DatagramPacket(messageBytes, messageBytes.length, adress);
}
public void close() {
clientSocket.close();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy