incubator-blur-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From amccu...@apache.org
Subject git commit: JSONReporter now integrated with jetty server to provide metrics with history.
Date Thu, 18 Apr 2013 02:25:50 GMT
Updated Branches:
  refs/heads/0.1.5 828e592aa -> 5b9742eb8


JSONReporter now integrated with jetty server to provide metrics with history.


Project: http://git-wip-us.apache.org/repos/asf/incubator-blur/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-blur/commit/5b9742eb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-blur/tree/5b9742eb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-blur/diff/5b9742eb

Branch: refs/heads/0.1.5
Commit: 5b9742eb8422b6fbebe9dad1aff4b8f7f85af25b
Parents: 828e592
Author: Aaron McCurry <amccurry@gmail.com>
Authored: Wed Apr 17 22:24:54 2013 -0400
Committer: Aaron McCurry <amccurry@gmail.com>
Committed: Wed Apr 17 22:24:54 2013 -0400

----------------------------------------------------------------------
 .../apache/blur/thrift/ThriftBlurShardServer.java  |    5 +
 .../java/org/apache/blur/gui/HttpJettyServer.java  |    2 +-
 .../java/org/apache/blur/metrics/JSONReporter.java |  293 +++++++--------
 .../apache/blur/metrics/JSONReporterServlet.java   |   22 ++
 .../java/org/apache/blur/metrics/MetricInfo.java   |  177 +++++++++
 .../blur/metrics/ResetableCharArrayWriter.java     |   23 ++
 6 files changed, 364 insertions(+), 158 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/5b9742eb/src/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java
----------------------------------------------------------------------
diff --git a/src/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java
b/src/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java
index 699c6bd..a5abbc1 100644
--- a/src/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java
+++ b/src/blur-core/src/main/java/org/apache/blur/thrift/ThriftBlurShardServer.java
@@ -39,6 +39,7 @@ import static org.apache.blur.utils.BlurUtil.quietClose;
 
 import java.lang.management.ManagementFactory;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.blur.BlurConfiguration;
 import org.apache.blur.concurrent.SimpleUncaughtExceptionHandler;
@@ -57,6 +58,8 @@ import org.apache.blur.manager.indexserver.BlurServerShutDown.BlurShutdown;
 import org.apache.blur.manager.indexserver.DefaultBlurIndexWarmup;
 import org.apache.blur.manager.indexserver.DistributedIndexServer;
 import org.apache.blur.manager.writer.BlurIndexRefresher;
+import org.apache.blur.metrics.JSONReporter;
+import org.apache.blur.metrics.JSONReporterServlet;
 import org.apache.blur.store.blockcache.BlockCache;
 import org.apache.blur.store.blockcache.BlockDirectory;
 import org.apache.blur.store.blockcache.BlockDirectoryCache;
@@ -210,6 +213,8 @@ public class ThriftBlurShardServer extends ThriftServer {
     Iface iface = BlurUtil.recordMethodCallsAndAverageTimes(shardServer, Iface.class);
     WebAppContext context = httpServer.getContext();
     context.addServlet(new ServletHolder(new TServlet(new Blur.Processor<Blur.Iface>(iface),
new TJSONProtocol.Factory())), "/blur");
+    context.addServlet(new ServletHolder(new JSONReporterServlet()), "/livemetrics");
+    JSONReporter.enable("json-reporter", 1, TimeUnit.SECONDS, 60);
 
     int threadCount = configuration.getInt(BLUR_SHARD_SERVER_THRIFT_THREAD_COUNT, 32);
 

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/5b9742eb/src/blur-gui/src/main/java/org/apache/blur/gui/HttpJettyServer.java
----------------------------------------------------------------------
diff --git a/src/blur-gui/src/main/java/org/apache/blur/gui/HttpJettyServer.java b/src/blur-gui/src/main/java/org/apache/blur/gui/HttpJettyServer.java
index 9360471..d930e16 100644
--- a/src/blur-gui/src/main/java/org/apache/blur/gui/HttpJettyServer.java
+++ b/src/blur-gui/src/main/java/org/apache/blur/gui/HttpJettyServer.java
@@ -78,7 +78,7 @@ public class HttpJettyServer {
     context.setWar(warPath);
     context.setContextPath("/");
     context.setParentLoaderPriority(true);
-    context.addServlet(new ServletHolder(new LiveMetricsServlet()), "/livemetrics");
+//    context.addServlet(new ServletHolder(new LiveMetricsServlet()), "/livemetrics");
     context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
     context.addServlet(new ServletHolder(new LogServlet(blurLogFile)), "/logs");
 

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/5b9742eb/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporter.java
----------------------------------------------------------------------
diff --git a/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporter.java b/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporter.java
index 6c597a7..8ce7a70 100644
--- a/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporter.java
+++ b/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporter.java
@@ -2,9 +2,7 @@ package org.apache.blur.metrics;
 
 import java.io.IOException;
 import java.io.Writer;
-import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -14,12 +12,7 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.json.JSONException;
-import org.json.JSONObject;
 
-import com.google.common.collect.RowSortedTable;
-import com.google.common.collect.Table.Cell;
-import com.google.common.collect.TreeBasedTable;
 import com.yammer.metrics.Metrics;
 import com.yammer.metrics.core.Counter;
 import com.yammer.metrics.core.Gauge;
@@ -36,102 +29,86 @@ import com.yammer.metrics.stats.Snapshot;
 
 public class JSONReporter extends AbstractPollingReporter implements MetricProcessor<JSONReporter.Context>
{
 
+  private static final ResetableCharArrayWriter EMPTY = new ResetableCharArrayWriter() {
+    {
+      try {
+        write("[]");
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+  };
   private static Log LOG = LogFactory.getLog(JSONReporter.class);
 
   private Context context;
-  private Writer writer;
-  private final StringBuilder jsonOutputBuilder = new StringBuilder();
-  private static final AtomicReference<String> jsonData = new AtomicReference<String>("[]");
-
-  public static void enable(String name, long period, TimeUnit unit, long ttl, TimeUnit ttlUnit)
throws IOException {
-    enable(Metrics.defaultRegistry(), name, period, unit, ttl, ttlUnit);
+  private int _256K = 262144;
+  private ResetableCharArrayWriter writerInUse = new ResetableCharArrayWriter(_256K);
+  private ResetableCharArrayWriter writerWriting = new ResetableCharArrayWriter(_256K);
+  private static AtomicReference<ResetableCharArrayWriter> reading = new AtomicReference<ResetableCharArrayWriter>(
+      EMPTY);
+
+  public static void enable(String name, long period, TimeUnit unit, int numberOfElements)
throws IOException {
+    enable(Metrics.defaultRegistry(), name, period, unit, numberOfElements);
   }
 
-  public static void enable(MetricsRegistry metricsRegistry, String name, long period, TimeUnit
unit, long ttl,
-      TimeUnit ttlUnit) throws IOException {
-    JSONReporter reporter = new JSONReporter(metricsRegistry, name, ttl, ttlUnit);
+  public static void enable(MetricsRegistry metricsRegistry, String name, long period, TimeUnit
unit,
+      int numberOfElements) throws IOException {
+    JSONReporter reporter = new JSONReporter(metricsRegistry, name, numberOfElements);
     reporter.start(period, unit);
   }
 
-  public static String getJSONData() {
-    return jsonData.get();
+  public static void writeJSONData(Writer writer) throws IOException {
+    synchronized (reading) {
+      ResetableCharArrayWriter reader = reading.get();
+      writer.write(reader.getBuffer(), 0, reader.size());
+    }
   }
 
-  protected JSONReporter(MetricsRegistry registry, String name, long ttl, TimeUnit ttlUnit)
{
+  protected JSONReporter(MetricsRegistry registry, String name, int numberOfElements) {
     super(registry, name);
-    this.context = new Context(ttl, ttlUnit);
-    setupBuffer();
-  }
-
-  private void setupBuffer() {
-    writer = new Writer() {
-
-      @Override
-      public void write(char[] cbuf, int off, int len) throws IOException {
-        jsonOutputBuilder.append(cbuf, off, len);
-      }
-
-      @Override
-      public void flush() throws IOException {
-
-      }
-
-      @Override
-      public void close() throws IOException {
-
-      }
-    };
+    this.context = new Context(numberOfElements);
   }
 
   static class Context {
 
-    private final Map<MetricName, RowSortedTable<Long, String, Object>> numberTable;
+    private final Map<MetricName, MetricInfo> metricInfoMap = new HashMap<MetricName,
MetricInfo>();
     private final Map<MetricName, String> typeTable;
-    private final long ttl;
-    private Long time;
+    private final int numberOfElements;
+    private long time;
 
-    Context(long ttl, TimeUnit ttlUnit) {
-      this.numberTable = new HashMap<MetricName, RowSortedTable<Long, String, Object>>();
+    Context(int numberOfElements) {
       this.typeTable = new HashMap<MetricName, String>();
-      this.ttl = ttlUnit.toMillis(ttl);
+      this.numberOfElements = numberOfElements;
     }
 
-    RowSortedTable<Long, String, Object> getTable(MetricName metricName) {
-      RowSortedTable<Long, String, Object> table = numberTable.get(metricName);
-      if (table == null) {
-        table = TreeBasedTable.create();
-        numberTable.put(metricName, table);
-      }
-      return table;
-    }
-
-    Long getTime() {
+    long getTime() {
       return time;
     }
 
-    void setTime(Long time) {
+    void setTime(long time) {
       this.time = time;
     }
 
-    void cleanUpOldRecords() {
-      Collection<RowSortedTable<Long, String, Object>> values = numberTable.values();
-      for (RowSortedTable<Long, String, Object> table : values) {
-        Set<Cell<Long, String, Object>> cellSet = table.cellSet();
-        Iterator<Cell<Long, String, Object>> iterator = cellSet.iterator();
-        while (iterator.hasNext()) {
-          Cell<Long, String, Object> cell = iterator.next();
-          if (isOld(cell.getRowKey())) {
-            iterator.remove();
-          }
-        }
+    public MetricInfo getMetricInfo(MetricName name) {
+      MetricInfo info = metricInfoMap.get(name);
+      if (info == null) {
+        info = new MetricInfo(getName(name), typeTable.get(name), numberOfElements);
+        metricInfoMap.put(name, info);
       }
+      return info;
     }
 
-    private boolean isOld(long rowId) {
-      if (rowId + ttl < time) {
-        return true;
-      }
-      return false;
+    private String getName(MetricName metricName) {
+      // String group = metricName.getGroup();
+      // String name = metricName.getName();
+      // String scope = metricName.getScope();
+      // String type = metricName.getType();
+      // JSONObject jsonObject = new JSONObject();
+      // jsonObject.put("name", name);
+      // jsonObject.put("group", group);
+      // jsonObject.put("scope", scope);
+      // jsonObject.put("type", type);
+      return metricName.toString();
     }
   }
 
@@ -157,125 +134,127 @@ public class JSONReporter extends AbstractPollingReporter implements
MetricProce
           metric.processWith(this, name, context);
         }
       }
-      context.cleanUpOldRecords();
-      jsonOutputBuilder.setLength(0);
-      Set<Entry<MetricName, RowSortedTable<Long, String, Object>>> entrySet
= context.numberTable.entrySet();
-      jsonOutputBuilder.append('[');
-      for (Entry<MetricName, RowSortedTable<Long, String, Object>> entry : entrySet)
{
-        if (jsonOutputBuilder.length() != 1) {
-          jsonOutputBuilder.append(',');
+      ResetableCharArrayWriter writer = getWriter();
+      writer.reset();
+      Set<Entry<MetricName, MetricInfo>> entrySet = context.metricInfoMap.entrySet();
+      writer.append('[');
+      boolean flag = false;
+      for (Entry<MetricName, MetricInfo> entry : entrySet) {
+        if (flag) {
+          writer.append(',');
         }
-        updateJson(entry.getKey(), context.typeTable.get(entry.getKey()), entry.getValue());
+        entry.getValue().write(writer);
+        flag = true;
       }
-      jsonOutputBuilder.append(']');
-      jsonData.set(jsonOutputBuilder.toString());
+      writer.append(']');
+      swapWriter();
     } catch (Throwable t) {
       LOG.error("Unknown error during the processing of metrics.", t);
     }
   }
 
-  private void updateJson(MetricName name, String type, RowSortedTable<Long, String, Object>
table)
-      throws JSONException, IOException {
-    JSONObject jsonObject = new JSONObject();
-    jsonObject.put("name", getName(name));
-    jsonObject.put("type", type);
-
-    Set<String> columnLabels = table.columnKeySet();
-    Set<Entry<Long, Map<String, Object>>> entrySet = table.rowMap().entrySet();
-    JSONObject dataJsonObject = new JSONObject();
-
-    for (Entry<Long, Map<String, Object>> row : entrySet) {
-      Long rowId = row.getKey();
-      Map<String, Object> cols = row.getValue();
-      dataJsonObject.accumulate("timestamp", rowId);
-      for (String columnLabel : columnLabels) {
-        dataJsonObject.accumulate(columnLabel, cols.get(columnLabel));
-      }
+  private void swapWriter() {
+    synchronized (reading) {
+      ResetableCharArrayWriter tmp1 = writerWriting;
+      writerWriting = writerInUse;
+      writerInUse = tmp1;
+      reading.set(writerInUse);
     }
-    jsonObject.put("data", dataJsonObject);
-    jsonObject.write(writer);
+  }
+
+  private ResetableCharArrayWriter getWriter() {
+    return writerWriting;
   }
 
   @Override
   public void processMeter(MetricName name, Metered meter, Context context) throws Exception
{
-    RowSortedTable<Long, String, Object> table = context.getTable(name);
-    Long time = context.getTime();
-    addMeterInfo(time, meter, table);
+    MetricInfo info = context.getMetricInfo(name);
+    long time = context.getTime();
+    addMeterInfo(time, meter, info);
   }
 
   @Override
   public void processCounter(MetricName name, Counter counter, Context context) throws Exception
{
-    RowSortedTable<Long, String, Object> table = context.getTable(name);
-    Long time = context.getTime();
-    table.put(time, "value", counter.count());
+    MetricInfo info = context.getMetricInfo(name);
+    long time = context.getTime();
+    info.addNumber("timestamp", time);
+    info.addNumber("value", counter.count());
   }
 
   @Override
   public void processHistogram(MetricName name, Histogram histogram, Context context) throws
Exception {
-    RowSortedTable<Long, String, Object> table = context.getTable(name);
-    Long time = context.getTime();
-    table.put(time, "min", histogram.min());
-    table.put(time, "max", histogram.max());
-    table.put(time, "mean", histogram.mean());
-    table.put(time, "stdDev", histogram.stdDev());
+    MetricInfo info = context.getMetricInfo(name);
+    long time = context.getTime();
+    info.addNumber("timestamp", time);
+    info.addNumber("min", histogram.min());
+    info.addNumber("max", histogram.max());
+    info.addNumber("mean", histogram.mean());
+    info.addNumber("stdDev", histogram.stdDev());
 
     Snapshot snapshot = histogram.getSnapshot();
-    table.put(time, "median", snapshot.getMedian());
-    table.put(time, "75%", snapshot.get75thPercentile());
-    table.put(time, "95%", snapshot.get95thPercentile());
-    table.put(time, "98%", snapshot.get98thPercentile());
-    table.put(time, "99%", snapshot.get99thPercentile());
-    table.put(time, "99.9%", snapshot.get999thPercentile());
+    info.addNumber("median", snapshot.getMedian());
+    info.addNumber("75%", snapshot.get75thPercentile());
+    info.addNumber("95%", snapshot.get95thPercentile());
+    info.addNumber("98%", snapshot.get98thPercentile());
+    info.addNumber("99%", snapshot.get99thPercentile());
+    info.addNumber("99.9%", snapshot.get999thPercentile());
   }
 
   @Override
   public void processTimer(MetricName name, Timer timer, Context context) throws Exception
{
-    RowSortedTable<Long, String, Object> table = context.getTable(name);
-    Long time = context.getTime();
-    addMeterInfo(time, timer, table);
-    table.put(time, "unit", timer.durationUnit());
-    table.put(time, "min", timer.min());
-    table.put(time, "max", timer.max());
-    table.put(time, "mean", timer.mean());
-    table.put(time, "stdDev", timer.stdDev());
+    MetricInfo info = context.getMetricInfo(name);
+    long time = context.getTime();
+
+    addMeterInfo(time, timer, info);
+    info.setMetaData("unit", timer.durationUnit().toString());
+    info.addNumber("min", timer.min());
+    info.addNumber("max", timer.max());
+    info.addNumber("mean", timer.mean());
+    info.addNumber("stdDev", timer.stdDev());
 
     Snapshot snapshot = timer.getSnapshot();
-    table.put(time, "median", snapshot.getMedian());
-    table.put(time, "75%", snapshot.get75thPercentile());
-    table.put(time, "95%", snapshot.get95thPercentile());
-    table.put(time, "98%", snapshot.get98thPercentile());
-    table.put(time, "99%", snapshot.get99thPercentile());
-    table.put(time, "99.9%", snapshot.get999thPercentile());
+    info.addNumber("median", snapshot.getMedian());
+    info.addNumber("75%", snapshot.get75thPercentile());
+    info.addNumber("95%", snapshot.get95thPercentile());
+    info.addNumber("98%", snapshot.get98thPercentile());
+    info.addNumber("99%", snapshot.get99thPercentile());
+    info.addNumber("99.9%", snapshot.get999thPercentile());
   }
 
   @Override
   public void processGauge(MetricName name, Gauge<?> gauge, Context context) throws
Exception {
-    RowSortedTable<Long, String, Object> table = context.getTable(name);
-    Long time = context.getTime();
-    table.put(time, "value", gauge.value());
+    MetricInfo info = context.getMetricInfo(name);
+    long time = context.getTime();
+    info.addNumber("timestamp", time);
+    info.addNumber("value", getDouble(gauge.value()));
   }
 
-  private void addMeterInfo(Long time, Metered meter, RowSortedTable<Long, String, Object>
table) {
-    table.put(time, "rateUnit", meter.rateUnit());
-    table.put(time, "eventType", meter.eventType());
-    table.put(time, "count", meter.count());
-    table.put(time, "meanRate", meter.meanRate());
-    table.put(time, "oneMinuteRate", meter.oneMinuteRate());
-    table.put(time, "fiveMinuteRate", meter.fiveMinuteRate());
-    table.put(time, "fifteenMinuteRate", meter.fifteenMinuteRate());
+  private double getDouble(Object value) {
+    if (value instanceof Integer) {
+      Integer v = (Integer) value;
+      return (int) v;
+    } else if (value instanceof Long) {
+      Long v = (Long) value;
+      return (long) v;
+    } else if (value instanceof Double) {
+      Double v = (Double) value;
+      return v;
+    } else if (value instanceof Float) {
+      Float v = (Float) value;
+      return (float) v;
+    }
+    return 0;
   }
 
-  private JSONObject getName(MetricName metricName) throws JSONException {
-    String group = metricName.getGroup();
-    String name = metricName.getName();
-    String scope = metricName.getScope();
-    String type = metricName.getType();
-    JSONObject jsonObject = new JSONObject();
-    jsonObject.put("name", name);
-    jsonObject.put("group", group);
-    jsonObject.put("scope", scope);
-    jsonObject.put("type", type);
-    return jsonObject;
+  private void addMeterInfo(Long time, Metered meter, MetricInfo info) {
+    info.addNumber("timestamp", time);
+    info.setMetaData("rateUnit", meter.rateUnit().toString());
+    info.setMetaData("eventType", meter.eventType());
+    info.addNumber("count", meter.count());
+    info.addNumber("meanRate", meter.meanRate());
+    info.addNumber("oneMinuteRate", meter.oneMinuteRate());
+    info.addNumber("fiveMinuteRate", meter.fiveMinuteRate());
+    info.addNumber("fifteenMinuteRate", meter.fifteenMinuteRate());
   }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/5b9742eb/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporterServlet.java
----------------------------------------------------------------------
diff --git a/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporterServlet.java
b/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporterServlet.java
new file mode 100644
index 0000000..0f4c4b8
--- /dev/null
+++ b/src/blur-util/src/main/java/org/apache/blur/metrics/JSONReporterServlet.java
@@ -0,0 +1,22 @@
+package org.apache.blur.metrics;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class JSONReporterServlet extends HttpServlet {
+  private static final long serialVersionUID = -3086441832701983642L;
+
+  @Override
+  protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException,
IOException {
+    response.setContentType("application/json");
+    PrintWriter writer = response.getWriter();
+    JSONReporter.writeJSONData(writer);
+    writer.flush();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/5b9742eb/src/blur-util/src/main/java/org/apache/blur/metrics/MetricInfo.java
----------------------------------------------------------------------
diff --git a/src/blur-util/src/main/java/org/apache/blur/metrics/MetricInfo.java b/src/blur-util/src/main/java/org/apache/blur/metrics/MetricInfo.java
new file mode 100644
index 0000000..ddb92e3
--- /dev/null
+++ b/src/blur-util/src/main/java/org/apache/blur/metrics/MetricInfo.java
@@ -0,0 +1,177 @@
+package org.apache.blur.metrics;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jboss.netty.util.internal.ConcurrentHashMap;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class MetricInfo {
+
+  public static void main(String[] args) throws IOException {
+    MetricInfo info = new MetricInfo("name", "type", 10);
+    info.addNumber("test1", 0.1);
+    info.addNumber("test1", 0.2);
+    info.addNumber("test1", 0.3);
+    info.addNumber("test1", 0.4);
+    info.addNumber("test1", 0.5);
+    info.addNumber("test1", 0.6);
+    info.addNumber("test1", 0.7);
+    info.addNumber("test1", 0.9);
+    info.addNumber("test1", 1.0);
+    info.addNumber("test1", 1.1);
+    info.addNumber("test1", 1.2);
+
+    StringWriter writer = new StringWriter();
+    info.write(writer);
+    System.out.println(writer);
+  }
+
+  static interface ArrayWriter {
+    void writeArray(Writer writer) throws IOException;
+  }
+
+  static class PrimitiveLongQueue implements ArrayWriter {
+    int head = -1;
+    int length = 0;
+    final long[] data;
+    final int numberOfElements;
+
+    PrimitiveLongQueue(int numberOfElements) {
+      this.data = new long[numberOfElements];
+      this.numberOfElements = numberOfElements;
+    }
+
+    void add(long d) {
+      head++;
+      if (head >= numberOfElements) {
+        head = 0;
+      }
+      data[head] = d;
+      if (length < numberOfElements) {
+        length++;
+      }
+    }
+
+    public void writeArray(Writer writer) throws IOException {
+      writer.append("[");
+      int position = head;
+      for (int i = 0; i < length; i++) {
+        if (i != 0) {
+          writer.append(',');
+        }
+        writer.append(Long.toString(data[position]));
+        position--;
+        if (position < 0) {
+          position = numberOfElements - 1;
+        }
+      }
+      writer.append("]");
+    }
+  }
+
+  static class PrimitiveDoubleQueue implements ArrayWriter {
+    int head = -1;
+    int length = 0;
+    final double[] data;
+    final int numberOfElements;
+
+    PrimitiveDoubleQueue(int numberOfElements) {
+      this.data = new double[numberOfElements];
+      this.numberOfElements = numberOfElements;
+    }
+
+    void add(double d) {
+      head++;
+      if (head >= numberOfElements) {
+        head = 0;
+      }
+      data[head] = d;
+      if (length < numberOfElements) {
+        length++;
+      }
+    }
+
+    public void writeArray(Writer writer) throws IOException {
+      writer.append("[");
+      int position = head;
+      for (int i = 0; i < length; i++) {
+        if (i != 0) {
+          writer.append(',');
+        }
+        double d = data[position];
+        try {
+          writer.append(JSONObject.numberToString(d));
+        } catch (JSONException e) {
+          throw new IOException(e);
+        }
+        position--;
+        if (position < 0) {
+          position = numberOfElements - 1;
+        }
+      }
+      writer.append("]");
+    }
+  }
+
+  private final String name;
+  private final String type;
+  private final Map<String, ArrayWriter> metricMap = new ConcurrentHashMap<String,
ArrayWriter>();
+  private int numberOfEntries;
+
+  public MetricInfo(String name, String type, int numberOfEntries) {
+    this.name = name;
+    this.type = type;
+    this.numberOfEntries = numberOfEntries;
+  }
+
+  public void addNumber(String name, long l) {
+    PrimitiveLongQueue queue = (PrimitiveLongQueue) metricMap.get(name);
+    if (queue == null) {
+      queue = new PrimitiveLongQueue(numberOfEntries);
+      metricMap.put(name, queue);
+    }
+    queue.add(l);
+  }
+
+  public void addNumber(String name, double d) {
+    PrimitiveDoubleQueue queue = (PrimitiveDoubleQueue) metricMap.get(name);
+    if (queue == null) {
+      queue = new PrimitiveDoubleQueue(numberOfEntries);
+      metricMap.put(name, queue);
+    }
+    queue.add(d);
+  }
+
+  public void write(Writer writer) throws IOException {
+    writer.append("{\"name\":\"");
+    writer.append(name);
+    writer.append("\",\"type\":\"");
+    writer.append(type);
+    writer.append("\",\"data\":{");
+    writeMetricMap(writer);
+    writer.append("}}");
+  }
+
+  private void writeMetricMap(Writer writer) throws IOException {
+    boolean flag = false;
+    for (Entry<String, ArrayWriter> entry : metricMap.entrySet()) {
+      if (flag) {
+        writer.append(',');
+      }
+      writer.append("\"");
+      writer.append(entry.getKey());
+      writer.append("\":");
+      entry.getValue().writeArray(writer);
+      flag = true;
+    }
+  }
+
+  public void setMetaData(String key, String value) {
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/5b9742eb/src/blur-util/src/main/java/org/apache/blur/metrics/ResetableCharArrayWriter.java
----------------------------------------------------------------------
diff --git a/src/blur-util/src/main/java/org/apache/blur/metrics/ResetableCharArrayWriter.java
b/src/blur-util/src/main/java/org/apache/blur/metrics/ResetableCharArrayWriter.java
new file mode 100644
index 0000000..66cb384
--- /dev/null
+++ b/src/blur-util/src/main/java/org/apache/blur/metrics/ResetableCharArrayWriter.java
@@ -0,0 +1,23 @@
+package org.apache.blur.metrics;
+
+import java.io.CharArrayWriter;
+
+public class ResetableCharArrayWriter extends CharArrayWriter {
+
+  public ResetableCharArrayWriter() {
+    super();
+  }
+
+  public ResetableCharArrayWriter(int initialSize) {
+    super(initialSize);
+  }
+
+  public char[] getBuffer() {
+    return buf;
+  }
+
+  public void reset() {
+    this.count = 0;
+  }
+
+}


Mime
View raw message