com.googlecode.jmxtrans.model.output.TCollectorUDPWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.jmxtrans.model.output.TCollectorUDPWriter.java

Source

/**
 * The MIT License
 * Copyright  2010 JmxTrans team
 *
 * 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 com.googlecode.jmxtrans.model.output;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.googlecode.jmxtrans.model.Query;
import com.googlecode.jmxtrans.model.Result;
import com.googlecode.jmxtrans.model.Server;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.googlecode.jmxtrans.exceptions.LifecycleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;

/**
 * {@link com.googlecode.jmxtrans.model.OutputWriter} for the <a href="https://github.com/OpenTSDB/tcollector/blob/master/collectors/0/udp_bridge.py">TCollector udp_bridge</a>.
 * Largely based on StatsDWriter and OpenTSDBWriter
 *
 * @author Kieren Hynd
 * @author Arthur Naseef
 */
public class TCollectorUDPWriter extends OpenTSDBGenericWriter {
    private static final Logger log = LoggerFactory.getLogger(TCollectorUDPWriter.class);

    protected SocketAddress address;
    protected DatagramSocket dgSocket;

    @JsonCreator
    public TCollectorUDPWriter(@JsonProperty("typeNames") ImmutableList<String> typeNames,
            @JsonProperty("booleanAsNumber") boolean booleanAsNumber, @JsonProperty("debug") Boolean debugEnabled,
            @JsonProperty("host") String host, @JsonProperty("port") Integer port,
            @JsonProperty("tags") Map<String, String> tags, @JsonProperty("tagName") String tagName,
            @JsonProperty("mergeTypeNamesTags") Boolean mergeTypeNamesTags,
            @JsonProperty("metricNamingExpression") String metricNamingExpression,
            @JsonProperty("addHostnameTag") boolean addHostnameTag,
            @JsonProperty("settings") Map<String, Object> settings)
            throws LifecycleException, UnknownHostException {
        super(typeNames, booleanAsNumber, debugEnabled, host, port, tags, tagName, mergeTypeNamesTags,
                metricNamingExpression, addHostnameTag, settings);
        log.warn("TCollectorUDPWriter is deprecated. Please use TCollectorUDPWriterFactory instead.");
    }

    /**
     * Do not add the hostname tag "host" with the name of the host by default since tcollector normally adds the
     * hostname.
     */
    @Override
    protected boolean getAddHostnameTagDefault() {
        return false;
    }

    /**
    * Write the results of the query.
     *
     * @param server
     * @param query   - the query and its results.
     * @param results
    */
    @Override
    public void internalWrite(Server server, Query query, ImmutableList<Result> results) throws Exception {
        this.startOutput();
        for (String resultString : messageFormatter.formatResults(results, server)) {
            log.debug("TCollectorUDP Message: {}", resultString);
            this.sendOutput(resultString);
        }
        this.finishOutput();
    }

    /**
     * Setup at start of the writer.
     */
    @Override
    public void prepareSender() throws LifecycleException {

        if (host == null || port == null) {
            throw new LifecycleException(
                    "Host and port for " + this.getClass().getSimpleName() + " output can't be null");
        }

        try {
            this.dgSocket = new DatagramSocket();
            this.address = new InetSocketAddress(host, port);
        } catch (SocketException sockExc) {
            log.error("Failed to create a datagram socket", sockExc);
            throw new LifecycleException(sockExc);
        }
    }

    /**
     * Send a single metric to TCollector.
     *
     * @param metricLine - the line containing the metric name, value, and tags for a single metric; excludes the
     *                   "put" keyword expected by OpenTSDB and the trailing newline character.
     */
    @Override
    protected void sendOutput(String metricLine) throws IOException {
        DatagramPacket packet;
        byte[] data;

        data = metricLine.getBytes("UTF-8");
        packet = new DatagramPacket(data, 0, data.length, this.address);

        this.dgSocket.send(packet);
    }

    public static Builder builder() {
        return new Builder();
    }

    public static final class Builder {
        private final ImmutableList.Builder<String> typeNames = ImmutableList.builder();
        private boolean booleanAsNumber;
        private Boolean debugEnabled;
        private String host;
        private Integer port;
        private final ImmutableMap.Builder<String, String> tags = ImmutableMap.builder();
        private String tagName;
        private Boolean mergeTypeNamesTags;
        private String metricNamingExpression;
        private boolean addHostnameTag;

        private Builder() {
        }

        public Builder addTypeNames(List<String> typeNames) {
            this.typeNames.addAll(typeNames);
            return this;
        }

        public Builder addTypeName(String typeName) {
            typeNames.add(typeName);
            return this;
        }

        public Builder setBooleanAsNumber(boolean booleanAsNumber) {
            this.booleanAsNumber = booleanAsNumber;
            return this;
        }

        public Builder setDebugEnabled(boolean debugEnabled) {
            this.debugEnabled = debugEnabled;
            return this;
        }

        public Builder setHost(String host) {
            this.host = host;
            return this;
        }

        public Builder setPort(int port) {
            this.port = port;
            return this;
        }

        public Builder addTag(String key, String value) {
            this.tags.put(key, value);
            return this;
        }

        public Builder addTags(Map<String, String> tags) {
            this.tags.putAll(tags);
            return this;
        }

        public Builder setTagName(String tagName) {
            this.tagName = tagName;
            return this;
        }

        public Builder setMergeTypeNamesTags(Boolean mergeTypeNamesTags) {
            this.mergeTypeNamesTags = mergeTypeNamesTags;
            return this;
        }

        public Builder setMetricNamingExpression(String metricNamingExpression) {
            this.metricNamingExpression = metricNamingExpression;
            return this;
        }

        public Builder setAddHostnameTag(Boolean addHostnameTag) {
            this.addHostnameTag = addHostnameTag;
            return this;
        }

        public TCollectorUDPWriter build() throws LifecycleException, UnknownHostException {
            return new TCollectorUDPWriter(typeNames.build(), booleanAsNumber, debugEnabled, host, port,
                    tags.build(), tagName, mergeTypeNamesTags, metricNamingExpression, addHostnameTag, null);
        }
    }

}