All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jmxtrans.agent.GraphiteUdpOutputWriter Maven / Gradle / Ivy

There is a newer version: 1.2.11
Show newest version
/*
 * 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