package org.atomnuke.collectd.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.time.FastDateFormat;
import org.atomnuke.atom.model.Category;
import org.atomnuke.atom.model.builder.CategoryBuilder;
import org.atomnuke.atom.model.builder.ContentBuilder;
import org.atomnuke.atom.model.builder.EntryBuilder;
import org.atomnuke.atom.model.builder.IdBuilder;
import org.atomnuke.atom.model.builder.PublishedBuilder;
import org.atomnuke.collectd.command.PutValCommand;
import org.atomnuke.collectd.command.PutValParser;
import org.atomnuke.util.source.QueueSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author zinic
*/
public class CollectdSinkServlet extends HttpServlet {
private static final Logger LOG = LoggerFactory.getLogger(CollectdSinkServlet.class);
private static final String JSON_CONTENT_TEMPLATE = "{\"timestamp\" : \"$\", \"value\" : \"$\"}";
private static final String COLLECTD_PLUGIN_SCHEME = "collectd.stats.plugin";
private static final String COLLECTD_TYPE_SCHEME = "collectd.stats.type";
private static final String COLLECTD_SCHEME = "collectd";
private static final String PATH_SEPERATOR = "/";
private final QueueSource queueSource;
private final boolean debug;
public CollectdSinkServlet(QueueSource queueSource, boolean debug) {
this.queueSource = queueSource;
this.debug = debug;
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(req.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
final PutValCommand parsedValue = PutValParser.instance().parse(line);
if (parsedValue == null) {
LOG.debug("Bad putval command: " + line);
continue;
}
final EntryBuilder entryBuilder = new EntryBuilder();
// Set the ID
entryBuilder.setId(new IdBuilder().setValue(UUID.randomUUID().toString()).build());
// Put in the proper categories
// Plugin category
entryBuilder.addCategory(new CategoryBuilder().setScheme(COLLECTD_PLUGIN_SCHEME).setTerm(parsedValue.plugin()).build());
// Type category
entryBuilder.addCategory(new CategoryBuilder().setScheme(COLLECTD_TYPE_SCHEME).setTerm(parsedValue.type()).build());
// Metrics category
entryBuilder.addCategory(buildMetricsCat(parsedValue));
// Set the publication time
entryBuilder.setPublished(new PublishedBuilder().setValue(FastDateFormat.getInstance().format(Calendar.getInstance())).build());
// Set the content
entryBuilder.setContent(new ContentBuilder()
.setType("application/json")
.setValue(JSON_CONTENT_TEMPLATE.replaceFirst("\\$", parsedValue.timestamp()).replaceFirst("\\$", parsedValue.value())).build());
// Queue the entry up
queueSource.put(entryBuilder.build());
}
bufferedReader.close();
}
private Category buildMetricsCat(PutValCommand parsedValue) {
final StringBuilder catBuilder = new StringBuilder(parsedValue.host());
catBuilder.append(PATH_SEPERATOR).append(parsedValue.type());
if (parsedValue.pluginInstance() != null) {
catBuilder.append(PATH_SEPERATOR).append(parsedValue.pluginInstance());
}
if (parsedValue.typeInstance() != null) {
catBuilder.append(PATH_SEPERATOR).append(parsedValue.typeInstance());
}
if (debug) {
LOG.info("Emitting: " + COLLECTD_SCHEME + "." + catBuilder.toString() + " - Value: " + parsedValue.value());
}
return new CategoryBuilder().setScheme(COLLECTD_SCHEME).setTerm(catBuilder.toString()).build();
}
}