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/11/28 19:45:23 UTC

[1/3] chukwa git commit: CHUKWA-787. Added full screen support, and quick link to Hadoop and HBase UI. (Eric Yang)

Repository: chukwa
Updated Branches:
  refs/heads/master 0e518f8d7 -> 6b70f9e54


CHUKWA-787. Added full screen support, and quick link to Hadoop and HBase UI.  (Eric Yang)


Project: http://git-wip-us.apache.org/repos/asf/chukwa/repo
Commit: http://git-wip-us.apache.org/repos/asf/chukwa/commit/49384fb1
Tree: http://git-wip-us.apache.org/repos/asf/chukwa/tree/49384fb1
Diff: http://git-wip-us.apache.org/repos/asf/chukwa/diff/49384fb1

Branch: refs/heads/master
Commit: 49384fb15850145f728c62c5d7320881c4909450
Parents: 0e518f8
Author: Eric Yang <ey...@apache.org>
Authored: Fri Nov 27 19:27:48 2015 -0800
Committer: Eric Yang <ey...@apache.org>
Committed: Fri Nov 27 19:27:48 2015 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |   2 +
 .../chukwa/datastore/ChukwaHBaseStore.java      | 374 +++++++++++++------
 .../chukwa/hicc/rest/DashboardController.java   |  68 ++++
 src/main/web/hicc/WEB-INF/vm/quick-links.vm     |  63 ++++
 src/main/web/hicc/home/css/component.css        |  12 +-
 src/main/web/hicc/home/index.html               |  27 ++
 6 files changed, 439 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/chukwa/blob/49384fb1/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index cab670f..684b3f5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,8 @@ Trunk (unreleased changes)
 
   NEW FEATURES
 
+    CHUKWA-787. Added full screen support, and quick link to Hadoop and HBase UI.  (Eric Yang)
+
     CHUKWA-785. Added banner, pie chart, gauge chart to graph explorer.  (Eric Yang)
 
     CHUKWA-778. Added pie chart, circle chart and timeline javascripts.  (Eric Yang)

http://git-wip-us.apache.org/repos/asf/chukwa/blob/49384fb1/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 fec9281..120b731 100644
--- a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
+++ b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
@@ -424,8 +424,8 @@ public class ChukwaHBaseStore {
    * Create a chart in HBase by specifying parameters.
    * @throws URISyntaxException 
    */
-  public static synchronized String createChart(String id, String yunitType, 
-      String title, String[] metrics, String source) throws URISyntaxException {
+  public static synchronized String createChart(String id,
+      String title, String[] metrics, String source, String yunitType) throws URISyntaxException {
     Chart chart = new Chart(id);
     chart.setYUnitType(yunitType);
     chart.setTitle(title);
@@ -445,6 +445,58 @@ public class ChukwaHBaseStore {
   }
 
   /**
+   * Create a chart in HBase by specifying parameters.
+   * @throws URISyntaxException 
+   */
+  public static synchronized String createCircle(String id,
+      String title, String[] metrics, String source, String suffixLabel) throws URISyntaxException {
+    Chart chart = new Chart(id);
+    chart.setSuffixText(suffixLabel);
+    chart.setTitle(title);
+    ArrayList<SeriesMetaData> series = new ArrayList<SeriesMetaData>();
+    for(String metric : metrics) {
+      SeriesMetaData s = new SeriesMetaData();
+      s.setLabel(metric + "/" + source);
+      s.setUrl(new URI("/hicc/v1/metrics/series/" + metric + "/"
+        + source));
+      series.add(s);
+    }
+    chart.setSeries(series);
+    return createChart(chart);
+    
+  }
+
+  /**
+   * Create a tile in HBase by specifying parameters.
+   * @param id
+   * @param title
+   * @param bannerText
+   * @param suffixLabel
+   * @param metrics
+   * @param source
+   * @param icon
+   * @return
+   * @throws URISyntaxException
+   */
+  public static synchronized String createTile(String id, String title, 
+      String bannerText, String suffixLabel, String[] metrics, String source, 
+      String icon) throws URISyntaxException {
+    Chart chart = new Chart(id);
+    chart.setTitle(title);
+    chart.setBannerText(bannerText);
+    chart.setSuffixText(suffixLabel);
+    chart.setIcon(icon);
+    List<SeriesMetaData> smd = new ArrayList<SeriesMetaData>();
+    for (String metric : metrics) {
+      SeriesMetaData series = new SeriesMetaData();
+      series.setUrl(new URI("/hicc/v1/metrics/series/" + metric + "/" + source));
+      smd.add(series);
+    }
+    chart.setSeries(smd);
+    return createChart(chart);
+  }
+
+  /**
    * Create a chart in HBase.
    * 
    * @param chart
@@ -662,6 +714,13 @@ public class ChukwaHBaseStore {
           Result result = it.next();
           for(Cell kv : result.rawCells()) {
             snapshot = new String(CellUtil.cloneValue(kv));
+            if(snapshot.matches("-?\\d+(\\.\\d+)?")) {
+              int endOffset = snapshot.length();
+              if(snapshot.length() - snapshot.indexOf(".") > 2) {
+                endOffset = snapshot.indexOf(".") + 2;
+              }
+              snapshot = snapshot.substring(0, endOffset);
+            }
           }
         }
         data.add(snapshot);
@@ -848,41 +907,67 @@ public class ChukwaHBaseStore {
       String hostname = InetAddress.getLocalHost().getHostName().toLowerCase();
       // Populate example chart widgets
       String[] metrics = { "SystemMetrics.LoadAverage.1" };
-      createChart("1", "", "System Load Average", metrics, hostname);
+      createChart("1", "System Load Average", metrics, hostname, "");
       String[] cpuMetrics = { "SystemMetrics.cpu.combined", "SystemMetrics.cpu.sys", "SystemMetrics.cpu.user" };
-      createChart("2", "percent", "CPU Utilization", cpuMetrics, hostname);
+      createChart("2", "CPU Utilization", cpuMetrics, hostname, "percent");
       String[] memMetrics = { "SystemMetrics.memory.FreePercent", "SystemMetrics.memory.UsedPercent"};
-      createChart("3", "percent", "Memory Utilization", memMetrics, hostname);
+      createChart("3", "Memory Utilization", memMetrics, hostname, "percent");
       String[] diskMetrics = { "SystemMetrics.disk.ReadBytes", "SystemMetrics.disk.WriteBytes" };
-      createChart("4", "bytes-decimal", "Disk Utilization", diskMetrics, hostname);
+      createChart("4", "Disk Utilization", diskMetrics, hostname, "bytes-decimal");
       String[] netMetrics = { "SystemMetrics.network.TxBytes", "SystemMetrics.network.RxBytes" };
-      createChart("5", "bytes", "Network Utilization", netMetrics, hostname);
+      createChart("5", "Network Utilization", netMetrics, hostname, "bytes");
       String[] swapMetrics = { "SystemMetrics.swap.Total", "SystemMetrics.swap.Used", "SystemMetrics.swap.Free" };
-      createChart("6", "bytes-decimal", "Swap Utilization", swapMetrics, hostname);
+      createChart("6", "Swap Utilization", swapMetrics, hostname, "bytes-decimal");
+      
+      // Namenode heap usage
       StringBuilder namenode = new StringBuilder();
       namenode.append(hostname);
       namenode.append(":NameNode");
       String[] namenodeHeap = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("7", "percent", "Namenode Memory", namenodeHeap, namenode.toString());
+      createCircle("7", "Namenode Memory", namenodeHeap, namenode.toString(), "%");
+      
+      // HDFS Usage
       String[] hdfsUsage = { "HadoopMetrics.dfs.FSNamesystem.CapacityUsed", "HadoopMetrics.dfs.FSNamesystem.CapacityTotal" };
-      createChart("8", "percent", "HDFS Usage", hdfsUsage, hostname);
+      createCircle("8", "HDFS Usage", hdfsUsage, hostname, "%");
 
+      // Resource Manager Memory
       StringBuilder rmnode = new StringBuilder();
       rmnode.append(hostname);
       rmnode.append(":ResourceManager");
       String[] rmHeap = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("9", "percent", "Resource Manager Memory", rmHeap, rmnode.toString());
+      createCircle("9", "Resource Manager Memory", rmHeap, rmnode.toString(), "%");
 
+      // Node Managers Health
+      String[] nmh = { "HadoopMetrics.yarn.ClusterMetrics.NumActiveNMs", "HadoopMetrics.yarn.ClusterMetrics.NumLostNMs" };
+      createTile("10", "Node Managers Health", "Node Managers", "Active/Lost", nmh, hostname, "glyphicon-th");
+
+      // High Availability State
+      String[] ha = { "HadoopMetrics.dfs.FSNamesystem.HAState" };
+      createTile("11", "HDFS High Availability State", "HDFS High Availability", "", ha, hostname, "glyphicon-random");
+
+      // HDFS Load
+      String[] hdfsLoad = { "HadoopMetrics.dfs.FSNamesystem.TotalLoad" };
+      createTile("12", "HDFS Load Average", "HDFS Load", "", hdfsLoad, hostname, "glyphicon-signal");
+
+      // Namenode RPC Latency
+      String[] nnLatency = { "HadoopMetrics.rpc.rpc.RpcProcessingTimeAvgTime" };
+      createTile("13", "NameNode Latency", "NameNode RPC Latency", "Milliseconds", nnLatency, hostname, "glyphicon-tasks");
+
+      // Datanode Health
+      String[] dnHealth = { "HadoopMetrics.dfs.FSNamesystem.StaleDataNodes" };
+      createTile("14", "Datanodes Health", "Datanodes", "Dead", dnHealth, hostname, "glyphicon-hdd");
+
+      // HBase Master Memory
       StringBuilder hbaseMaster = new StringBuilder();
       hbaseMaster.append(hostname);
       hbaseMaster.append(":Master");
       String[] hbm = { "HBaseMetrics.jvm.JvmMetrics.MemHeapUsedM", "HBaseMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("10", "percent", "HBase Master Memory", hbm, hbaseMaster.toString());
+      createCircle("15", "HBase Master Memory", hbm, hbaseMaster.toString(), "%");
 
       // Demo metrics
-      String[] trialAbandonRate = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createChart("11", "percent", "Trial Abandon Rate", trialAbandonRate, namenode.toString());
-      createChart("12", "percent", "Unhealthy Clusters", hdfsUsage, hostname);
+//      String[] trialAbandonRate = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
+//      createChart("T1", "Trial Abandon Rate", trialAbandonRate, namenode.toString(), "percent");
+//      createChart("T2", "Unhealthy Clusters", hdfsUsage, hostname, "percent");
       
       // Populate default widgets
       Widget widget = new Widget();
@@ -902,7 +987,7 @@ public class ChukwaHBaseStore {
       widget.setSrc(new URI("/hicc/welcome.html"));
       widget.setCol(1);
       widget.setRow(1);
-      widget.setSize_x(9);
+      widget.setSize_x(10);
       widget.setSize_y(5);
       createWidget(widget);
       dashboard.add(widget);
@@ -992,25 +1077,65 @@ public class ChukwaHBaseStore {
 
       // Populate user dashboards
       dashboard = new Dashboard();
+
       widget = new Widget();
-      widget.setTitle("Top Applications");
-      widget.setSrc(new URI("/hicc/apps/"));
+      widget.setTitle("Quick Links");
+      widget.setSrc(new URI("/hicc/v1/dashboard/quicklinks"));
       widget.setCol(1);
       widget.setRow(1);
-      widget.setSize_x(2);
-      widget.setSize_y(2);
+      widget.setSize_x(10);
+      widget.setSize_y(5);
+      createWidget(widget);
       dashboard.add(widget);
 
       // Log Search widget
       widget = new Widget();
       widget.setTitle("Log Search");
       widget.setSrc(new URI("/hicc/ajax-solr/chukwa"));
-      widget.setCol(3);
+      widget.setCol(1);
       widget.setRow(1);
       widget.setSize_x(6);
       widget.setSize_y(6);
       createWidget(widget);
-      dashboard.add(widget);
+
+      // Applications
+      widget = new Widget();
+      widget.setTitle("YARN Applications");
+      widget.setSrc(new URI("http://localhost:8088/"));
+      widget.setCol(1);
+      widget.setRow(7);
+      widget.setSize_x(6);
+      widget.setSize_y(6);
+      createWidget(widget);
+
+      // Hadoop Distributed File System
+      widget = new Widget();
+      widget.setTitle("HDFS");
+      widget.setSrc(new URI("http://localhost:50070/explorer.html#/"));
+      widget.setCol(1);
+      widget.setRow(7);
+      widget.setSize_x(6);
+      widget.setSize_y(6);
+      createWidget(widget);
+
+      // HBase Tables
+      widget = new Widget();
+      widget.setTitle("HBase Tables");
+      widget.setSrc(new URI("http://localhost:50654/tablesDetailed.jsp"));
+      widget.setCol(1);
+      widget.setRow(14);
+      widget.setSize_x(6);
+      widget.setSize_y(6);
+      createWidget(widget);
+
+      widget = new Widget();
+      widget.setTitle("Top Applications");
+      widget.setSrc(new URI("/hicc/apps/"));
+      widget.setCol(1);
+      widget.setRow(1);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
+      createWidget(widget);
 
       widget = new Widget();
       widget.setTitle("Top Users");
@@ -1020,116 +1145,116 @@ public class ChukwaHBaseStore {
       widget.setSize_x(2);
       widget.setSize_y(2);
       createWidget(widget);
-      dashboard.add(widget);
       updateDashboard("user", "", dashboard);
 
       // Populate system dashboards
       dashboard = new Dashboard();
       widget = new Widget();
-      widget.setTitle("Services Running");
-      widget.setSrc(new URI("/hicc/services/services.html"));
+      widget.setTitle("HDFS High Availability State");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/11"));
       widget.setCol(1);
       widget.setRow(1);
       widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
-      
+
       widget = new Widget();
-      widget.setTitle("Applications Running");
-      widget.setSrc(new URI("/hicc/home/apps.html"));
+      widget.setTitle("HDFS Load");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/12"));
       widget.setCol(3);
       widget.setRow(1);
       widget.setSize_x(2);
       widget.setSize_y(1);
+      createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("HDFS Usage");
-      widget.setSrc(new URI("/hicc/v1/circles/draw/8"));
+      widget.setTitle("HDFS Namenode Latency");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/13"));
       widget.setCol(5);
       widget.setRow(1);
-      widget.setSize_x(1);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("Namenode Memory");
-      widget.setSrc(new URI("/hicc/v1/circles/draw/7"));
-      widget.setCol(6);
+      widget.setTitle("Datanodes Health");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/14"));
+      widget.setCol(7);
       widget.setRow(1);
-      widget.setSize_x(1);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
-
+      
       widget = new Widget();
-      widget.setTitle("Resource Manager Memory");
-      widget.setSrc(new URI("/hicc/v1/circles/draw/9"));
-      widget.setCol(7);
+      widget.setTitle("Node Managers Health");
+      widget.setSrc(new URI("/hicc/v1/tile/draw/10"));
+      widget.setCol(9);
       widget.setRow(1);
-      widget.setSize_x(1);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("HBase Master Memory");
-      widget.setSrc(new URI("/hicc/v1/circles/draw/10"));
-      widget.setCol(8);
-      widget.setRow(1);
-      widget.setSize_x(1);
-      widget.setSize_y(1);
+      widget.setTitle("HDFS Usage");
+      widget.setSrc(new URI("/hicc/v1/circles/draw/8"));
+      widget.setCol(1);
+      widget.setRow(2);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("System Load Average");
-      widget.setSrc(new URI("/hicc/v1/chart/draw/1"));
-      widget.setCol(1);
+      widget.setTitle("Namenode Memory");
+      widget.setSrc(new URI("/hicc/v1/circles/draw/7"));
+      widget.setCol(3);
       widget.setRow(2);
-      widget.setSize_x(3);
-      widget.setSize_y(1);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("Disk Utilization");
-      widget.setSrc(new URI("/hicc/v1/chart/draw/4"));
-      widget.setCol(4);
+      widget.setTitle("Resource Manager Memory");
+      widget.setSrc(new URI("/hicc/v1/circles/draw/9"));
+      widget.setCol(5);
       widget.setRow(2);
-      widget.setSize_x(3);
-      widget.setSize_y(1);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("Timeline");
-      widget.setSrc(new URI("/hicc/timeline/"));
+      widget.setTitle("HBase Master Memory");
+      widget.setSrc(new URI("/hicc/v1/circles/draw/15"));
       widget.setCol(7);
       widget.setRow(2);
-      widget.setSize_x(4);
-      widget.setSize_y(6);
+      widget.setSize_x(2);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("CPU Utilization");
-      widget.setSrc(new URI("/hicc/v1/chart/draw/2"));
-      widget.setCol(1);
-      widget.setRow(3);
-      widget.setSize_x(3);
+      widget.setTitle("System Load Average");
+      widget.setSrc(new URI("/hicc/v1/chart/draw/1"));
+      widget.setCol(9);
+      widget.setRow(2);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("Network Utilization");
-      widget.setSrc(new URI("/hicc/v1/chart/draw/5"));
-      widget.setCol(4);
+      widget.setTitle("CPU Utilization");
+      widget.setSrc(new URI("/hicc/v1/chart/draw/2"));
+      widget.setCol(9);
       widget.setRow(3);
-      widget.setSize_x(3);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
@@ -1137,9 +1262,9 @@ public class ChukwaHBaseStore {
       widget = new Widget();
       widget.setTitle("Memory Utilization");
       widget.setSrc(new URI("/hicc/v1/chart/draw/3"));
-      widget.setCol(1);
+      widget.setCol(9);
       widget.setRow(4);
-      widget.setSize_x(3);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
@@ -1147,68 +1272,109 @@ public class ChukwaHBaseStore {
       widget = new Widget();
       widget.setTitle("Swap Utilization");
       widget.setSrc(new URI("/hicc/v1/chart/draw/6"));
-      widget.setCol(4);
-      widget.setRow(4);
-      widget.setSize_x(3);
+      widget.setCol(9);
+      widget.setRow(5);
+      widget.setSize_x(2);
       widget.setSize_y(1);
       createWidget(widget);
       dashboard.add(widget);
 
-      // CPU heatmap
       widget = new Widget();
-      widget.setTitle("CPU Heatmap");
-      widget.setSrc(new URI("/hicc/v1/heatmap/render/SystemMetrics/cpu.combined."));
+      widget.setTitle("Disk Utilization");
+      widget.setSrc(new URI("/hicc/v1/chart/draw/4"));
       widget.setCol(1);
-      widget.setRow(5);
-      widget.setSize_x(6);
-      widget.setSize_y(5);
+      widget.setRow(4);
+      widget.setSize_x(4);
+      widget.setSize_y(2);
       createWidget(widget);
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("Alerts");
-      widget.setSrc(new URI("/hicc/alerts/"));
-      widget.setCol(1);
-      widget.setRow(5);
-      widget.setSize_x(6);
-      widget.setSize_y(5);
+      widget.setTitle("Network Utilization");
+      widget.setSrc(new URI("/hicc/v1/chart/draw/5"));
+      widget.setCol(5);
+      widget.setRow(4);
+      widget.setSize_x(4);
+      widget.setSize_y(2);
       createWidget(widget);
+      dashboard.add(widget);
 
+      // CPU heatmap
       widget = new Widget();
-      widget.setTitle("Log Errors");
-      widget.setSrc(new URI("/hicc/logs/"));
+      widget.setTitle("CPU Heatmap");
+      widget.setSrc(new URI("/hicc/v1/heatmap/render/SystemMetrics/cpu.combined."));
       widget.setCol(1);
       widget.setRow(5);
       widget.setSize_x(6);
       widget.setSize_y(5);
       createWidget(widget);
 
+      // HDFS Namenode
       widget = new Widget();
-      widget.setTitle("Web Stats");
-      widget.setSrc(new URI("https://birepo-internal.svl.ibm.com/awstats/awstats.pl?config=ibm-open-platform&framename=mainright&month=08&year=2015#month"));
+      widget.setTitle("HDFS UI");
+      widget.setSrc(new URI("http://localhost:50070/"));
       widget.setCol(1);
-      widget.setRow(5);
+      widget.setRow(11);
       widget.setSize_x(6);
-      widget.setSize_y(5);
+      widget.setSize_y(6);
       createWidget(widget);
 
+      // HBase Master
       widget = new Widget();
-      widget.setTitle("Sessions");
-      widget.setSrc(new URI("https://birepo-internal.svl.ibm.com/awstats/awstats.pl?config=ibm-open-platform&framename=mainright&month=08&year=2015#sessions"));
+      widget.setTitle("HBase Master UI");
+      widget.setSrc(new URI("http://localhost:16010/"));
       widget.setCol(1);
-      widget.setRow(5);
+      widget.setRow(18);
       widget.setSize_x(6);
-      widget.setSize_y(5);
+      widget.setSize_y(6);
       createWidget(widget);
 
-      widget = new Widget();
-      widget.setTitle("Domains");
-      widget.setSrc(new URI("https://birepo-internal.svl.ibm.com/awstats/awstats.pl?config=ibm-open-platform&framename=mainright&month=08&year=2015#domains"));
-      widget.setCol(1);
-      widget.setRow(5);
-      widget.setSize_x(6);
-      widget.setSize_y(5);
-      createWidget(widget);
+//    widget = new Widget();
+//    widget.setTitle("Services Running");
+//    widget.setSrc(new URI("/hicc/services/services.html"));
+//    widget.setCol(1);
+//    widget.setRow(1);
+//    widget.setSize_x(2);
+//    widget.setSize_y(1);
+//    createWidget(widget);
+//    dashboard.add(widget);
+//    
+//    widget = new Widget();
+//    widget.setTitle("Applications Running");
+//    widget.setSrc(new URI("/hicc/home/apps.html"));
+//    widget.setCol(3);
+//    widget.setRow(1);
+//    widget.setSize_x(2);
+//    widget.setSize_y(1);
+//    dashboard.add(widget);
+
+//    widget = new Widget();
+//    widget.setTitle("Timeline");
+//    widget.setSrc(new URI("/hicc/timeline/"));
+//    widget.setCol(7);
+//    widget.setRow(2);
+//    widget.setSize_x(4);
+//    widget.setSize_y(6);
+//    createWidget(widget);
+//    dashboard.add(widget);
+
+//      widget = new Widget();
+//      widget.setTitle("Alerts");
+//      widget.setSrc(new URI("/hicc/alerts/"));
+//      widget.setCol(1);
+//      widget.setRow(5);
+//      widget.setSize_x(6);
+//      widget.setSize_y(5);
+//      createWidget(widget);
+//
+//      widget = new Widget();
+//      widget.setTitle("Log Errors");
+//      widget.setSrc(new URI("/hicc/logs/"));
+//      widget.setCol(1);
+//      widget.setRow(5);
+//      widget.setSize_x(6);
+//      widget.setSize_y(5);
+//      createWidget(widget);
 
       updateDashboard("system", "", dashboard);
       

http://git-wip-us.apache.org/repos/asf/chukwa/blob/49384fb1/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java
index 987e405..16133f4 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/rest/DashboardController.java
@@ -17,6 +17,9 @@
  */
 package org.apache.hadoop.chukwa.hicc.rest;
 
+import java.io.StringWriter;
+import java.util.Set;
+
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -24,6 +27,7 @@ import javax.ws.rs.GET;
 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;
@@ -31,7 +35,15 @@ import javax.ws.rs.core.Response.Status;
 
 import org.apache.hadoop.chukwa.datastore.ChukwaHBaseStore;
 import org.apache.hadoop.chukwa.hicc.bean.Dashboard;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hdfs.DFSConfigKeys;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.log4j.Logger;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
 
 import com.google.gson.Gson;
 
@@ -41,6 +53,9 @@ public class DashboardController {
 
   @Context
   private ServletContext context;
+  @Context
+  VelocityEngine velocity;
+
   
   @GET
   @Path("load/{id}")
@@ -69,4 +84,57 @@ public class DashboardController {
   public String whoami(@Context HttpServletRequest request) {
     return request.getRemoteUser();
   }
+  
+  @GET
+  @Path("quicklinks")
+  @Produces(MediaType.TEXT_HTML)
+  public String quicklinks() {
+    VelocityContext context = new VelocityContext();
+    StringWriter sw = null;
+    Configuration hconf = HBaseConfiguration.create();
+    Configuration hadoop = new Configuration();
+    String nn = "";
+    String rm = "";
+    String hm = "";
+    Set<String> sourceNames = ChukwaHBaseStore.getSourceNames("");
+    for (String source : sourceNames) {
+      String[] sourceParts = source.split(":");
+      if(sourceParts.length<2) {
+        continue;
+      }
+      if(sourceParts[1].equals("NameNode")) {
+        String[] parts = hadoop.get(DFSConfigKeys.DFS_NAMENODE_HTTP_ADDRESS_KEY).split(":");
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(sourceParts[0]);
+        buffer.append(":");
+        buffer.append(parts[1]);
+        nn = buffer.toString();
+      } else if(sourceParts[1].equals("ResourceManager")) {
+        String[] parts = hadoop.get(YarnConfiguration.RM_WEBAPP_ADDRESS).split(":");
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(sourceParts[0]);
+        buffer.append(":");
+        buffer.append(parts[1]);
+        rm = buffer.toString();
+      } else if(sourceParts[1].equals("Master")) {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(sourceParts[0]);
+        buffer.append(":");
+        buffer.append(hconf.getInt("hbase.master.info.port", HConstants.DEFAULT_MASTER_INFOPORT));
+        hm = buffer.toString();
+      }
+    }
+    try {
+      context.put("nn", nn);
+      context.put("rm", rm);
+      context.put("hm", hm);
+      Template template = velocity.getTemplate("quick-links.vm");
+      sw = new StringWriter();
+      template.merge(context, sw);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return e.getMessage();
+    }
+    return sw.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/chukwa/blob/49384fb1/src/main/web/hicc/WEB-INF/vm/quick-links.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/quick-links.vm b/src/main/web/hicc/WEB-INF/vm/quick-links.vm
new file mode 100644
index 0000000..fd6bf9b
--- /dev/null
+++ b/src/main/web/hicc/WEB-INF/vm/quick-links.vm
@@ -0,0 +1,63 @@
+<!--
+   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" class="no-js">
+  <head>
+    <link href="/hicc/css/bootstrap-theme.min.css" type="text/css" rel="stylesheet" />
+    <link href="/hicc/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
+    <script src="/hicc/js/jquery.js" type="text/javascript"></script>
+    <script src="/hicc/js/bootstrap.min.js" type="text/javascript"></script>
+    <style>
+      html, body, .row, .container {
+        height: 100%;
+        min-height: 100%;
+      }
+      .menu {
+        float:left;
+        height: 95%;
+      }
+      .main {
+        float:left;
+        height: 95%;
+      }
+      iframe {
+        border: 0px none transparent;
+        width: 100%;
+        height: 100%;
+      }
+      .container {
+        width: 100%;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="container">
+      <div class="row">
+        <div class="menu col-md-2 col-lg-2">
+          <h1>Quick Links</h1>
+          <p><a href="http://$nn/explorer.html#/" target="link_target">Browse File System</a></p>
+          <p><a href="http://$hm/tablesDetailed.jsp" target="link_target">Browse HBase Tables</a></p>
+          <p><a href="http://$rm/" target="link_target">Browse Hadoop Applications</a></p>
+          <p><a href="/hicc/ajax-solr/chukwa/" target="link_target">Search Log Files</a></p>
+        </div>
+        <div class="main col-md-10 col-lg-10">
+          <iframe id="link_target" src="/hicc/ajax-solr/chukwa/" width="100%" height="100%"></iframe>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/chukwa/blob/49384fb1/src/main/web/hicc/home/css/component.css
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/css/component.css b/src/main/web/hicc/home/css/component.css
index 9b4bcec..1d4d53e 100755
--- a/src/main/web/hicc/home/css/component.css
+++ b/src/main/web/hicc/home/css/component.css
@@ -243,10 +243,10 @@ body {
 		user-select: none;
 }
 
-.gn-menu-main > li:nth-last-child(2) {
+.gn-menu-main > li:nth-last-child(3) {
 		padding-right: 10px;
                 position: absolute;
-		right: 82px;
+		right: 164px;
 		overflow: hidden;
 		float: left;
 		border-left: none;
@@ -254,7 +254,7 @@ body {
 		white-space: nowrap;
 }
 
-.gn-menu-main > li:last-child {
+.gn-menu-main > li:nth-last-child(-n+2) {
 		width: 82px;
 		float: right;
 		border-right: none;
@@ -457,6 +457,12 @@ input.gn-search:focus {
 		content: "\e017";
 }
 
+.gn-icon-fullscreen::before {
+		font-family: 'Glyphicons Halflings';
+		font-size: 18px;
+		content: "\e140";
+}
+
 .gn-icon-home::before {
 		font-family: 'Glyphicons Halflings';
 		font-size: 18px;

http://git-wip-us.apache.org/repos/asf/chukwa/blob/49384fb1/src/main/web/hicc/home/index.html
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/index.html b/src/main/web/hicc/home/index.html
index b7ed0a1..828c291 100755
--- a/src/main/web/hicc/home/index.html
+++ b/src/main/web/hicc/home/index.html
@@ -72,6 +72,7 @@
         </li>
         <li><span id="username"></span></li>
         <li><a class="gn-icon-poweroff" onclick="logout()"><span> </span></a></li>
+        <li><a class="gn-icon-fullscreen" onclick="toggleFullScreen()"><span> </span></a></li>
       </ul>
     </div><!-- /container -->
     <div class="gridster">
@@ -111,6 +112,32 @@ var substringMatcher = function(strs) {
   };
 };
 
+function toggleFullScreen() {
+  var element = document.documentElement;
+  if(document.fullscreenElement ||
+	document.webkitFullscreenElement ||
+	document.mozFullScreenElement ||
+	document.msFullscreenElement) {
+    if(document.exitFullscreen) {
+      document.exitFullscreen();
+    } else if(document.mozCancelFullScreen) {
+      document.mozCancelFullScreen();
+    } else if(document.webkitExitFullscreen) {
+      document.webkitExitFullscreen();
+    }
+  } else {
+    if(element.requestFullscreen) {
+      element.requestFullscreen();
+    } else if(element.mozRequestFullScreen) {
+      element.mozRequestFullScreen();
+    } else if(element.webkitRequestFullscreen) {
+      element.webkitRequestFullscreen();
+    } else if(element.msRequestFullscreen) {
+      element.msRequestFullscreen();
+    }
+  }
+}
+
 function toggleGlass() {
   $('#glass').toggle();
 }


[3/3] chukwa git commit: CHUKWA-789. Added HBase schema to data model document. (Eric Yang)

Posted by ey...@apache.org.
CHUKWA-789. Added HBase schema to data model document. (Eric Yang)


Project: http://git-wip-us.apache.org/repos/asf/chukwa/repo
Commit: http://git-wip-us.apache.org/repos/asf/chukwa/commit/6b70f9e5
Tree: http://git-wip-us.apache.org/repos/asf/chukwa/tree/6b70f9e5
Diff: http://git-wip-us.apache.org/repos/asf/chukwa/diff/6b70f9e5

Branch: refs/heads/master
Commit: 6b70f9e544074bedddb573f3ab4cf45ce0f0eea8
Parents: aa76d99
Author: Eric Yang <ey...@apache.org>
Authored: Sat Nov 28 10:42:59 2015 -0800
Committer: Eric Yang <ey...@apache.org>
Committed: Sat Nov 28 10:42:59 2015 -0800

----------------------------------------------------------------------
 CHANGES.txt                |  2 +
 src/site/apt/datamodel.apt | 90 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 91 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/chukwa/blob/6b70f9e5/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 6d37755..01e8f6d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -30,6 +30,8 @@ Trunk (unreleased changes)
 
   IMPROVEMENTS
 
+    CHUKWA-789. Added HBase schema to data model document. (Eric Yang)
+
     CHUKWA-786. Update documentation to reflect 0.7 release. (Eric Yang)
 
     CHUKWA-773. Update maven surefire version.  (Anna Wang via Eric Yang)

http://git-wip-us.apache.org/repos/asf/chukwa/blob/6b70f9e5/src/site/apt/datamodel.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/datamodel.apt b/src/site/apt/datamodel.apt
index 1aae1f5..7f44c78 100644
--- a/src/site/apt/datamodel.apt
+++ b/src/site/apt/datamodel.apt
@@ -51,4 +51,92 @@ little peculiar, but it's actually the same way that TCP sequence numbers work.
 correctly after a crash, and not send redundant data. When starting adaptors, 
 it's usually save to specify 0 as an ID, but it's sometimes useful to specify 
 something else. For instance, it lets you do things like only tail the second 
-half of a file. 
+half of a file.
+
+HBase Schema
+
+* Metrics
+
+  Chukwa table stores time series data.
+
+** Row Key
+
+*------*------*------------*------------*
+|      | Day  | Metric MD5 | Source MD5 |
+*------*------*------------*------------*
+| Size | 2    | 6          | 6          |
+*------*------*------------*------------*
+
+  Row key is composed of 14 bytes data.  First 2 bytes are day of the year.
+The next 6 bytes are md5 signature of metrics name.  The last 6 bytes are
+md5 signature of data source.  This arrangement helps Chukwa to partition
+data evenly across regions base on time.
+
+  This arrangement provides a good condensed store for data of the same day
+for the same source.
+
+** Column Family
+
+  The column family format for Chukwa table are:
+
+*---------------*-----------------------------------------------------------------:
+| Column Family | Description                                                     |
+*---------------*-----------------------------------------------------------------:
+| t             | Time series data.  Column name is timestamp.  Value is a string |
+*---------------*-----------------------------------------------------------------:
+| a             | Annotation, string tags associated with time series data.       |
+*---------------*-----------------------------------------------------------------:
+
+* Metadata
+
+  Metadata is designed to store point lookup data.  For example, small amount of 
+data to describe the metric name mapping for chukwa table.  It is also used to store
+JSON blob of dashboard data.
+
+** Row Key
+
+*----------------*------------------------------------------------------------------:
+| Row Key        | Description                                                      |
+*----------------*------------------------------------------------------------------:
+| [Metrics Group]| Metrics Group Name, this allows to fetch all metrics name from   |
+|                | the group can be fetched from loading the row key.               |
+*----------------*------------------------------------------------------------------:
+| chart_meta     | All charts are stored in this row.                               |
+*----------------*------------------------------------------------------------------:
+| dashboard_meta | All dashboard are stored in this row.                            |
+*----------------*------------------------------------------------------------------:
+| widget_meta    | All widgets are stored in this row.                              |
+*----------------*------------------------------------------------------------------:
+
+** Special Row
+
+*----------------*------------------------------------------------------------------:
+| chart_meta     | Cell contains the rendering option and metric series name in     |
+|                | a JSON blob                                                      |
+*----------------*------------------------------------------------------------------:
+| dashboard_meta | Cell describes one dashboard view                                |
+*----------------*------------------------------------------------------------------:
+| widget_meta    | Cell describes title and URL of a dashboard widget               |
+*----------------*------------------------------------------------------------------:
+
+** Column Family
+
+*---------------*-------------------------------------------------------------------:
+| Column Family | Description                                                       |
+*---------------*-------------------------------------------------------------------:
+| k             | Key, associated with a fixed structure for describing key types   |
+|               | and md5 signature of the key used in chukwa table.                |
+*---------------*-------------------------------------------------------------------:
+| c             | column for storing JSON blob for special rows.  This column is    |
+|               | used to store dashboard, chart, and widget metadata.              |
+*---------------*-------------------------------------------------------------------:
+
+  Key Types for k column Family, the current supported key types are:
+
+*----------*----------------------------------------------------:
+| Type     | Description                                        |
+*----------*----------------------------------------------------:
+| metric   | This key is a metric name.                         |
+*----------*----------------------------------------------------:
+| source   | This key is a source name.                         |
+*----------*----------------------------------------------------:


[2/3] chukwa git commit: CHUKWA-788. Save ring chart threshold setting in HBase. (Eric Yang)

Posted by ey...@apache.org.
CHUKWA-788. Save ring chart threshold setting in HBase. (Eric Yang)


Project: http://git-wip-us.apache.org/repos/asf/chukwa/repo
Commit: http://git-wip-us.apache.org/repos/asf/chukwa/commit/aa76d992
Tree: http://git-wip-us.apache.org/repos/asf/chukwa/tree/aa76d992
Diff: http://git-wip-us.apache.org/repos/asf/chukwa/diff/aa76d992

Branch: refs/heads/master
Commit: aa76d992103168e93b7d1b2c1c92d67fad843567
Parents: 49384fb
Author: Eric Yang <ey...@apache.org>
Authored: Sat Nov 28 10:38:30 2015 -0800
Committer: Eric Yang <ey...@apache.org>
Committed: Sat Nov 28 10:38:30 2015 -0800

----------------------------------------------------------------------
 CHANGES.txt                                     |  2 ++
 .../chukwa/datastore/ChukwaHBaseStore.java      | 15 +++++++-------
 .../apache/hadoop/chukwa/hicc/bean/Chart.java   |  9 +++++++++
 .../apache/hadoop/chukwa/util/HBaseUtil.java    | 14 ++++++-------
 src/main/web/hicc/WEB-INF/vm/circles.vm         | 21 ++++++++++++++------
 src/main/web/hicc/home/css/jquery.gridster.css  |  6 +++---
 src/main/web/hicc/home/graph-explorer.html      | 10 ++++++----
 7 files changed, 50 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/chukwa/blob/aa76d992/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 684b3f5..6d37755 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -66,6 +66,8 @@ Trunk (unreleased changes)
 
   BUGS
 
+    CHUKWA-788. Save ring chart threshold setting in HBase. (Eric Yang)
+
     CHUKWA-784. Improve CharFileTailingAdaptorUTF8NewLineEscaped and LocalWriter 
                 logic to send proper data chunk. (Eric Yang)
 

http://git-wip-us.apache.org/repos/asf/chukwa/blob/aa76d992/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 120b731..bdd765d 100644
--- a/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
+++ b/src/main/java/org/apache/hadoop/chukwa/datastore/ChukwaHBaseStore.java
@@ -449,10 +449,11 @@ public class ChukwaHBaseStore {
    * @throws URISyntaxException 
    */
   public static synchronized String createCircle(String id,
-      String title, String[] metrics, String source, String suffixLabel) throws URISyntaxException {
+      String title, String[] metrics, String source, String suffixLabel, String direction) throws URISyntaxException {
     Chart chart = new Chart(id);
     chart.setSuffixText(suffixLabel);
     chart.setTitle(title);
+    chart.setThreshold(direction);
     ArrayList<SeriesMetaData> series = new ArrayList<SeriesMetaData>();
     for(String metric : metrics) {
       SeriesMetaData s = new SeriesMetaData();
@@ -924,18 +925,18 @@ public class ChukwaHBaseStore {
       namenode.append(hostname);
       namenode.append(":NameNode");
       String[] namenodeHeap = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createCircle("7", "Namenode Memory", namenodeHeap, namenode.toString(), "%");
+      createCircle("7", "Namenode Memory", namenodeHeap, namenode.toString(), "%", "up");
       
       // HDFS Usage
-      String[] hdfsUsage = { "HadoopMetrics.dfs.FSNamesystem.CapacityUsed", "HadoopMetrics.dfs.FSNamesystem.CapacityTotal" };
-      createCircle("8", "HDFS Usage", hdfsUsage, hostname, "%");
+      String[] hdfsUsage = { "HadoopMetrics.dfs.FSNamesystem.CapacityRemainingGB", "HadoopMetrics.dfs.FSNamesystem.CapacityTotalGB" };
+      createCircle("8", "HDFS Remaining", hdfsUsage, hostname, "%", "down");
 
       // Resource Manager Memory
       StringBuilder rmnode = new StringBuilder();
       rmnode.append(hostname);
       rmnode.append(":ResourceManager");
       String[] rmHeap = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createCircle("9", "Resource Manager Memory", rmHeap, rmnode.toString(), "%");
+      createCircle("9", "Resource Manager Memory", rmHeap, rmnode.toString(), "%", "up");
 
       // Node Managers Health
       String[] nmh = { "HadoopMetrics.yarn.ClusterMetrics.NumActiveNMs", "HadoopMetrics.yarn.ClusterMetrics.NumLostNMs" };
@@ -962,7 +963,7 @@ public class ChukwaHBaseStore {
       hbaseMaster.append(hostname);
       hbaseMaster.append(":Master");
       String[] hbm = { "HBaseMetrics.jvm.JvmMetrics.MemHeapUsedM", "HBaseMetrics.jvm.JvmMetrics.MemHeapMaxM" };
-      createCircle("15", "HBase Master Memory", hbm, hbaseMaster.toString(), "%");
+      createCircle("15", "HBase Master Memory", hbm, hbaseMaster.toString(), "%", "up");
 
       // Demo metrics
 //      String[] trialAbandonRate = { "HadoopMetrics.jvm.JvmMetrics.MemHeapUsedM", "HadoopMetrics.jvm.JvmMetrics.MemHeapMaxM" };
@@ -1200,7 +1201,7 @@ public class ChukwaHBaseStore {
       dashboard.add(widget);
 
       widget = new Widget();
-      widget.setTitle("HDFS Usage");
+      widget.setTitle("HDFS Remaining");
       widget.setSrc(new URI("/hicc/v1/circles/draw/8"));
       widget.setCol(1);
       widget.setRow(2);

http://git-wip-us.apache.org/repos/asf/chukwa/blob/aa76d992/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
index 06b2bd5..a944373 100644
--- a/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
+++ b/src/main/java/org/apache/hadoop/chukwa/hicc/bean/Chart.java
@@ -46,6 +46,7 @@ public class Chart {
   private String icon = "";
   private String bannerText = "";
   private String suffixText = "";
+  private String threshold = "";
 
   public Chart(String id) {
     this.id = id;
@@ -233,4 +234,12 @@ public class Chart {
   public String getSuffixText() {
     return this.suffixText;
   }
+
+  public void setThreshold(String direction) {
+    this.threshold = direction;
+  }
+  
+  public String getThreshold() {
+    return this.threshold;
+  }
 }

http://git-wip-us.apache.org/repos/asf/chukwa/blob/aa76d992/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 70a80c0..9462b5d 100644
--- a/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java
+++ b/src/main/java/org/apache/hadoop/chukwa/util/HBaseUtil.java
@@ -54,9 +54,9 @@ public class HBaseUtil {
     c.setTimeInMillis(time);
     byte[] day = Integer.toString(c.get(Calendar.DAY_OF_YEAR)).getBytes(Charset.forName("UTF-8"));
     byte[] pk = getHash(primaryKey);
-    byte[] key = new byte[12];
+    byte[] key = new byte[14];
     System.arraycopy(day, 0, key, 0, day.length);
-    System.arraycopy(pk, 0, key, 2, 5);
+    System.arraycopy(pk, 0, key, 2, 6);
     return key;
   }
   
@@ -66,16 +66,16 @@ public class HBaseUtil {
     byte[] day = Integer.toString(c.get(Calendar.DAY_OF_YEAR)).getBytes(Charset.forName("UTF-8"));
     byte[] pk = getHash(primaryKey);
     byte[] src = getHash(source);
-    byte[] key = new byte[12];
+    byte[] key = new byte[14];
     System.arraycopy(day, 0, key, 0, day.length);
-    System.arraycopy(pk, 0, key, 2, 5);
-    System.arraycopy(src, 0, key, 7, 5);
+    System.arraycopy(pk, 0, key, 2, 6);
+    System.arraycopy(src, 0, key, 8, 6);
     return key;
   }
   
   private static byte[] getHash(String key) {
-    byte[] hash = new byte[5];
-    System.arraycopy(md5.digest(key.getBytes(Charset.forName("UTF-8"))), 0, hash, 0, 5);
+    byte[] hash = new byte[6];
+    System.arraycopy(md5.digest(key.getBytes(Charset.forName("UTF-8"))), 0, hash, 0, 6);
     return hash;
   }
 }

http://git-wip-us.apache.org/repos/asf/chukwa/blob/aa76d992/src/main/web/hicc/WEB-INF/vm/circles.vm
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/WEB-INF/vm/circles.vm b/src/main/web/hicc/WEB-INF/vm/circles.vm
index 76d9b41..65e38ff 100644
--- a/src/main/web/hicc/WEB-INF/vm/circles.vm
+++ b/src/main/web/hicc/WEB-INF/vm/circles.vm
@@ -88,12 +88,21 @@ function render(result) {
     var fontsize = 38;
     var percent = result.series.data[0][1];
     var text = percent+"$chart.getSuffixText()";
-    var color = "#70cac8";
-    if(percent > 75) {
-      color = "#fc6e64";
-    } else if (percent > 50) {
-      color = "#f7d254";
-    }
+    #if ($chart.getThreshold()=="up")
+      var color = "#70cac8";
+      if(percent > 75) {
+        color = "#fc6e64";
+      } else if (percent > 50) {
+        color = "#f7d254";
+      }
+    #else
+      var color = "#70cac8";
+      if(percent < 25) {
+        color = "#fc6e64";
+      } else if (percent < 50) {
+        color = "#f7d254";
+      }
+    #end
     if(radius < 200) {
       width=10;
       fontsize = 12;

http://git-wip-us.apache.org/repos/asf/chukwa/blob/aa76d992/src/main/web/hicc/home/css/jquery.gridster.css
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/css/jquery.gridster.css b/src/main/web/hicc/home/css/jquery.gridster.css
index 9251929..14fee6b 100755
--- a/src/main/web/hicc/home/css/jquery.gridster.css
+++ b/src/main/web/hicc/home/css/jquery.gridster.css
@@ -177,18 +177,18 @@ body {
 }
 
 .gs-w:hover .gs-header {
-    opacity: .9;
+    opacity: .3;
     //filter: blur(5px);
 }
 
 .gs-header {
-    color: white;
+    color: #555555;
     position: absolute;
     top: 0;
     left: 0;
     width: 100%;
     height: 30px;
-    background-color: #496274;
+    background-color: #eeeeee;
     opacity: 0;
     z-index: 20;
 }

http://git-wip-us.apache.org/repos/asf/chukwa/blob/aa76d992/src/main/web/hicc/home/graph-explorer.html
----------------------------------------------------------------------
diff --git a/src/main/web/hicc/home/graph-explorer.html b/src/main/web/hicc/home/graph-explorer.html
index 03ede7c..a7c1084 100644
--- a/src/main/web/hicc/home/graph-explorer.html
+++ b/src/main/web/hicc/home/graph-explorer.html
@@ -82,8 +82,8 @@
             <div role="tabpanel" class="tab-pane" id="ring">
               <label>Threshold</label>
               <select id="threshold" class="form-control">
-                <option>Upper bound</option>
-                <option>Lower bound</option>
+                <option value="up">Upper bound</option>
+                <option value="down">Lower bound</option>
               </select>
               <label>Suffix Label</label><input type="text" id="ringSuffix" class="form-control" />
             </div>
@@ -227,6 +227,7 @@ $(function() {
       var ymin = $('#ymin').val() ;
       var ymax = $('#ymax').val();
       var yunit = $('#yunit').val();
+      var threshold = $('#threshold').val();
       var banner = $('#banner').val();
       var suffix = $('#suffix').val();
       var view = $("ul#view li.active");
@@ -239,10 +240,11 @@ $(function() {
                    'icon' : icon,
                    'bannerText' : banner, 
                    'suffixText' : suffix, 
-                   'yUnitType' : yunit, 
+                   'yUnitType' : yunit,
+                   'threshold' : threshold, 
                    'width' : 300, 
                    'height' : 200, 
-                   'series' : url 
+                   'series' : url
       };
       if(ymin!='') {
         data['min']=ymin;