package com.codahale.metrics.graphite;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.SocketFactory;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.Charset;

import static java.nio.charset.StandardCharsets.UTF_8;

A client to a Carbon server via TCP.
/** * A client to a Carbon server via TCP. */
public class Graphite implements GraphiteSender { // this may be optimistic about Carbon/Graphite private final String hostname; private final int port; private final InetSocketAddress address; private final SocketFactory socketFactory; private final Charset charset; private Socket socket; private Writer writer; private int failures; private static final Logger LOGGER = LoggerFactory.getLogger(Graphite.class);
Creates a new client which connects to the given address using the default SocketFactory.
Params:
  • hostname – The hostname of the Carbon server
  • port – The port of the Carbon server
/** * Creates a new client which connects to the given address using the default * {@link SocketFactory}. * * @param hostname The hostname of the Carbon server * @param port The port of the Carbon server */
public Graphite(String hostname, int port) { this(hostname, port, SocketFactory.getDefault()); }
Creates a new client which connects to the given address and socket factory.
Params:
  • hostname – The hostname of the Carbon server
  • port – The port of the Carbon server
  • socketFactory – the socket factory
/** * Creates a new client which connects to the given address and socket factory. * * @param hostname The hostname of the Carbon server * @param port The port of the Carbon server * @param socketFactory the socket factory */
public Graphite(String hostname, int port, SocketFactory socketFactory) { this(hostname, port, socketFactory, UTF_8); }
Creates a new client which connects to the given address and socket factory using the given character set.
Params:
  • hostname – The hostname of the Carbon server
  • port – The port of the Carbon server
  • socketFactory – the socket factory
  • charset – the character set used by the server
/** * Creates a new client which connects to the given address and socket factory using the given * character set. * * @param hostname The hostname of the Carbon server * @param port The port of the Carbon server * @param socketFactory the socket factory * @param charset the character set used by the server */
public Graphite(String hostname, int port, SocketFactory socketFactory, Charset charset) { this.hostname = hostname; this.port = port; this.address = null; this.socketFactory = socketFactory; this.charset = charset; }
Creates a new client which connects to the given address using the default SocketFactory.
Params:
  • address – the address of the Carbon server
/** * Creates a new client which connects to the given address using the default * {@link SocketFactory}. * * @param address the address of the Carbon server */
public Graphite(InetSocketAddress address) { this(address, SocketFactory.getDefault()); }
Creates a new client which connects to the given address and socket factory.
Params:
  • address – the address of the Carbon server
  • socketFactory – the socket factory
/** * Creates a new client which connects to the given address and socket factory. * * @param address the address of the Carbon server * @param socketFactory the socket factory */
public Graphite(InetSocketAddress address, SocketFactory socketFactory) { this(address, socketFactory, UTF_8); }
Creates a new client which connects to the given address and socket factory using the given character set.
Params:
  • address – the address of the Carbon server
  • socketFactory – the socket factory
  • charset – the character set used by the server
/** * Creates a new client which connects to the given address and socket factory using the given * character set. * * @param address the address of the Carbon server * @param socketFactory the socket factory * @param charset the character set used by the server */
public Graphite(InetSocketAddress address, SocketFactory socketFactory, Charset charset) { this.hostname = null; this.port = -1; this.address = address; this.socketFactory = socketFactory; this.charset = charset; } @Override public void connect() throws IllegalStateException, IOException { if (isConnected()) { throw new IllegalStateException("Already connected"); } InetSocketAddress address = this.address; // the previous dns retry logic did not work, as address.getAddress would always return the cached value // this version of the simplified logic will always cause a dns request if hostname has been supplied. // InetAddress.getByName forces the dns lookup // if an InetSocketAddress was supplied at create time that will take precedence. if (address == null || hostname != null) { address = new InetSocketAddress(InetAddress.getByName(hostname), port); } if (address.getAddress() == null) { throw new UnknownHostException(address.getHostName()); } this.socket = socketFactory.createSocket(address.getAddress(), address.getPort()); this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), charset)); } @Override public boolean isConnected() { return socket != null && socket.isConnected() && !socket.isClosed(); } @Override public void send(String name, String value, long timestamp) throws IOException { try { writer.write(sanitize(name)); writer.write(' '); writer.write(sanitize(value)); writer.write(' '); writer.write(Long.toString(timestamp)); writer.write('\n'); this.failures = 0; } catch (IOException e) { failures++; throw e; } } @Override public int getFailures() { return failures; } @Override public void flush() throws IOException { if (writer != null) { writer.flush(); } } @Override public void close() throws IOException { try { if (writer != null) { writer.close(); } } catch (IOException ex) { LOGGER.debug("Error closing writer", ex); } finally { this.writer = null; } try { if (socket != null) { socket.close(); } } catch (IOException ex) { LOGGER.debug("Error closing socket", ex); } finally { this.socket = null; } } protected String sanitize(String s) { return GraphiteSanitize.sanitize(s); } }