You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@chukwa.apache.org by ey...@apache.org on 2015/04/27 02:37:46 UTC
[4/4] chukwa git commit: CHUKWA-745. Improved chart configuration
management. (Eric Yang)
CHUKWA-745. Improved chart configuration management. (Eric Yang)
Project: http://git-wip-us.apache.org/repos/asf/chukwa/repo
Commit: http://git-wip-us.apache.org/repos/asf/chukwa/commit/a6e0cbad
Tree: http://git-wip-us.apache.org/repos/asf/chukwa/tree/a6e0cbad
Diff: http://git-wip-us.apache.org/repos/asf/chukwa/diff/a6e0cbad
Branch: refs/heads/master
Commit: a6e0cbad7cd52cc04a5363c04bc0fbd5b78f66be
Parents: 16927ce
Author: Eric Yang <ey...@apache.org>
Authored: Sun Apr 26 14:52:58 2015 -0700
Committer: Eric Yang <ey...@apache.org>
Committed: Sun Apr 26 17:25:26 2015 -0700
----------------------------------------------------------------------
CHANGES.txt | 2 +
bin/chukwa | 1 +
conf/hbase.schema | 3 +-
pom.xml | 11 +
.../writer/hbase/HBaseWriter.java | 15 +-
.../chukwa/datastore/ChukwaHBaseStore.java | 174 +++++++-
.../extraction/hbase/AbstractProcessor.java | 2 -
.../apache/hadoop/chukwa/hicc/BarOptions.java | 30 ++
.../org/apache/hadoop/chukwa/hicc/Chart.java | 446 ++++---------------
.../hadoop/chukwa/hicc/HiccWebServer.java | 19 +
.../apache/hadoop/chukwa/hicc/LineOptions.java | 25 ++
.../apache/hadoop/chukwa/hicc/PointOptions.java | 27 ++
.../org/apache/hadoop/chukwa/hicc/Series.java | 121 +++++
.../hadoop/chukwa/hicc/SeriesOptions.java | 33 ++
.../apache/hadoop/chukwa/hicc/bean/Series.java | 4 +
.../chukwa/hicc/rest/ChartController.java | 187 ++++++++
.../chukwa/hicc/rest/MetricsController.java | 7 +-
.../chukwa/hicc/rest/VelocityResolver.java | 86 ++++
.../apache/hadoop/chukwa/util/HBaseUtil.java | 17 +
src/main/web/hicc/WEB-INF/vm/chart.vm | 106 +++++
.../web/hicc/WEB-INF/vm/unit-bytes-binary.vm | 27 ++
.../web/hicc/WEB-INF/vm/unit-bytes-decimal.vm | 27 ++
src/main/web/hicc/WEB-INF/vm/unit-generic.vm | 20 +
src/main/web/hicc/WEB-INF/vm/unit-ops.vm | 20 +
src/main/web/hicc/WEB-INF/vm/unit-percent.vm | 20 +
src/main/web/hicc/css/default.css | 11 +-
src/main/web/hicc/css/iframe.css | 91 +++-
src/main/web/hicc/js/flot.extend.js | 170 +++----
src/main/web/hicc/jsp/graph_explorer.jsp | 204 ++++-----
.../apache/hadoop/chukwa/hicc/TestChart.java | 84 ++--
30 files changed, 1321 insertions(+), 669 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index dd3f642..5e3e93c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -10,6 +10,8 @@ Trunk (unreleased changes)
IMPROVEMENTS
+ CHUKWA-745. Improved chart configuration management. (Eric Yang)
+
CHUKWA-744. Implemented new parsers for extract and transform data to HBase format. (Eric Yang)
CHUKWA-667. Optimize HBase metrics schema. (Eric Yang)
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/bin/chukwa
----------------------------------------------------------------------
diff --git a/bin/chukwa b/bin/chukwa
index 1a3a341..db77200 100755
--- a/bin/chukwa
+++ b/bin/chukwa
@@ -153,6 +153,7 @@ fi
pid="$CHUKWA_PID_DIR/chukwa-$CHUKWA_IDENT_STRING-$COMMAND.pid"
if [ "$1" = "start" ]; then
+ shift
if [ -f $pid ]; then
TARGET_PID=`cat $pid`
if kill -0 `cat $pid` > /dev/null 2>&1; then
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/conf/hbase.schema
----------------------------------------------------------------------
diff --git a/conf/hbase.schema b/conf/hbase.schema
index 5e32f90..54e5b01 100644
--- a/conf/hbase.schema
+++ b/conf/hbase.schema
@@ -1,5 +1,6 @@
create "chukwa_meta",
-{NAME=>"k"}
+{NAME=>"k"},
+{NAME=>"c"}
create "chukwa",
{NAME=>"t"},
{NAME=>"a"}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6beaef8..1c8d26c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -109,6 +109,16 @@
<version>1.8.1</version>
</dependency>
<dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <version>1.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity-tools</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
<groupId>edu.berkeley.confspell</groupId>
<artifactId>confspellcheck</artifactId>
<version>1.0</version>
@@ -481,6 +491,7 @@
<exclude>**/JobLog.java</exclude>
<exclude>**/TestJobLogEntry.java</exclude>
<exclude>**/TestDemuxManager.java</exclude>
+ <exclude>**/TestFSMBuilder.java</exclude>
</testExcludes>
</configuration>
</execution>
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/HBaseWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/HBaseWriter.java b/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/HBaseWriter.java
index 34c82e1..e5a8083 100644
--- a/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/HBaseWriter.java
+++ b/src/main/java/org/apache/hadoop/chukwa/datacollection/writer/hbase/HBaseWriter.java
@@ -37,10 +37,14 @@ import org.apache.hadoop.chukwa.extraction.hbase.UnknownRecordTypeException;
import org.apache.hadoop.chukwa.util.ExceptionUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HConnectionManager;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Table;
import org.apache.log4j.Logger;
public class HBaseWriter extends PipelineableWriter {
@@ -54,7 +58,7 @@ public class HBaseWriter extends PipelineableWriter {
private Reporter reporter;
private ChukwaConfiguration conf;
String defaultProcessor;
- private HConnection connection;
+ private static Connection connection;
private class StatReportingTask extends TimerTask {
private long lastTs = System.currentTimeMillis();
@@ -105,7 +109,9 @@ public class HBaseWriter extends PipelineableWriter {
} catch (NoSuchAlgorithmException e) {
throw new IOException("Can not register hashing algorithm.");
}
- connection = HConnectionManager.createConnection(hconf);
+ if (connection == null) {
+ connection = ConnectionFactory.createConnection(hconf);
+ }
}
public void close() {
@@ -121,8 +127,8 @@ public class HBaseWriter extends PipelineableWriter {
public CommitStatus add(List<Chunk> chunks) throws WriterException {
CommitStatus rv = ChukwaWriter.COMMIT_OK;
try {
- HTableInterface hbase = connection.getTable(CHUKWA_TABLE);
- HTableInterface meta = connection.getTable(CHUKWA_META_TABLE);
+ Table hbase = connection.getTable(TableName.valueOf(CHUKWA_TABLE));
+ Table meta = connection.getTable(TableName.valueOf(CHUKWA_META_TABLE));
for(Chunk chunk : chunks) {
synchronized (this) {
try {
@@ -140,6 +146,7 @@ public class HBaseWriter extends PipelineableWriter {
}
}
hbase.close();
+ meta.close();
} catch (Exception e) {
log.error(ExceptionUtil.getStackTrace(e));
throw new WriterException("Failed to store data to HBase.");
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
index d9c32d6..7494aa8 100644
--- a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
+++ b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -29,11 +30,13 @@ import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TimeZone;
+import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.hadoop.chukwa.hicc.Chart;
import org.apache.hadoop.chukwa.hicc.bean.HeatMapPoint;
import org.apache.hadoop.chukwa.hicc.bean.Heatmap;
import org.apache.hadoop.chukwa.hicc.bean.Series;
@@ -48,6 +51,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
@@ -56,16 +60,37 @@ import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
+import com.google.gson.Gson;
+
public class ChukwaHBaseStore {
private static Configuration hconf = HBaseConfiguration.create();
static Logger LOG = Logger.getLogger(ChukwaHBaseStore.class);
static byte[] COLUMN_FAMILY = "t".getBytes();
static byte[] ANNOTATION_FAMILY = "a".getBytes();
static byte[] KEY_NAMES = "k".getBytes();
+ static byte[] CHART_TYPE = "chart_meta".getBytes();
+ static byte[] CHART_FAMILY = "c".getBytes();
private static final String CHUKWA = "chukwa";
private static final String CHUKWA_META = "chukwa_meta";
private static long MILLISECONDS_IN_DAY = 86400000L;
+ private static Connection connection = null;
+ public static void getHBaseConnection() throws IOException {
+ if (connection == null || connection.isClosed()) {
+ connection = ConnectionFactory.createConnection(hconf);
+ }
+ }
+
+ public static void closeHBase() {
+ try {
+ if(connection != null) {
+ connection.close();
+ }
+ } catch(IOException e) {
+ LOG.warn("Unable to release HBase connection.");
+ }
+ }
+
/**
* Scan chukwa table for a particular metric group and metric name based on
* time ranges.
@@ -93,7 +118,7 @@ public class ChukwaHBaseStore {
* @param endTime
* @return
*/
- public static Series getSeries(String metric, String source, long startTime,
+ public static synchronized Series getSeries(String metric, String source, long startTime,
long endTime) {
String seriesName = new StringBuilder(metric).append(":").append(source).toString();
Series series = new Series(seriesName);
@@ -104,7 +129,7 @@ public class ChukwaHBaseStore {
startTime = endTime;
endTime = temp;
}
- Connection connection = ConnectionFactory.createConnection(hconf);
+ getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA));
Scan scan = new Scan();
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
@@ -144,6 +169,7 @@ public class ChukwaHBaseStore {
}
table.close();
} catch (Exception e) {
+ closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return series;
@@ -152,7 +178,7 @@ public class ChukwaHBaseStore {
public static Set<String> getMetricNames(String metricGroup) {
Set<String> familyNames = new CopyOnWriteArraySet<String>();
try {
- Connection connection = ConnectionFactory.createConnection(hconf);
+ getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Get get = new Get(metricGroup.getBytes());
Result result = table.get(get);
@@ -163,8 +189,8 @@ public class ChukwaHBaseStore {
}
}
table.close();
- connection.close();
} catch (Exception e) {
+ closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return familyNames;
@@ -174,7 +200,7 @@ public class ChukwaHBaseStore {
public static Set<String> getMetricGroups() {
Set<String> metricGroups = new CopyOnWriteArraySet<String>();
try {
- Connection connection = ConnectionFactory.createConnection(hconf);
+ getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Scan scan = new Scan();
scan.addFamily(KEY_NAMES);
@@ -185,8 +211,8 @@ public class ChukwaHBaseStore {
metricGroups.add(new String(result.getRow(), "UTF-8"));
}
table.close();
- connection.close();
} catch (Exception e) {
+ closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return metricGroups;
@@ -195,7 +221,7 @@ public class ChukwaHBaseStore {
public static Set<String> getSourceNames(String dataType) {
Set<String> pk = new HashSet<String>();
try {
- Connection connection = ConnectionFactory.createConnection(hconf);
+ getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Scan scan = new Scan();
scan.addFamily(KEY_NAMES);
@@ -211,8 +237,8 @@ public class ChukwaHBaseStore {
}
}
table.close();
- connection.close();
} catch (Exception e) {
+ closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return pk;
@@ -227,7 +253,7 @@ public class ChukwaHBaseStore {
List<Get> series = new ArrayList<Get>();
String fullName = new StringBuilder(metricGroup).append(".").append(metric).toString();
try {
- Connection connection = ConnectionFactory.createConnection(hconf);
+ getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA));
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
c.setTimeInMillis(startTime);
@@ -288,6 +314,7 @@ public class ChukwaHBaseStore {
heatmap.putRadius(radius);
heatmap.putSeries(index);
} catch (IOException e) {
+ closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return heatmap;
@@ -304,7 +331,7 @@ public class ChukwaHBaseStore {
public static Set<String> getClusterNames(long startTime, long endTime) {
Set<String> clusters = new HashSet<String>();
try {
- Connection connection = ConnectionFactory.createConnection(hconf);
+ getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Scan scan = new Scan();
scan.addFamily(KEY_NAMES);
@@ -320,11 +347,136 @@ public class ChukwaHBaseStore {
}
}
table.close();
- connection.close();
} catch (Exception e) {
+ closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return clusters;
}
+ public static Chart getChart(String id) {
+ Chart chart = null;
+ try {
+ getHBaseConnection();
+ Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
+ Get get = new Get(CHART_TYPE);
+ Result r = table.get(get);
+ byte[] value = r.getValue(CHART_FAMILY, id.getBytes());
+ Gson gson = new Gson();
+ if(value!=null) {
+ chart = gson.fromJson(new String(value), Chart.class);
+ }
+ table.close();
+ } catch (Exception e) {
+ closeHBase();
+ LOG.error(ExceptionUtil.getStackTrace(e));
+ }
+ return chart;
+ }
+
+ public static void putChart(String id, Chart chart) {
+ try {
+ getHBaseConnection();
+ Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
+ Put put = new Put(CHART_TYPE);
+ Gson gson = new Gson();
+ String buffer = gson.toJson(chart);
+ put.add(CHART_FAMILY, id.getBytes(), buffer.getBytes());
+ table.put(put);
+ table.close();
+ } catch (Exception e) {
+ closeHBase();
+ LOG.error(ExceptionUtil.getStackTrace(e));
+ }
+
+ }
+
+ public static String createChart(Chart chart) throws IOException {
+ getHBaseConnection();
+ String id = chart.getId();
+ if(id!=null) {
+ // Check if there is existing chart with same id.
+ Chart test = getChart(id);
+ if(test!=null) {
+ // If id already exists, randomly generate an id.
+ id = String.valueOf(UUID.randomUUID());
+ }
+ } else {
+ // If id is not provided, randomly generate an id.
+ id = String.valueOf(UUID.randomUUID());
+ }
+ chart.setId(id);
+ Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
+ Put put = new Put(CHART_TYPE);
+ Gson gson = new Gson();
+ String buffer = gson.toJson(chart);
+ put.add(CHART_FAMILY, id.getBytes(), buffer.getBytes());
+ table.put(put);
+ table.close();
+ return id;
+ }
+
+ public static synchronized ArrayList<org.apache.hadoop.chukwa.hicc.Series> getChartSeries(ArrayList<org.apache.hadoop.chukwa.hicc.Series> series, long startTime, long endTime) {
+ ArrayList<org.apache.hadoop.chukwa.hicc.Series> list = new ArrayList<org.apache.hadoop.chukwa.hicc.Series>();
+ try {
+ // Swap start and end if the values are inverted.
+ if (startTime > endTime) {
+ long temp = endTime;
+ startTime = endTime;
+ endTime = temp;
+ }
+ getHBaseConnection();
+ Table table = connection.getTable(TableName.valueOf(CHUKWA));
+ Scan scan = new Scan();
+ Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ c.setTimeInMillis(startTime);
+ int startDay = c.get(Calendar.DAY_OF_YEAR);
+ c.setTimeInMillis(endTime);
+ int endDay = c.get(Calendar.DAY_OF_YEAR);
+ for (org.apache.hadoop.chukwa.hicc.Series s : series) {
+ org.apache.hadoop.chukwa.hicc.Series clone = (org.apache.hadoop.chukwa.hicc.Series) s.clone();
+ long currentDay = startTime;
+ String[] parts = s.getUrl().toString().split("/");
+ String metric = parts[5];
+ String source = parts[6];
+ ArrayList<ArrayList<Number>> data = new ArrayList<ArrayList<Number>>();
+ for (int i = startDay; i <= endDay; i++) {
+ byte[] rowKey = HBaseUtil.buildKey(currentDay, metric, source);
+ scan.addFamily(COLUMN_FAMILY);
+ scan.setStartRow(rowKey);
+ scan.setStopRow(rowKey);
+ scan.setTimeRange(startTime, endTime);
+ scan.setBatch(10000);
+
+ ResultScanner results = table.getScanner(scan);
+ Iterator<Result> it = results.iterator();
+ // TODO: Apply discrete wavelet transformation to limit the output
+ // size to 1000 data points for graphing optimization. (i.e jwave)
+ while (it.hasNext()) {
+ Result result = it.next();
+ for (KeyValue kv : result.raw()) {
+ byte[] key = kv.getQualifier();
+ long timestamp = ByteBuffer.wrap(key).getLong();
+ double value = Double.parseDouble(new String(kv.getValue(),
+ "UTF-8"));
+ ArrayList<Number> points = new ArrayList<Number>();
+ points.add(timestamp);
+ points.add(value);
+ data.add(points);
+ }
+ }
+ results.close();
+ currentDay = currentDay + (i * MILLISECONDS_IN_DAY);
+ }
+ clone.setData(data);
+ list.add(clone);
+ }
+ table.close();
+ } catch (Exception e) {
+ closeHBase();
+ LOG.error(ExceptionUtil.getStackTrace(e));
+ }
+ return list;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/extraction/hbase/AbstractProcessor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/extraction/hbase/AbstractProcessor.java b/src/main/java/org/apache/hadoop/chukwa/extraction/hbase/AbstractProcessor.java
index b39c789..eb79cd7 100644
--- a/src/main/java/org/apache/hadoop/chukwa/extraction/hbase/AbstractProcessor.java
+++ b/src/main/java/org/apache/hadoop/chukwa/extraction/hbase/AbstractProcessor.java
@@ -22,8 +22,6 @@ import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.TimeZone;
import org.apache.hadoop.chukwa.Chunk;
import org.apache.hadoop.chukwa.datacollection.writer.hbase.Reporter;
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/BarOptions.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/BarOptions.java b/src/main/java/org/apache/hadoop/chukwa/hicc/BarOptions.java
new file mode 100644
index 0000000..9ab686d
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/BarOptions.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.chukwa.hicc;
+
+public class BarOptions extends SeriesOptions {
+ public boolean zero;
+ public boolean stepByStep = true;
+ public int barWidth = 4;
+ public String align;
+ public boolean horizontal;
+
+ public BarOptions() {
+ fill = true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/Chart.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/Chart.java b/src/main/java/org/apache/hadoop/chukwa/hicc/Chart.java
index 76ba919..ab6dc4e 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/Chart.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/Chart.java
@@ -19,27 +19,13 @@
package org.apache.hadoop.chukwa.hicc;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.TreeMap;
import java.util.HashMap;
import java.util.List;
-import java.util.Map.Entry;
-import java.text.SimpleDateFormat;
-import javax.servlet.http.HttpServletRequest;
-import javax.swing.text.html.HTMLDocument.Iterator;
-import org.apache.hadoop.chukwa.util.XssFilter;
-import org.json.JSONArray;
-
-@SuppressWarnings("unused")
public class Chart {
private String id;
private String title;
- private String graphType;
- private ArrayList<TreeMap<String, TreeMap<String, Double>>> dataset;
- private ArrayList<String> chartType;
- private ArrayList<String> restData;
+ private List<Series> series;
private boolean xLabelOn;
private boolean yLabelOn;
private boolean yRightLabelOn;
@@ -47,45 +33,27 @@ public class Chart {
private int height;
private List<String> xLabelRange;
private HashMap<String, Long> xLabelRangeHash;
- private HttpServletRequest request = null;
- private boolean legend;
+ private boolean legend = true;
private String xLabel = "";
private String yLabel = "";
private String yRightLabel = "";
- private int datasetCounter = 0;
private double max = 0;
private double min = 0;
- private int seriesCounter = 0;
- private List<String> rightList;
- private boolean userDefinedMax = false;
- private boolean userDefinedMin = false;
- private boolean displayPercentage = false;
- private String[] seriesOrder = null;
- private XssFilter xf = null;
-
- public Chart(HttpServletRequest request) {
- xf = new XssFilter(request);
- if (request != null && xf.getParameter("boxId") != null) {
- this.id = xf.getParameter("boxId");
- } else {
- this.id = "0";
- }
+ private boolean userDefinedMax = true;
+ private boolean userDefinedMin = true;
+ private String yUnitType = "";
+
+ public Chart(String id) {
+ this.id = id;
this.title = "Untitled Chart";
- this.graphType = "image";
this.xLabelOn = true;
this.yLabelOn = true;
- this.width = 400;
- this.height = 200;
- this.request = request;
+ this.width = 100;
+ this.height = 100;
this.legend = true;
this.max = 0;
- this.datasetCounter = 0;
- this.seriesCounter = 0;
- this.rightList = new ArrayList<String>();
this.userDefinedMax = false;
this.userDefinedMin = false;
- this.displayPercentage = false;
- this.seriesOrder = null;
}
public void setYMax(double max) {
@@ -93,13 +61,25 @@ public class Chart {
this.userDefinedMax = true;
}
+ public double getYMax() {
+ return this.max;
+ }
+
+ public boolean getUserDefinedMax() {
+ return this.userDefinedMax;
+ }
+
public void setYMin(double min) {
this.min = min;
this.userDefinedMin = true;
}
- public void setDisplayPercentage(boolean percentage) {
- this.displayPercentage = percentage;
+ public double getYMin() {
+ return this.min;
+ }
+
+ public boolean getUserDefinedMin() {
+ return this.userDefinedMin;
}
public void setSize(int width, int height) {
@@ -107,71 +87,86 @@ public class Chart {
this.height = height;
}
- public void setGraphType(String graphType) {
- if (graphType != null) {
- this.graphType = graphType;
- }
+ public int getWidth() {
+ return this.width;
+ }
+
+ public int getHeight() {
+ return this.height;
}
public void setTitle(String title) {
this.title = title;
}
+ public String getTitle() {
+ return this.title;
+ }
+
public void setId(String id) {
this.id = id;
}
- public void setDataSet(String chartType,
- TreeMap<String, TreeMap<String, Double>> data) {
- if (this.dataset == null) {
- this.dataset = new ArrayList<TreeMap<String, TreeMap<String, Double>>>();
- this.chartType = new ArrayList<String>();
- }
- this.dataset.add(data);
- this.chartType.add(chartType);
+ public String getId() {
+ return this.id;
}
- public void setDataSet(String chartType, String series, String data) {
- if (this.dataset == null) {
- this.restData = new ArrayList<String>();
- this.dataset = new ArrayList<TreeMap<String, TreeMap<String, Double>>>();
- this.chartType = new ArrayList<String>();
- }
- this.chartType.add(chartType);
- this.restData.add(data);
- TreeMap<String, TreeMap<String, Double>> tree = new TreeMap<String, TreeMap<String, Double>>();
- tree.put(series, new TreeMap<String, Double>());
- this.dataset.add(tree);
+ public void SetSeries(List<Series> series) {
+ this.series = series;
}
-
- public void setSeriesOrder(String[] metrics) {
- this.seriesOrder = (String[]) metrics.clone();
+
+ public List<Series> getSeries() {
+ return this.series;
}
-
- public void setXAxisLabels(boolean toggle) {
+
+ public void setXAxisLabelsOn(boolean toggle) {
xLabelOn = toggle;
}
+ public boolean isXAxisLabelsOn() {
+ return xLabelOn;
+ }
+
public void setYAxisLabels(boolean toggle) {
yLabelOn = toggle;
}
+ public boolean isYAxisLabelsOn() {
+ return yLabelOn;
+ }
+
public void setYAxisRightLabels(boolean toggle) {
yRightLabelOn = toggle;
}
+ public boolean isYAxisRightLabelsOn() {
+ return yRightLabelOn;
+ }
+
public void setXAxisLabel(String label) {
xLabel = label;
}
+ public String getXAxisLabel() {
+ return xLabel;
+ }
+
public void setYAxisLabel(String label) {
yLabel = label;
}
+ public String getYAxisLabel() {
+ return yLabel;
+ }
+
public void setYAxisRightLabel(String label) {
yRightLabel = label;
}
+ public String getYAxisRightLabel() {
+ return yRightLabel;
+ }
+
public void setXLabelsRange(List<String> range) {
xLabelRange = range;
xLabelRangeHash = new HashMap<String, Long>();
@@ -182,302 +177,23 @@ public class Chart {
}
}
+ public List<String> getXLabelsRange() {
+ return xLabelRange;
+ }
+
public void setLegend(boolean toggle) {
legend = toggle;
}
- public String plot() {
- StringBuilder output = new StringBuilder();
- if (dataset == null && restData == null) {
- output.append("No Data available.");
- return output.toString();
- }
- String dateFormat = "%H:%M";
- if (xLabel.intern() == "Time".intern()) {
-// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-// try {
-// long xMin = 0;
-// long xMax = 0;
-// if(xLabelRange!=null && xLabelRange.size()>0) {
-// xMin = Long.parseLong(xLabelRange.get(0));
-// xMax = Long.parseLong(xLabelRange.get(xLabelRange.size() - 1));
-// }
-// if (xMax - xMin > 31536000000L) {
-// dateFormat = "%y";
-// } else if (xMax - xMin > 2592000000L) {
-// dateFormat = "%y-%m";
-// } else if (xMax - xMin > 604800000L) {
-// dateFormat = "%m-%d";
-// } else if (xMax - xMin > 86400000L) {
-// dateFormat = "%m-%d %H:%M";
-// }
-// } catch (NumberFormatException e) {
-// dateFormat = "%y-%m-%d %H:%M";
-// }
- }
- StringBuilder xAxisOptions = new StringBuilder();
- if (xLabel.intern() == "Time".intern()) {
-// if(this.restData==null) {
-// xAxisOptions.append("timeformat: \"");
-// xAxisOptions.append(dateFormat);
-// xAxisOptions.append("\",");
-// }
- xAxisOptions.append("mode: \"time\"");
- } else {
- xAxisOptions
- .append("tickFormatter: function (val, axis) { if(val!=0) { return xLabels[Math.round(val)]; } else { return \" \"; }; }, ticks: 5");
- }
- if (request != null && xf.getParameter("format") == null) {
- output
- .append("<html><link href=\"/hicc/css/default.css\" rel=\"stylesheet\" type=\"text/css\">\n");
- output
- .append("<html><link href=\"/hicc/css/iframe.css\" rel=\"stylesheet\" type=\"text/css\">\n");
- output
- .append("<html><link href=\"/hicc/css/flexigrid/flexigrid.css\" rel=\"stylesheet\" type=\"text/css\">\n");
- output
- .append("<body><script type=\"text/javascript\" src=\"/hicc/js/jquery-1.2.6.min.js\"></script>\n");
- output
- .append("<script type=\"text/javascript\" src=\"/hicc/js/jquery.flot.pack.js\"></script>\n");
- output
- .append("<script type=\"text/javascript\" src=\"/hicc/js/flexigrid.pack.js\"></script>\n");
- output
- .append("<script type=\"text/javascript\" src=\"/hicc/js/excanvas.pack.js\"></script>\n");
- output
- .append("<script type=\"text/javascript\" src=\"/hicc/js/base64.js\"></script>\n");
- output
- .append("<script type=\"text/javascript\" src=\"/hicc/js/canvas2image.js\"></script>\n");
- output.append("<div id=\"placeholderTitle\"><center>" + title
- + "</center></div>\n");
- output.append("<div id=\"placeholder\" style=\"width:" + this.width
- + "px;height:" + this.height + "px;\"></div>\n");
- output.append("<center><div id=\"placeholderLegend\" style=\"display:"+(legend?"block":"none")+";\"></div></center>\n");
- output.append("<center><div id=\"statisLegend\" style=\"display:"+(legend?"block":"none")+";\"></div></center>\n");
- output.append("<center><div id=\"statisLegend\" style=\"display:"+(legend?"block":"none")+";\"></div></center>\n");
- output.append("<input type=\"hidden\" id=\"boxId\" value=\"iframe"
- + this.id + "\">\n");
- output
- .append("<script type=\"text/javascript\" src=\"/hicc/js/flot.extend.js\">\n");
- output.append("</script>\n");
- output.append("<script type=\"text/javascript\">\n");
- output.append("var chartTitle=\"<center>" + title + "</center>\";\n");
- output.append("var height=" + this.height + ";\n");
- output.append("var xLabels=new Array();\n");
- output.append("var cw = document.body.clientWidth-70;\n");
- output.append("var ch = document.body.clientHeight-50;\n");
- output
- .append("document.getElementById('placeholder').style.width=cw+'px';\n");
- output
- .append("document.getElementById('placeholder').style.height=ch+'px';\n");
- }
- output.append("_options={\n");
- output.append(" points: { show: false },\n");
- output.append(" xaxis: { " + xAxisOptions + " },\n");
- output.append(" selection: { mode: \"xy\" },\n");
- output.append(" grid: {\n");
- output.append(" clickable: true,\n");
- output.append(" hoverable: true,\n");
- output.append(" tickColor: \"#C0C0C0\",\n");
- output.append(" borderWidth: 0,\n");
- output.append(" backgroundColor:\"#F9F9F9\"\n");
- output.append(" },\n");
- output.append(" legend: { show: " + this.legend
- + ", noColumns: 3, container: $(\"#placeholderLegend\") },\n");
- output.append(" yaxis: { ");
- boolean stack = false;
- for (String type : this.chartType) {
- if (type.startsWith("stack")) {
- stack = true;
- }
- }
- if (stack) {
- output.append("mode: \"stack\", ");
- }
- if (displayPercentage) {
- output
- .append("tickFormatter: function(val, axis) { return val.toFixed(axis.tickDecimals) + \" %\"; }");
- } else {
- output.append("tickFormatter: function(val, axis) { ");
- output
- .append("if (val >= 1000000000000000) return (val / 1000000000000000).toFixed(2) + \"x10<sup>15</sup>\";");
- output
- .append("else if (val >= 100000000000000) return (val / 100000000000000).toFixed(2) + \"x10<sup>14</sup>\";");
- output
- .append("else if (val >= 10000000000000) return (val / 10000000000000).toFixed(2) + \"x10<sup>13</sup>\";");
- output
- .append("else if (val >= 1000000000000) return (val / 1000000000000).toFixed(2) + \"x10<sup>12</sup>\";");
- output
- .append("else if (val >= 100000000000) return (val / 100000000000).toFixed(2) + \"x10<sup>11</sup>\";");
- output
- .append("else if (val >= 10000000000) return (val / 10000000000).toFixed(2) + \"x10<sup>10</sup>\";");
- output
- .append("else if (val >= 1000000000) return (val / 1000000000).toFixed(2) + \"x10<sup>9</sup>\";");
- output
- .append("else if (val >= 100000000) return (val / 100000000).toFixed(2) + \"x10<sup>8</sup>\";");
- output
- .append("else if (val >= 10000000) return (val / 10000000).toFixed(2) + \"x10<sup>7</sup>\";");
- output
- .append("else if (val >= 1000000) return (val / 1000000).toFixed(2) + \"x10<sup>6</sup>\";");
- output
- .append("else if (val >= 100000) return (val / 100000).toFixed(2) + \"x10<sup>5</sup>\";");
- output
- .append("else if (val >= 10000) return (val / 10000).toFixed(2) + \"x10<sup>4</sup>\";");
- output
- .append("else if (val >= 2000) return (val / 1000).toFixed(2) + \"x10<sup>3</sup>\";");
- output.append("else return val.toFixed(2) + \"\"; }");
- }
- if (userDefinedMin) {
- output.append(", min:");
- output.append(this.min);
- }
- if (userDefinedMax) {
- output.append(", max:");
- output.append(this.max);
- }
- output.append("}\n");
- output.append(" };\n");
- if (!xLabel.equals("Time")) {
- output.append("xLabels = [\"");
- for (int i = 0; i < xLabelRange.size(); i++) {
- if (i > 0) {
- output.append("\",\"");
- }
- output.append(xLabelRange.get(i));
- }
- output.append("\"];\n");
- }
- output.append("_series=[\n");
- ColorPicker cp = new ColorPicker();
- int i = 0;
- if(this.dataset!=null) {
- for (TreeMap<String, TreeMap<String, Double>> dataMap : this.dataset) {
- String[] keyNames;
- if (this.seriesOrder != null) {
- keyNames = this.seriesOrder;
- } else {
- keyNames = dataMap.keySet().toArray(
- new String[dataMap.size()]);
- }
- int counter = 0;
- if (i != 0 && !this.userDefinedMax) {
- this.max = 0;
- }
- for (String seriesName : keyNames) {
- int counter2 = 0;
- if ((counter != 0) || (i != 0)) {
- output.append(",");
- }
- String param = "fill: false, lineWidth: 1";
- String type = "lines";
- if (this.chartType.get(i).intern() == "stack-area".intern()
- || this.chartType.get(i).intern() == "area".intern()) {
- param = "fill: true, lineWidth: 0";
- }
- if (this.chartType.get(i).intern() == "bar".intern()) {
- type = "bars";
- param = "stepByStep: true, lineWidth: 0";
- }
- if (this.chartType.get(i).intern() == "point".intern()) {
- type = "points";
- param = "fill: false";
- }
- output.append(" {");
- output.append(type);
- output.append(": { show: true, ");
- output.append(param);
- output.append(" }, color: \"");
- output.append(cp.getNext());
- output.append("\", label: \"");
- output.append(seriesName);
- output.append("\", ");
- String showYAxis = "false";
- String shortRow = "false";
- if (counter == 0 || i > 0) {
- showYAxis = "true";
- shortRow = "false";
- }
- output.append(" row: { show: ");
- output.append(showYAxis);
- output.append(",shortRow:");
- output.append(shortRow);
- output.append(", showYAxis:");
- output.append(showYAxis);
- output.append("}, data:[");
- TreeMap<String, Double> data = dataMap.get(seriesName);
- if(data!=null) {
- java.util.Iterator<Entry<String, Double>> iter = data.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry<String, Double> entry = (Map.Entry<String, Double>) iter.next();
- int rangeLabel = 0;
- if (counter2 != 0) {
- output.append(",");
- }
- if (xLabel.equals("Time")) {
- if (Double.isNaN(entry.getValue())) {
- output.append("[");
- output.append(entry.getKey());
- output.append(",NULL]");
- } else {
- output.append("[");
- output.append(entry.getKey());
- output.append(",");
- output.append(entry.getValue());
- output.append("]");
- }
- } else {
- long value = xLabelRangeHash.get(entry.getKey());
- if (Double.isNaN(entry.getValue())) {
- output.append("[");
- output.append(value);
- output.append(",NULL]");
- } else {
- output.append("[");
- output.append(value);
- output.append(",");
- output.append(entry.getValue());
- output.append("]");
- }
- rangeLabel++;
- }
- counter2++;
- }
- }
- output.append("], min:0");
- if (this.userDefinedMax) {
- output.append(", max:");
- output.append(this.max);
- }
- output.append("}");
- counter++;
- }
- i++;
- }
- }
- output.append(" ];\n");
- if(this.restData!=null) {
- JSONArray arr = new JSONArray();
- for(String url : restData) {
- arr.put(url);
- }
- output.append("var _rest = ");
- output.append(arr.toString());
- output.append(";");
- }
- if (request != null && xf.getParameter("format") == null) {
- output.append("$(document).ready(function() { \n");
- if(this.restData!=null) {
- output.append(" loadData();\n");
- } else {
- output.append(" wholePeriod();\n");
- }
- output.append(" $(window).resize(function() { wholePeriod(); });\n");
- output.append("});\n");
- output.append("</script>\n");
- output.append("<input type=\"button\" value=\"Export\" onclick=\"javascript:saveReport();\">\n");
- output.append("</body></html>\n");
- } else {
- output.append("chartTitle=\"<center>" + this.title + "</center>\";");
- output.append("height=" + this.height + ";");
- }
- return output.toString();
+ public boolean getLegend() {
+ return legend;
+ }
+
+ public void setYUnitType(String yUnitType) {
+ this.yUnitType = yUnitType;
+ }
+
+ public String getYUnitType() {
+ return this.yUnitType;
}
}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/HiccWebServer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/HiccWebServer.java b/src/main/java/org/apache/hadoop/chukwa/hicc/HiccWebServer.java
index 09e829d..ea53941 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/HiccWebServer.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/HiccWebServer.java
@@ -22,6 +22,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
@@ -31,6 +32,7 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.hadoop.chukwa.conf.ChukwaConfiguration;
+import org.apache.hadoop.chukwa.datastore.ChukwaHBaseStore;
import org.apache.hadoop.chukwa.util.ExceptionUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
@@ -106,6 +108,7 @@ public class HiccWebServer {
}
}
}
+ jar.close();
return result;
}
@@ -187,6 +190,22 @@ public class HiccWebServer {
fs.mkdirs(viewsPath);
List<String> views = getResourceListing("views");
populateDir(views, viewsPath);
+
+ // Populate example chart widgets
+ Chart chart = new Chart("1");
+ chart.setYUnitType("");
+ chart.setTitle("Load Average");
+ ArrayList<Series> series = new ArrayList<Series>();
+
+ Series s = new Series();
+ s.setLabel("SystemMetrics.LoadAverage.1/Erics-MacBook-Pro.local");
+ s.setUrl(new URI("/hicc/v1/metrics/series/SystemMetrics.LoadAverage.1/Erics-MacBook-Pro.local"));
+ LineOptions l = new LineOptions();
+ s.setLineOptions(l);
+ series.add(s);
+
+ chart.SetSeries(series);
+ ChukwaHBaseStore.createChart(chart);
log.info("HICC Datastore initialization completed.");
}
} catch (IOException ex) {
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/LineOptions.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/LineOptions.java b/src/main/java/org/apache/hadoop/chukwa/hicc/LineOptions.java
new file mode 100644
index 0000000..f0e1279
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/LineOptions.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.chukwa.hicc;
+
+public class LineOptions extends SeriesOptions {
+ public boolean zero;
+ public boolean steps;
+
+
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/PointOptions.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/PointOptions.java b/src/main/java/org/apache/hadoop/chukwa/hicc/PointOptions.java
new file mode 100644
index 0000000..dedea86
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/PointOptions.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.chukwa.hicc;
+
+public class PointOptions extends SeriesOptions {
+ public int radius;
+ public String symbol = "circle";
+
+ public PointOptions() {
+ radius = 5;
+ }
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/Series.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/Series.java b/src/main/java/org/apache/hadoop/chukwa/hicc/Series.java
new file mode 100644
index 0000000..4906059
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/Series.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.chukwa.hicc;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Series implements Cloneable {
+
+ @XmlElement
+ public URI url;
+ @XmlElement
+ public String color;
+ @XmlElement
+ public String label;
+ @XmlElement
+ public LineOptions lines;
+ @XmlElement
+ public BarOptions bars;
+ @XmlElement
+ public PointOptions points;
+ @XmlElement
+ public int xaxis;
+ @XmlElement
+ public int yaxis;
+ @XmlElement
+ public boolean clickable;
+ @XmlElement
+ public boolean hoverable;
+ @XmlElement
+ public int shadowSize;
+ @XmlElement
+ public int highlightColor;
+ public ArrayList<ArrayList<Number>> data = null;
+
+ public Series() {
+
+ }
+
+ public void setUrl(URI url) {
+ this.url = url;
+ }
+
+ public URI getUrl() {
+ return url;
+ }
+
+ public void setLineOptions(LineOptions lines) {
+ this.lines = lines;
+
+ }
+
+ public LineOptions getLineOptions() {
+ return lines;
+ }
+
+ public void setBarOptions(BarOptions bars) {
+ this.bars = bars;
+ }
+
+ public BarOptions getBarOptions() {
+ return bars;
+ }
+
+ public void setPointOptions(PointOptions points) {
+ this.points = points;
+ }
+
+ public PointOptions getPointOptions() {
+ return points;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setData(ArrayList<ArrayList<Number>> data) {
+ this.data = data;
+ }
+
+ public ArrayList<ArrayList<Number>> getData() {
+ return data;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ @Override
+ public Object clone()throws CloneNotSupportedException{
+ return super.clone();
+ }
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/SeriesOptions.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/SeriesOptions.java b/src/main/java/org/apache/hadoop/chukwa/hicc/SeriesOptions.java
new file mode 100644
index 0000000..74527d9
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/SeriesOptions.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.chukwa.hicc;
+
+public class SeriesOptions {
+ public boolean show = true;
+ public boolean fill = false;
+ public int lineWidth;
+ public String fillColor;
+
+ public boolean getFill() {
+ return fill;
+ }
+
+ public void setFill(boolean fill) {
+ this.fill = fill;
+ }
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Series.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Series.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Series.java
index 90d3963..c946086 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Series.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Series.java
@@ -64,4 +64,8 @@ public class Series {
public Object toJSONObject() {
return series;
}
+
+ public String getData() {
+ return (String) series.get("data");
+ }
}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/rest/ChartController.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/ChartController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/ChartController.java
new file mode 100644
index 0000000..93b8ab9
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/ChartController.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.chukwa.hicc.rest;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.lang.reflect.Type;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.hadoop.chukwa.datastore.ChukwaHBaseStore;
+import org.apache.hadoop.chukwa.hicc.Chart;
+import org.apache.hadoop.chukwa.hicc.Series;
+import org.apache.hadoop.chukwa.hicc.TimeHandler;
+import org.apache.log4j.Logger;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.mortbay.log.Log;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.sun.jersey.api.Responses;
+
+@Path("/chart")
+public class ChartController {
+ static Logger LOG = Logger.getLogger(ChartController.class);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+
+ @Context
+ VelocityEngine velocity;
+
+ /**
+ * Render chart using flot.js
+ *
+ * @param id Reference ID of Chart stored in HBase chukwa_meta table.
+ * @return html chart widget
+ */
+ @GET
+ @Path("draw/{id}")
+ @Produces(MediaType.TEXT_HTML)
+ public String draw(@PathParam("id") String id) {
+ VelocityContext context = new VelocityContext();
+ StringWriter sw = null;
+ try {
+ Chart chart = ChukwaHBaseStore.getChart(id);
+ List<Series> series = chart.getSeries();
+ Gson gson = new Gson();
+ String seriesMetaData = gson.toJson(series);
+
+ context.put("chart", chart);
+ context.put("seriesMetaData", seriesMetaData);
+ Template template = velocity.getTemplate("chart.vm");
+ sw = new StringWriter();
+ template.merge(context, sw);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return e.getMessage();
+ }
+ return sw.toString();
+ }
+
+ /**
+ * Describe chart meta data
+ */
+ @GET
+ @Path("describe/{id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public String describe(@PathParam("id") String id) {
+ Chart chart = ChukwaHBaseStore.getChart(id);
+ Gson gson = new Gson();
+ String buffer = gson.toJson(chart);
+ return buffer;
+ }
+
+ /**
+ * Create a new chart meta data
+ *
+ * @param chart
+ * @return
+ */
+ @POST
+ @Path("save")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response create(String buffer) {
+ try {
+ Gson gson = new Gson();
+ Chart chart = gson.fromJson(buffer, Chart.class);
+ String id = ChukwaHBaseStore.createChart(chart);
+ return Response.ok(id).build();
+ } catch (IOException e) {
+ return Responses.notAcceptable().build();
+ }
+
+ }
+
+ /**
+ * Save chart meta data
+ *
+ * @param chart
+ * @return
+ */
+ @PUT
+ @Path("save/{id}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response save(@PathParam("id") String id, String buffer) {
+ Gson gson = new Gson();
+ Chart chart = gson.fromJson(buffer, Chart.class);
+ ChukwaHBaseStore.putChart(id, chart);
+ return Response.ok().build();
+
+ }
+
+ /**
+ * Preview a chart
+ */
+ @PUT
+ @Path("preview")
+ public String preview(String buffer) {
+ VelocityContext context = new VelocityContext();
+ StringWriter sw = null;
+ try {
+ Gson gson = new Gson();
+ Chart chart = gson.fromJson(buffer, Chart.class);
+ List<Series> series = chart.getSeries();
+ String seriesMetaData = gson.toJson(series);
+
+ context.put("chart", chart);
+ context.put("seriesMetaData", seriesMetaData);
+ Template template = velocity.getTemplate("chart.vm");
+ sw = new StringWriter();
+ template.merge(context, sw);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return e.getMessage();
+ }
+ return sw.toString();
+ }
+
+ @PUT
+ @Path("preview/series")
+ @Produces("application/json")
+ public String previewSeries(@Context HttpServletRequest request, String buffer) {
+ Type listType = new TypeToken<ArrayList<Series>>() {
+ }.getType();
+ long startTime = 0;
+ long endTime = 0;
+ TimeHandler time = new TimeHandler(request);
+ startTime = time.getStartTime();
+ endTime = time.getEndTime();
+ Gson gson = new Gson();
+ ArrayList<Series> series = gson.fromJson(buffer, listType);
+ series = ChukwaHBaseStore.getChartSeries(series, startTime, endTime);
+ String result = gson.toJson(series);
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/rest/MetricsController.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/MetricsController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/MetricsController.java
index 61f8247..9730b43 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/MetricsController.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/MetricsController.java
@@ -37,6 +37,8 @@ import org.apache.hadoop.chukwa.hicc.TimeHandler;
import org.apache.hadoop.chukwa.hicc.bean.Series;
import org.json.simple.JSONArray;
+import com.google.gson.Gson;
+
@Path("/metrics")
public class MetricsController {
@@ -128,7 +130,7 @@ public class MetricsController {
@GET
@Path("schema/{metricGroup}")
@Produces("application/json")
- public String getFamilies(@PathParam("metricGroup") String metricGroup) {
+ public String getMetrics(@PathParam("metricGroup") String metricGroup) {
Set<String> metricNames = ChukwaHBaseStore.getMetricNames(metricGroup);
JSONArray metrics = new JSONArray();
for(String metric : metricNames) {
@@ -136,7 +138,7 @@ public class MetricsController {
}
return metrics.toString();
}
-
+
@GET
@Path("source/{metricGroup}")
@Produces("application/json")
@@ -148,4 +150,5 @@ public class MetricsController {
}
return rows.toString();
}
+
}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/hicc/rest/VelocityResolver.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/VelocityResolver.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/VelocityResolver.java
new file mode 100644
index 0000000..ea07797
--- /dev/null
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/VelocityResolver.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.chukwa.hicc.rest;
+
+import java.lang.reflect.Type;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.log4j.Logger;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+
+import com.sun.jersey.core.spi.component.ComponentContext;
+import com.sun.jersey.core.spi.component.ComponentScope;
+import com.sun.jersey.spi.inject.Injectable;
+import com.sun.jersey.spi.inject.InjectableProvider;
+
+@Provider
+public class VelocityResolver implements InjectableProvider<Context, Type> {
+ @Context
+ private ServletContext servletContext;
+
+ private VelocityEngine ve;
+ private static Logger LOG = Logger.getLogger(VelocityResolver.class);
+ public static String LOGGER_NAME = VelocityResolver.class.getName();
+
+ /**
+ * Jersey configuration for setting up Velocity configuration.
+ */
+ @Override
+ public Injectable<VelocityEngine> getInjectable(ComponentContext arg0,
+ Context arg1, Type c) {
+ if (c.equals(VelocityEngine.class)) {
+ return new Injectable<VelocityEngine>() {
+ public VelocityEngine getValue() {
+ if (ve == null) {
+ LOG.info("Ready to start velocity");
+ ve = new VelocityEngine();
+ ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
+ "org.apache.velocity.runtime.log.Log4JLogChute");
+ ve.setProperty("runtime.log.logsystem.log4j.logger",
+ LOGGER_NAME);
+ ve.setProperty(RuntimeConstants.RESOURCE_LOADER,
+ "webapp");
+ ve.setProperty("webapp.resource.loader.class",
+ "org.apache.velocity.tools.view.WebappResourceLoader");
+ ve.setProperty("webapp.resource.loader.path",
+ "/WEB-INF/vm/");
+ ve.setApplicationAttribute(
+ "javax.servlet.ServletContext", servletContext);
+ try {
+ ve.init();
+ LOG.info("Velocity is loaded");
+ } catch (Exception e) {
+ LOG.error("Error when initializing Velocity", e);
+ }
+ }
+ return ve;
+ }
+ };
+ }
+ return null;
+ }
+
+ public ComponentScope getScope() {
+ return ComponentScope.Singleton;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java b/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java
index d463dd1..b0ae38e 100644
--- a/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java
+++ b/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java
@@ -1,3 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.apache.hadoop.chukwa.util;
import java.security.MessageDigest;
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/WEB-INF/vm/chart.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/chart.vm b/src/main/web/hicc/WEB-INF/vm/chart.vm
new file mode 100644
index 0000000..90cb1d7
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/chart.vm
@@ -0,0 +1,106 @@
+#*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ *#
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <link href="/hicc/css/default.css" rel="stylesheet" type="text/css">
+ <link href="/hicc/css/iframe.css" rel="stylesheet" type="text/css">
+ <link href="/hicc/css/flexigrid/flexigrid.css" rel="stylesheet" type="text/css">
+ </head>
+ <body>
+ <div id="placeholderTitle"><center>$chart.getTitle()</center></div>
+ <div id="placeholder"></div>
+ <div class="legendHolder">
+ <div class="left"></div>
+ <div class="center" id="placeholderLegend"></div>
+ <div class="right"></div>
+ </div>
+ <div class="legendHolder">
+ <div class="center" id="statisLegend"></div>
+ </div>
+ <script type="text/javascript" src="/hicc/js/jquery-1.2.6.min.js"></script>
+ <script type="text/javascript" src="/hicc/js/jquery.flot.pack.js"></script>
+ <script type="text/javascript" src="/hicc/js/flexigrid.pack.js"></script>
+ <script type="text/javascript" src="/hicc/js/excanvas.pack.js"></script>
+ <script type="text/javascript" src="/hicc/js/base64.js"></script>
+ <script type="text/javascript" src="/hicc/js/canvas2image.js"></script>
+ <script type="text/javascript" src="/hicc/js/flot.extend.js"></script>
+
+ <script type="text/javascript">
+
+var chartTitle="<center>$chart.getTitle()</center>";
+var xLabels=new Array();
+
+var _options={
+ points: {
+ show: false
+ },
+ xaxis: {
+ mode: "time"
+ },
+ selection: {
+ mode: "xy",
+ color: "#999999"
+ },
+ grid: {
+ clickable: true,
+ hoverable: true,
+ tickColor: "#C0C0C0",
+ borderWidth: 0,
+ backgroundColor:"#F9F9F9"
+ },
+ legend: { show: true, noColumns: 3, container: $("#placeholderLegend") },
+ yaxis: {
+ #if ( $chart.getYMin()!=0 )
+ min: $chart.getYMin(),
+ #end
+ #if ( $chart.getYMax()!=0 )
+ max: $chart.getYMax(),
+ #end
+ tickFormatter: function(val, axis) {
+ #if ( $chart.getYUnitType().equals('bytes') )
+ #parse("unit-bytes-binary.vm")
+ #elseif ( $chart.getYUnitType().equals('bytes-decimal') )
+ #parse("unit-bytes-decimal.vm")
+ #elseif ( $chart.getYUnitType().equals('ops') )
+ #parse("unit-ops.vm")
+ #elseif ( $chart.getYUnitType().equals('percent') )
+ #parse("unit-percent.vm")
+ #else
+ #parse("unit-generic.vm")
+ #end
+ }
+ }
+};
+
+var _series=$seriesMetaData;
+var _seriesTemplate=$seriesMetaData;
+
+$(document).ready(function() {
+ reload();
+ $(window).resize(function() {
+ wholePeriod();
+ });
+});
+
+
+</script>
+<input type="hidden" id="boxId" value="iframe">
+<!-- <input type="button" value="Export" onclick="javascript:saveReport();"> -->
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/WEB-INF/vm/unit-bytes-binary.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/unit-bytes-binary.vm b/src/main/web/hicc/WEB-INF/vm/unit-bytes-binary.vm
new file mode 100644
index 0000000..96c6cf7
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/unit-bytes-binary.vm
@@ -0,0 +1,27 @@
+#*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ *#
+var bytes = val;
+var thresh = 1024;
+if(bytes < thresh) return bytes + 'B';
+ var units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
+ var u = -1;
+ do {
+ bytes /= thresh;
+ ++u;
+ } while(bytes >= thresh);
+return bytes.toFixed(1)+units[u];
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/WEB-INF/vm/unit-bytes-decimal.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/unit-bytes-decimal.vm b/src/main/web/hicc/WEB-INF/vm/unit-bytes-decimal.vm
new file mode 100644
index 0000000..ed91660
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/unit-bytes-decimal.vm
@@ -0,0 +1,27 @@
+#*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ *#
+var bytes = val;
+var thresh = 1000;
+if(bytes < thresh) return bytes + 'B';
+ var units = ['kB','MB','GB','TB','PB','EB','ZB','YB'];
+ var u = -1;
+ do {
+ bytes /= thresh;
+ ++u;
+ } while(bytes >= thresh);
+return bytes.toFixed(1)+units[u];
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/WEB-INF/vm/unit-generic.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/unit-generic.vm b/src/main/web/hicc/WEB-INF/vm/unit-generic.vm
new file mode 100644
index 0000000..2c56c1f
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/unit-generic.vm
@@ -0,0 +1,20 @@
+#*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ *#
+var parts = val.toString().split(".");
+parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+return parts.join(".");
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/WEB-INF/vm/unit-ops.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/unit-ops.vm b/src/main/web/hicc/WEB-INF/vm/unit-ops.vm
new file mode 100644
index 0000000..e863b6a
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/unit-ops.vm
@@ -0,0 +1,20 @@
+#*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ *#
+var parts = val.toString().split(".");
+parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+return parts.join(".") + "ops";
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/WEB-INF/vm/unit-percent.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/unit-percent.vm b/src/main/web/hicc/WEB-INF/vm/unit-percent.vm
new file mode 100644
index 0000000..d37807a
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/unit-percent.vm
@@ -0,0 +1,20 @@
+#*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ *#
+var parts = val.toString().split(".");
+parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+return parts.join(".") + "%";
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/css/default.css
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/css/default.css b/src/main/web/hicc/css/default.css
index eef956e..3a2741b 100644
--- a/src/main/web/hicc/css/default.css
+++ b/src/main/web/hicc/css/default.css
@@ -67,8 +67,7 @@ body {font-family:Oswald,Arial;background-color:#ffffff;}
.glossy_icon img {
position:relative; /*this is the key*/
z-index:24;
- filter:progid:DXImageTransform.Microsoft.Alpha(opacity=65);
- opacity:.65; -moz-opacity: 0.65;
+ opacity:.65;
text-decoration:none;
border:none;
}
@@ -78,14 +77,14 @@ body {font-family:Oswald,Arial;background-color:#ffffff;}
border:none;
text-decoration:none;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=100);
- opacity:1.00; -moz-opacity: 1.00;
+ opacity:1.00;
}
.glossy_icon:hover img {
z-index:25;
border:none;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=100);
- opacity:1.00; -moz-opacity: 1.00;
+ opacity:1.00;
}
.glossy_icon span{display: none}
@@ -107,7 +106,7 @@ body {font-family:Oswald,Arial;background-color:#ffffff;}
.glossy_icon:disabled {
border:none;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=25);
- opacity:.25; -moz-opacity: 0.25;
+ opacity:.25;
}
.group_box {
@@ -443,7 +442,6 @@ table.simple th {
border-color: #E1D8E5;
background-color: #E1D8E5;
font: bold 11px Arial; color:#000000;
- -moz-border-radius: ;
}
table.simple td {
text-decoration: none;
@@ -451,7 +449,6 @@ table.simple td {
padding: 2px;
border-style: inset;
border-color: #E1D8E5;
- -moz-border-radius: ;
}
thead.fixedHead {
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/css/iframe.css
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/css/iframe.css b/src/main/web/hicc/css/iframe.css
index 4f7555f..493e0b1 100644
--- a/src/main/web/hicc/css/iframe.css
+++ b/src/main/web/hicc/css/iframe.css
@@ -16,31 +16,31 @@
* limitations under the License.
*/
#statisLegend table {
- border-collapse: collapse;
+ border-collapse: collapse;
+ padding: 5px;
}
#statisLegend th strong {
- color: #fff;
+ color: #fff;
}
#statisLegend th {
- padding-left: 5px;
- padding-right: 5px;
- background: #93BC0C;
- color: #fff;
- text-align: center;
- border-left: 1px solid #B6D59A;
- border-bottom: solid 2px #fff;
+ padding-left: 5px;
+ padding-right: 5px;
+ background: #999999;
+ color: #fff;
+ text-align: center;
+ border-bottom: solid 2px #fff;
}
#statisLegend tr {
}
#statisLegend td {
- padding-left: 5px;
- padding-right: 5px;
- border-left: 1px solid #fff;
- border-bottom: 1px solid #fff;
+ padding-left: 5px;
+ padding-right: 5px;
+ border-left: 1px solid #fff;
+ border-bottom: 1px solid #fff;
}
#statisLegend td.first,th.first {
@@ -57,8 +57,73 @@
#statisLegend {
font-size: 0.85em;
+ margin: auto;
+ align: center;
+ overflow-x: hidden;
+ overflow-y: hidden;
}
.small_font {
font-size: 0.85em;
}
+
+#placeholder {
+ align: center;
+ width: 100%;
+ height: 70%;
+ min-height: 100px;
+ max-height: 480px;
+}
+
+#placeholder canvas {
+ width: 100%;
+ height: 100%;
+ margin: 0 auto;
+ min-height: 100px;
+ max-height: 450px;
+}
+
+.legendHolder {
+ text-align:center;
+ min-width: 400px;
+ min-height: 20px;
+}
+
+div.center {
+ display: inline-block;
+ margin:auto;
+ min-width: 200px;
+ min-height: 20px;
+}
+
+div.left {
+ display: inline-block;
+ margin:auto auto auto 0;
+ width: 20px;
+ height: 20px;
+}
+
+div.right {
+ display: inline-block;
+ margin:auto 0 auto auto;
+ width: 20px;
+ height: 20px;
+}
+
+#placeholderLegend {
+ margin: auto;
+ align: center;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
+
+.statisTable table th td {
+ table-layout:fixed;
+ overflow:hidden;
+ white-space: nowrap;
+}
+
+html, body {
+ height: 100%;
+ overflow: hidden;
+}
http://git-wip-us.apache.org/repos/asf/chukwa/blob/a6e0cbad/src/main/web/hicc/js/flot.extend.js
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/js/flot.extend.js b/src/main/web/hicc/js/flot.extend.js
index 5af6793..d7a2056 100644
--- a/src/main/web/hicc/js/flot.extend.js
+++ b/src/main/web/hicc/js/flot.extend.js
@@ -15,7 +15,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-var zoom=false;
+var pause=false;
+var timer;
var bound=null;
var _chartSeriesSize=0;
@@ -97,7 +98,6 @@ function calculateStatis() {
}
dataTable+='</table>';
$('#statisLegend').html(dataTable);
- setIframeHeight(document.getElementById('boxId').value);
}
/*
@@ -112,23 +112,31 @@ function showTooltip(x, y, contents) {
}
$('<div id="tooltip">' + contents + '</div>').css( {
position: 'absolute',
- display: 'none',
- top: y + 5,
- left: x + 5,
- border: '2px solid #aaa',
- padding: '2px',
- 'background-color': '#fff',
- }).appendTo("body").fadeIn(200);
+ display: 'none',
+ top: y + 5,
+ left: x + 5,
+ 'border-radius': '5px',
+ border: '2px solid #aaa',
+ padding: '2px',
+ 'background-color': '#fff',
+ }).appendTo("body").fadeIn(200);
}
/*
* calculate the height of the area and set the correct height for the chart, legend and the statis legend as well.
*/
function wholePeriod() {
- var cw = document.body.clientWidth-30;
- var ch = height-$("#placeholderTitle").height()-10;
- document.getElementById('placeholder').style.width=cw+'px';
- document.getElementById('placeholder').style.height=ch+'px';
+ var ch = document.body.clientHeight;
+ if (ch < 200 ) {
+ $('#placeholderLegend').hide();
+ $('#statisLegend').hide();
+ } else if (ch < 320) {
+ $('#placeholderLegend').show();
+ $('#statisLegend').hide();
+ } else {
+ $('#placeholderLegend').show();
+ $('#statisLegend').show();
+ }
$.plot($("#placeholder"), _series, _options);
// update statis
calculateStatis();
@@ -163,29 +171,29 @@ $("#placeholder").bind("plotclick", function (event, pos, item) {
};
if (item) {
if (previousPoint != item.datapoint) {
- previousPoint = item.datapoint;
-
- $("#tooltip").remove();
- if(xLabels.length==0) {
- var x = item.datapoint[0],
- y = item.stackValue.toFixed(2);
- var dnow=new Date();
- dnow.setTime(x);
- var dita=leftPad(dnow.getUTCFullYear())+"/"+leftPad(dnow.getUTCMonth()+1)+"/"+dnow.getUTCDate()+" "+leftPad(dnow.getUTCHours())+":"+leftPad(dnow.getUTCMinutes())+":"+leftPad(dnow.getUTCSeconds());
-
- showTooltip(item.pageX, item.pageY,
- item.series.label + ": " + y + "<br>Time: " + dita);
- } else {
- var x = item.datapoint[0],
- y = item.stackValue.toFixed(2);
- xLabel = xLabels[x];
- showTooltip(item.pageX, item.pageY,
- item.series.label + ": " + y + "<br>" + xLabel);
- }
+ previousPoint = item.datapoint;
+ pause = true;
+ $("#tooltip").remove();
+ if(xLabels.length==0) {
+ var x = item.datapoint[0],
+ y = item.stackValue.toFixed(2);
+ var dnow=new Date();
+ dnow.setTime(x);
+ var dita=leftPad(dnow.getUTCFullYear())+"/"+leftPad(dnow.getUTCMonth()+1)+"/"+dnow.getUTCDate()+" "+leftPad(dnow.getUTCHours())+":"+leftPad(dnow.getUTCMinutes())+":"+leftPad(dnow.getUTCSeconds());
+ showTooltip(item.pageX, item.pageY,
+ item.series.label + ": " + y + "<br>Time: " + dita);
+ } else {
+ var x = item.datapoint[0],
+ y = item.stackValue.toFixed(2);
+ xLabel = xLabels[x];
+ showTooltip(item.pageX, item.pageY,
+ item.series.label + ": " + y + "<br>" + xLabel);
+ }
}
} else {
$("#tooltip").remove();
- previousPoint = null;
+ previousPoint = null;
+ pause = false;
}
});
@@ -193,9 +201,13 @@ $("#placeholder").bind("plotclick", function (event, pos, item) {
* bind the function for resizing the area inside the chart.
*/
$("#placeholder").bind("selected", function (event, area) {
- zoom = true;
+ if(area.x1 == area.x2 && area.y1 == area.y2) {
+ pause = false;
+ } else {
+ pause = true;
+ }
extra_options = {};
- extra_options.xaxis={ min: area.x1, max: area.x2 };
+ extra_options.xaxis={ min: area.x1, max: area.x2 };
extra_options.yaxis={ min: area.y1, max: area.y2 };
bound = {};
bound.xmin=area.x1;
@@ -204,15 +216,14 @@ $("#placeholder").bind("selected", function (event, area) {
bound.ymax=area.y2;
calculateStatis();
plot = $.plot(
- $("#placeholder"),
- _series,
- $.extend(
- true,
- {},
- _options, extra_options
- )
- );
- setIframeHeight(document.getElementById('boxId').value);
+ $("#placeholder"),
+ _series,
+ $.extend(
+ true,
+ {},
+ _options, extra_options
+ )
+ );
});
/*
@@ -230,71 +241,30 @@ function getDocHeight(doc) {
}
/*
- * auto resize the iframe height to match content.
- */
-function setIframeHeight(ifrm) {
- try {
- objToResize = parent.document.getElementById(window.name);
- objToResize.height = document.body.scrollHeight;
- } catch(err) {
- window.status = err.message;
- }
-}
-
-/*
- * refresh the chart widget.
+ * Reload data
*/
-function refresh(url, parameters) {
- bound=null;
- if(zoom) {
- wholePeriod();
- zoom=false;
- } else {
- if(parameters.indexOf("render=stack")>0) {
- return false;
- }
- if(parameters.indexOf("_force_refresh")>0) {
- return false;
- }
- var dataURL = url+"?"+parameters;
- $.get(dataURL,{format: 'json'}, function(data){
- try {
- eval(data);
- wholePeriod();
- document.getElementById('placeholderTitle').innerHTML=chartTitle;
- } catch(err) {
- return false;
- }
- });a
- if(_rest!=null) {
- loadData(url, parameters);
- }
+function reload() {
+ if (!pause) {
+ loadData();
}
- return true;
+ timer = setTimeout(reload, 3000);
}
/*
* Initialize data from REST API.
*/
function loadData() {
- _chartSeriesSize=0;
- for(var i=0;i<_series.length;i++) {
- $.getJSON(_rest[i], function(json) {
- if(json.constructor.toString().indexOf("Array") != -1) {
- for(var index=0;index<json.length;index++) {
- _series[_chartSeriesSize].label=json[index].name;
- _series[_chartSeriesSize].data=json[index].data;
- _chartSeriesSize++;
- }
- } else {
- var name=json.name;
- _series[_chartSeriesSize].label=name;
- _series[_chartSeriesSize].data=json.data;
- _chartSeriesSize++;
- }
+ $.ajax({
+ url: '/hicc/v1/chart/preview/series',
+ type: 'PUT',
+ contentType: 'application/json',
+ data: JSON.stringify(_seriesTemplate),
+ dataType: "json",
+ success: function(result) {
+ _series = result;
wholePeriod();
- });
- }
+ }
+ });
}
/*