package com.tts.jtcollector;
import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NoRouteToHostException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
/**
* Created with IntelliJ IDEA.
* User: wendybartlett
* Date: 10/8/13
* Time: 11:31 AM
* To change this template use File | Settings | File Templates.
*/
public class MetricSender extends Thread {
private static Logger log = Logger.getLogger(MetricSender.class.getName());
private List<String> metricList;
private static List<String> metricListForTSD;
static Producer<Integer,byte[]> producer = null;
private static Schema writer_schema = null;
private static String local_hostname = null;
private boolean time_to_shutdown = false;
private static Properties producer_props = null;
public MetricSender(List<String> listOfMetrics, Properties producer_props, Schema schema) throws UnknownHostException {
metricList = listOfMetrics;
producer = new Producer<Integer, byte[]>(new ProducerConfig(producer_props));
writer_schema = schema;
local_hostname = java.net.InetAddress.getLocalHost().getHostName().toLowerCase();
this.producer_props = producer_props;
}
public MetricSender(List<String> listOfMetrics, Properties producer_props, List<String> listOfMetricsForTSD) throws UnknownHostException {
metricList = listOfMetrics;
if (producer_props != null)
producer = new Producer<Integer, byte[]>(new ProducerConfig(producer_props));
if (listOfMetricsForTSD != null)
metricListForTSD = listOfMetricsForTSD;
local_hostname = java.net.InetAddress.getLocalHost().getHostName().toLowerCase();
}
public void freeResources() {
time_to_shutdown = true;
}
public static void sendMessage(String metrics_line) {
byte[] msg = null;
String mess = "";
if (writer_schema != null) {
try {
// Got a schema, let's encode
GenericRecord record = new GenericData.Record(writer_schema);
// Add hostname to metric and parse
String[] parts = (metrics_line + " hostname=" + local_hostname).split(" ");
List<String> tag_list = new LinkedList<String>(Arrays.asList(parts));
log.trace(tag_list);
record.put("metric_id", tag_list.get(0));
record.put("timestamp", Long.parseLong(tag_list.get(1)));
record.put("value", tag_list.get(2));
List<String> tags = tag_list.subList(3, tag_list.size());
record.put("tags", tags);
msg = JTCollector.avro.encodeKafkaMessage(record, JTCollector.metrics_topic,
JTCollector.metrics_schema_id, true);
if (msg == null) {
JTCollector.avroEncodeFailure.incrementAndGet();
log.error("Unable to encode jtcollector metric message");
return;
}
} catch(Exception e) {
log.error("Unable to Avro encode jtcollector message", e);
return;
}
} else {
// No schema, so let's see if we are producing to a TSD
mess = (metrics_line + " hostname=" + local_hostname);
try {
msg = mess.getBytes();
if (metricListForTSD != null) {
// Add metric to TSD queue
synchronized (metricListForTSD) {
metricListForTSD.add(mess);
}
}
} catch (Exception e) {
log.error("Unable to produce message to TSD", e);
return;
}
}
// Check to see if we are sending metric to Kafka
try {
if (producer_props != null) {
if (producer == null) {
producer = new Producer<Integer, byte[]>(new ProducerConfig(producer_props));
}
producer.send(new KeyedMessage<Integer, byte[]>(JTCollector.metrics_topic, msg));
JTCollector.numMessagesSent.incrementAndGet();
}
} catch (Exception e) {
log.error("Unable to produce metric to Kafka", e);
return;
}
}
public void run() {
while(!time_to_shutdown) {
boolean metricsWaiting;
synchronized (metricList) {
if (metricList.size() > 0)
metricsWaiting = true;
else
metricsWaiting = false;
}
if (metricsWaiting) {
String currentMetric = "";
synchronized (metricList) {
for (String metric : metricList) {
currentMetric = metric;
metricList.remove(metric);
if (currentMetric.length() > 0) {
break;
}
}
}
if (currentMetric.length() > 0) {
// Got valid metric, let's send it
sendMessage(currentMetric);
}
} else {
try {
sleep(500);
} catch (InterruptedException e) {
time_to_shutdown = true;
}
}
}
}
}