You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ct...@apache.org on 2013/11/01 01:56:10 UTC

[31/54] [partial] ACCUMULO-658, ACCUMULO-656 Split server into separate modules

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/Table.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/Table.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/Table.java
new file mode 100644
index 0000000..e2578c9
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/Table.java
@@ -0,0 +1,233 @@
+/*
+ * 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.accumulo.monitor.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.accumulo.monitor.servlets.BasicServlet;
+import org.apache.accumulo.monitor.util.celltypes.CellType;
+import org.apache.accumulo.monitor.util.celltypes.StringType;
+
+public class Table {
+  private String table;
+  private String caption;
+  private String captionclass;
+  private String subcaption;
+  private ArrayList<TableColumn<?>> columns;
+  private ArrayList<TableRow> rows;
+  private boolean hasBegunAddingRows = false;
+  
+  public Table(String tableName, String caption) {
+    this(tableName, caption, null);
+  }
+  
+  public Table(String tableName, String caption, String captionClass) {
+    this.table = tableName;
+    this.caption = caption;
+    this.captionclass = captionClass;
+    this.subcaption = null;
+    this.columns = new ArrayList<TableColumn<?>>();
+    this.rows = new ArrayList<TableRow>();
+  }
+  
+  public synchronized void setSubCaption(String subcaption) {
+    this.subcaption = subcaption;
+  }
+  
+  public synchronized <T> void addColumn(TableColumn<T> column) {
+    if (hasBegunAddingRows)
+      throw new IllegalStateException("Cannot add more columns newServer rows have been added");
+    columns.add(column);
+  }
+  
+  private synchronized <T> void addColumn(String title, CellType<T> type, String legend, boolean sortable) {
+    if (type == null)
+      type = new StringType<T>();
+    type.setSortable(sortable);
+    addColumn(new TableColumn<T>(title, type, legend));
+  }
+  
+  public synchronized <T> void addUnsortableColumn(String title, CellType<T> type, String legend) {
+    addColumn(title, type, legend, false);
+  }
+  
+  public synchronized <T> void addSortableColumn(String title, CellType<T> type, String legend) {
+    addColumn(title, type, legend, true);
+  }
+  
+  public synchronized void addUnsortableColumn(String title) {
+    addUnsortableColumn(title, null, null);
+  }
+  
+  public synchronized void addSortableColumn(String title) {
+    addSortableColumn(title, null, null);
+  }
+  
+  public synchronized TableRow prepareRow() {
+    hasBegunAddingRows = true;
+    return new TableRow(columns.size());
+  }
+  
+  public synchronized void addRow(TableRow row) {
+    hasBegunAddingRows = true;
+    if (columns.size() != row.size())
+      throw new IllegalStateException("Row must be the same size as the columns");
+    rows.add(row);
+  }
+  
+  public synchronized void addRow(Object... cells) {
+    TableRow row = prepareRow();
+    if (cells.length != columns.size())
+      throw new IllegalArgumentException("Argument length not equal to the number of columns");
+    for (Object cell : cells)
+      row.add(cell);
+    addRow(row);
+  }
+  
+  public synchronized void generate(HttpServletRequest req, StringBuilder sb) {
+    String page = req.getRequestURI();
+    if (columns.isEmpty())
+      throw new IllegalStateException("No columns in table");
+    for (TableRow row : rows)
+      if (row.size() != columns.size())
+        throw new RuntimeException("Each row must have the same number of columns");
+    
+    boolean sortAscending = true;
+    Cookie c = BasicServlet.getCookie(req, "tableSort." + page + "." + table + "." + "sortAsc");
+    if (c != null && "false".equals(c.getValue()))
+      sortAscending = false;
+    
+    int sortCol = -1; // set to first sortable column by default
+    int numLegends = 0;
+    for (int i = 0; i < columns.size(); ++i) {
+      TableColumn<?> col = columns.get(i);
+      if (sortCol < 0 && col.getCellType().isSortable())
+        sortCol = i;
+      if (col.getLegend() != null && !col.getLegend().isEmpty())
+        ++numLegends;
+    }
+    
+    // only get cookie if there is a possibility that it is sortable
+    if (sortCol >= 0) {
+      c = BasicServlet.getCookie(req, "tableSort." + page + "." + table + "." + "sortCol");
+      if (c != null && c.getValue() != null) {
+        try {
+          int col = Integer.parseInt(c.getValue());
+          // only bother if specified column is sortable
+          if (!(col < 0 || sortCol >= columns.size()) && columns.get(col).getCellType().isSortable())
+            sortCol = col;
+        } catch (NumberFormatException e) {
+          // ignore improperly formatted user cookie
+        }
+      }
+    }
+    
+    boolean showLegend = false;
+    if (numLegends > 0) {
+      c = BasicServlet.getCookie(req, "tableLegend." + page + "." + table + "." + "show");
+      showLegend = c != null && Boolean.parseBoolean(c.getValue());
+    }
+    
+    sb.append("<div>\n");
+    sb.append("<a name='").append(table).append("'>&nbsp;</a>\n");
+    sb.append("<table id='").append(table).append("' class='sortable'>\n");
+    sb.append("<caption");
+    if (captionclass != null && !captionclass.isEmpty())
+      sb.append(" class='").append(captionclass).append("'");
+    sb.append(">\n");
+    if (caption != null && !caption.isEmpty())
+      sb.append("<span class='table-caption'>").append(caption).append("</span><br />\n");
+    if (subcaption != null && !subcaption.isEmpty())
+      sb.append("<span class='table-subcaption'>").append(subcaption).append("</span><br />\n");
+    
+    String redir = BasicServlet.currentPage(req);
+    if (numLegends > 0) {
+      String legendUrl = String.format("/op?action=toggleLegend&redir=%s&page=%s&table=%s&show=%s", redir, page, table, !showLegend);
+      sb.append("<a href='").append(legendUrl).append("'>").append(showLegend ? "Hide" : "Show").append("&nbsp;Legend</a>\n");
+      if (showLegend)
+        sb.append("<div class='left ").append(showLegend ? "show" : "hide").append("'><dl>\n");
+    }
+    for (int i = 0; i < columns.size(); ++i) {
+      TableColumn<?> col = columns.get(i);
+      String title = col.getTitle();
+      if (rows.size() > 1 && col.getCellType().isSortable()) {
+        String url = String.format("/op?action=sortTable&redir=%s&page=%s&table=%s&%s=%s", redir, page, table, sortCol == i ? "asc" : "col",
+            sortCol == i ? !sortAscending : i);
+        String img = "";
+        if (sortCol == i)
+          img = String.format("&nbsp;<img width='10px' height='10px' src='/web/%s.gif' alt='%s' />", sortAscending ? "up" : "down", !sortAscending ? "^" : "v");
+        col.setTitle(String.format("<a href='%s'>%s%s</a>", url, title, img));
+      }
+      String legend = col.getLegend();
+      if (showLegend && legend != null && !legend.isEmpty())
+        sb.append("<dt class='smalltext'><b>").append(title.replace("<br />", "&nbsp;")).append("</b><dd>").append(legend).append("</dd></dt>\n");
+    }
+    if (showLegend && numLegends > 0)
+      sb.append("</dl></div>\n");
+    sb.append("</caption>\n");
+    sb.append("<tr>");
+    boolean first = true;
+    for (TableColumn<?> col : columns) {
+      String cellValue = col.getTitle() == null ? "" : String.valueOf(col.getTitle()).trim();
+      sb.append("<th").append(first ? " class='firstcell'" : "").append(">").append(cellValue.isEmpty() ? "-" : cellValue).append("</th>");
+      first = false;
+    }
+    sb.append("</tr>\n");
+    // don't sort if no columns are sortable or if there aren't enough rows
+    if (rows.size() > 1 && sortCol > -1) {
+      Collections.sort(rows, TableRow.getComparator(sortCol, columns.get(sortCol).getCellType()));
+      if (!sortAscending)
+        Collections.reverse(rows);
+    }
+    boolean highlight = true;
+    for (TableRow row : rows) {
+      for (int i = 0; i < row.size(); ++i) {
+        try {
+          row.set(i, columns.get(i).getCellType().format(row.get(i)));
+        } catch (Exception ex) {
+          throw new RuntimeException("Unable to process column " + i, ex);
+        }
+      }
+      row(sb, highlight, columns, row);
+      highlight = !highlight;
+    }
+    if (rows.isEmpty())
+      sb.append("<tr><td class='center' colspan='").append(columns.size()).append("'><i>Empty</i></td></tr>\n");
+    sb.append("</table>\n</div>\n\n");
+  }
+  
+  private static void row(StringBuilder sb, boolean highlight, ArrayList<TableColumn<?>> columns, TableRow row) {
+    sb.append(highlight ? "<tr class='highlight'>" : "<tr>");
+    boolean first = true;
+    for (int i = 0; i < row.size(); ++i) {
+      String cellValue = String.valueOf(row.get(i)).trim();
+      if (cellValue.isEmpty() || cellValue.equals(String.valueOf((Object) null)))
+        cellValue = "-";
+      sb.append("<td class='").append(first ? "firstcell" : "");
+      if (columns.get(i).getCellType().alignment() != null)
+        sb.append(first ? " " : "").append(columns.get(i).getCellType().alignment());
+      sb.append("'>").append(cellValue).append("</td>");
+      first = false;
+    }
+    sb.append("</tr>\n");
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableColumn.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableColumn.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableColumn.java
new file mode 100644
index 0000000..a7330ac
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableColumn.java
@@ -0,0 +1,48 @@
+/*
+ * 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.accumulo.monitor.util;
+
+import org.apache.accumulo.monitor.util.celltypes.CellType;
+import org.apache.accumulo.monitor.util.celltypes.StringType;
+
+public class TableColumn<T> {
+  private String title;
+  private CellType<T> type;
+  private String legend;
+  
+  public TableColumn(String title, CellType<T> type, String legend) {
+    this.title = title;
+    this.type = type != null ? type : new StringType<T>();
+    this.legend = legend;
+  }
+  
+  public void setTitle(String title) {
+    this.title = title;
+  }
+  
+  public String getTitle() {
+    return title;
+  }
+  
+  public String getLegend() {
+    return legend;
+  }
+  
+  public CellType<T> getCellType() {
+    return type;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableRow.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableRow.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableRow.java
new file mode 100644
index 0000000..5de0863
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/TableRow.java
@@ -0,0 +1,68 @@
+/*
+ * 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.accumulo.monitor.util;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+
+public class TableRow {
+  private int size;
+  private ArrayList<Object> row;
+  
+  TableRow(int size) {
+    this.size = size;
+    this.row = new ArrayList<Object>(size);
+  }
+  
+  public boolean add(Object obj) {
+    if (row.size() == size)
+      throw new IllegalStateException("Row is full.");
+    return row.add(obj);
+  }
+  
+  Object get(int index) {
+    return row.get(index);
+  }
+  
+  int size() {
+    return row.size();
+  }
+  
+  Object set(int i, Object value) {
+    return row.set(i, value);
+  }
+  
+  public static <T> Comparator<TableRow> getComparator(int index, Comparator<T> comp) {
+    return new TableRowComparator<T>(index, comp);
+  }
+  
+  private static class TableRowComparator<T> implements Comparator<TableRow> {
+    private int index;
+    private Comparator<T> comp;
+    
+    public TableRowComparator(int index, Comparator<T> comp) {
+      this.index = index;
+      this.comp = comp;
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public int compare(TableRow o1, TableRow o2) {
+      return comp.compare((T) o1.get(index), (T) o2.get(index));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CellType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CellType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CellType.java
new file mode 100644
index 0000000..23071a8
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CellType.java
@@ -0,0 +1,35 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import java.util.Comparator;
+
+public abstract class CellType<T> implements Comparator<T> {
+  private boolean sortable = true;
+  
+  abstract public String alignment();
+  
+  abstract public String format(Object obj);
+  
+  public final void setSortable(boolean sortable) {
+    this.sortable = sortable;
+  }
+  
+  public final boolean isSortable() {
+    return sortable;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CompactionsType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CompactionsType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CompactionsType.java
new file mode 100644
index 0000000..704aa42
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/CompactionsType.java
@@ -0,0 +1,72 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import org.apache.accumulo.core.master.thrift.Compacting;
+import org.apache.accumulo.core.master.thrift.TableInfo;
+
+public class CompactionsType extends CellType<TableInfo> {
+  
+  private String fieldName;
+  
+  public CompactionsType(String which) {
+    this.fieldName = which;
+  }
+  
+  @Override
+  public String format(Object obj) {
+    if (obj == null)
+      return "-";
+    TableInfo summary = (TableInfo) obj;
+    Compacting c = summary.majors;
+    if (fieldName.equals("minor"))
+      c = summary.minors;
+    else if (fieldName.equals("scans"))
+      c = summary.scans;
+    if (c == null)
+      c = new Compacting();
+    return String.format("%s&nbsp;(%,d)", NumberType.commas(c.running, c.queued == 0 ? 0 : 1, summary.onlineTablets), c.queued);
+  }
+  
+  @Override
+  public int compare(TableInfo o1, TableInfo o2) {
+    if (o1 == null)
+      return -1;
+    if (o2 == null)
+      return 1;
+    Compacting c1 = o1.majors;
+    Compacting c2 = o2.majors;
+    if (fieldName.equals("minor")) {
+      c1 = o1.minors;
+      c2 = o2.minors;
+    } else if (fieldName.equals("scans")) {
+      c1 = o1.scans;
+      c2 = o2.scans;
+    }
+    if (c1 == null)
+      return -1;
+    if (c2 == null)
+      return 1;
+    return c1.running + c1.queued - c2.running - c2.queued;
+  }
+  
+  @Override
+  public String alignment() {
+    return "right";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DateTimeType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DateTimeType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DateTimeType.java
new file mode 100644
index 0000000..8ff3b60
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DateTimeType.java
@@ -0,0 +1,66 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class DateTimeType extends CellType<Long> {
+  private SimpleDateFormat simple;
+  private int dateFormat;
+  private int timeFormat;
+  
+  public DateTimeType(int dateFormat, int timeFormat) {
+    this.dateFormat = dateFormat;
+    this.timeFormat = timeFormat;
+    this.simple = null;
+  }
+  
+  public DateTimeType(SimpleDateFormat fmt) {
+    simple = fmt;
+  }
+  
+  @Override
+  public String format(Object obj) {
+    if (obj == null)
+      return "-";
+    Long millis = (Long) obj;
+    if (millis == 0)
+      return "-";
+    if (simple != null)
+      return simple.format(new Date(millis)).replace(" ", "&nbsp;");
+    return DateFormat.getDateTimeInstance(dateFormat, timeFormat, Locale.getDefault()).format(new Date(millis)).replace(" ", "&nbsp;");
+  }
+  
+  @Override
+  public int compare(Long o1, Long o2) {
+    if (o1 == null && o2 == null)
+      return 0;
+    else if (o1 == null)
+      return -1;
+    else
+      return o1.compareTo(o2);
+  }
+  
+  @Override
+  public String alignment() {
+    return "right";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DurationType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DurationType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DurationType.java
new file mode 100644
index 0000000..7f3472e
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/DurationType.java
@@ -0,0 +1,51 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import org.apache.accumulo.core.util.Duration;
+
+public class DurationType extends NumberType<Long> {
+  private Long errMin;
+  private Long errMax;
+  
+  public DurationType() {
+    this(null, null);
+  }
+  
+  public DurationType(Long errMin, Long errMax) {
+    this.errMin = errMin;
+    this.errMax = errMax;
+  }
+  
+  @Override
+  public String format(Object obj) {
+    if (obj == null)
+      return "-";
+    Long millis = (Long) obj;
+    if (errMin != null && errMax != null)
+      return seconds(millis, errMin, errMax);
+    return Duration.format(millis);
+  }
+  
+  private static String seconds(long secs, long errMin, long errMax) {
+    String numbers = Duration.format(secs);
+    if (secs < errMin || secs > errMax)
+      return "<span class='error'>" + numbers + "</span>";
+    return numbers;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/NumberType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/NumberType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/NumberType.java
new file mode 100644
index 0000000..d311603
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/NumberType.java
@@ -0,0 +1,118 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import static org.apache.accumulo.core.util.NumUtil.bigNumberForQuantity;
+
+public class NumberType<T extends Number> extends CellType<T> {
+  
+  private T warnMin, warnMax, errMin, errMax;
+  
+  public NumberType(T warnMin, T warnMax, T errMin, T errMax) {
+    this.warnMin = warnMin;
+    this.warnMax = warnMax;
+    this.errMin = errMin;
+    this.errMax = errMax;
+  }
+  
+  public NumberType(T errMin, T errMax) {
+    this(null, null, errMin, errMax);
+  }
+  
+  public NumberType() {
+    this(null, null);
+  }
+  
+  @SuppressWarnings("unchecked")
+  @Override
+  public String format(Object obj) {
+    T number = (T) obj;
+    String s = "-";
+    if (number instanceof Double || number instanceof Float) {
+      if (warnMin != null && warnMax != null && errMin != null && errMax != null)
+        s = commas(number.doubleValue(), warnMin.doubleValue(), warnMax.doubleValue(), errMin.doubleValue(), errMax.doubleValue());
+      else if (errMin != null && errMax != null)
+        s = commas(number.doubleValue(), errMin.doubleValue(), errMax.doubleValue());
+      else
+        s = commas(number.doubleValue());
+    } else if (number instanceof Long || number instanceof Integer || number instanceof Short || number instanceof Byte) {
+      if (warnMin != null && warnMax != null && errMin != null && errMax != null)
+        s = commas(number.longValue(), warnMin.longValue(), warnMax.longValue(), errMin.longValue(), errMax.longValue());
+      else if (errMin != null && errMax != null)
+        s = commas(number.longValue(), errMin.longValue(), errMax.longValue());
+      else
+        s = commas(number.longValue());
+    } else {
+      if (number != null)
+        s = String.valueOf(number);
+    }
+    return s;
+  }
+  
+  @Override
+  public int compare(T o1, T o2) {
+    if (o1 == null && o2 == null)
+      return 0;
+    else if (o1 == null)
+      return -1;
+    else if (o2 == null)
+      return 1;
+    else
+      return Double.valueOf(o1.doubleValue()).compareTo(o2.doubleValue());
+  }
+  
+  public static String commas(long i) {
+    return bigNumberForQuantity(i);
+  }
+  
+  public static String commas(long i, long errMin, long errMax) {
+    if (i < errMin || i > errMax)
+      return String.format("<span class='error'>%s</span>", bigNumberForQuantity(i));
+    return bigNumberForQuantity(i);
+  }
+  
+  public static String commas(double i) {
+    return bigNumberForQuantity((long) i);
+  }
+  
+  public static String commas(double d, double errMin, double errMax) {
+    if (d < errMin || d > errMax)
+      return String.format("<span class='error'>%s</span>", bigNumberForQuantity(d));
+    return bigNumberForQuantity(d);
+  }
+  
+  public static String commas(long i, long warnMin, long warnMax, long errMin, long errMax) {
+    if (i < errMin || i > errMax)
+      return String.format("<span class='error'>%s</span>", bigNumberForQuantity(i));
+    if (i < warnMin || i > warnMax)
+      return String.format("<span class='warning'>%s</span>", bigNumberForQuantity(i));
+    return bigNumberForQuantity(i);
+  }
+  
+  public static String commas(double d, double warnMin, double warnMax, double errMin, double errMax) {
+    if (d < errMin || d > errMax)
+      return String.format("<span class='error'>%s</span>", bigNumberForQuantity(d));
+    if (d < warnMin || d > warnMax)
+      return String.format("<span class='warning'>%s</span>", bigNumberForQuantity(d));
+    return bigNumberForQuantity(d);
+  }
+  
+  @Override
+  public String alignment() {
+    return "right";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/PercentageType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/PercentageType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/PercentageType.java
new file mode 100644
index 0000000..2efc65f
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/PercentageType.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+public class PercentageType extends CellType<Double> {
+  
+  @Override
+  public int compare(Double o1, Double o2) {
+    return o1.compareTo(o2);
+  }
+  
+  @Override
+  public String alignment() {
+    return "right";
+  }
+  
+  @Override
+  public String format(Object obj) {
+    if (obj == null)
+      return "-";
+    
+    return String.format("%.0f%s", 100 * (Double) obj, "%");
+    
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/ProgressChartType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/ProgressChartType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/ProgressChartType.java
new file mode 100644
index 0000000..20db871
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/ProgressChartType.java
@@ -0,0 +1,59 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+public class ProgressChartType extends NumberType<Double> {
+  
+  private double max;
+  
+  public ProgressChartType() {
+    this(1.0);
+  }
+  
+  public ProgressChartType(Double total) {
+    max = total == null ? 1.0 : total;
+  }
+  
+  @Override
+  public String format(Object obj) {
+    if (obj == null)
+      return "-";
+    Double num = (Double) obj;
+    return getChart(num, max);
+  }
+  
+  public static String getChart(double num, double total) {
+    StringBuilder result = new StringBuilder();
+    double percent = 0;
+    if (total != 0)
+      percent = (num / total) * 100;
+    
+    int width = 0;
+    if (percent < 1)
+      width = 0;
+    else if (percent > 100)
+      width = 100;
+    else
+      width = (int) percent;
+    
+    result.append("<div class='progress-chart'>");
+    result.append("<div style='width: ").append(width).append("%;'></div>");
+    result.append("</div>&nbsp;");
+    result.append((percent < 1 && percent > 0) ? "&lt;1" : (int) percent).append("%");
+    return result.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/StringType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/StringType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/StringType.java
new file mode 100644
index 0000000..8807423
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/StringType.java
@@ -0,0 +1,40 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+public class StringType<T> extends CellType<T> {
+  @Override
+  public String format(Object obj) {
+    return obj == null ? "-" : obj.toString();
+  }
+  
+  @Override
+  public int compare(T o1, T o2) {
+    if (o1 == null && o2 == null)
+      return 0;
+    else if (o1 == null)
+      return -1;
+    else if (o2 == null)
+      return 1;
+    return o1.toString().compareTo(o2.toString());
+  }
+  
+  @Override
+  public String alignment() {
+    return "left";
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TServerLinkType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TServerLinkType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TServerLinkType.java
new file mode 100644
index 0000000..26d623a
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TServerLinkType.java
@@ -0,0 +1,51 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import org.apache.accumulo.core.master.thrift.TabletServerStatus;
+
+public class TServerLinkType extends CellType<TabletServerStatus> {
+  
+  @Override
+  public String format(Object obj) {
+    if (obj == null)
+      return "-";
+    TabletServerStatus status = (TabletServerStatus) obj;
+    return String.format("<a href='/tservers?s=%s'>%s</a>", status.name, displayName(status));
+  }
+  
+  public static String displayName(TabletServerStatus status) {
+    return displayName(status == null ? null : status.name);
+  }
+  
+  public static String displayName(String address) {
+    if (address == null)
+      return "--Unknown--";
+    return address;
+  }
+  
+  @Override
+  public int compare(TabletServerStatus o1, TabletServerStatus o2) {
+    return displayName(o1).compareTo(displayName(o2));
+  }
+  
+  @Override
+  public String alignment() {
+    return "left";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableLinkType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableLinkType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableLinkType.java
new file mode 100644
index 0000000..03bd06b
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableLinkType.java
@@ -0,0 +1,56 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import java.util.Map;
+
+import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.server.client.HdfsZooInstance;
+
+public class TableLinkType extends CellType<String> {
+  
+  private Map<String,String> tidToNameMap;
+  
+  public TableLinkType() {
+    tidToNameMap = Tables.getIdToNameMap(HdfsZooInstance.getInstance());
+  }
+  
+  @Override
+  public String format(Object obj) {
+    if (obj == null)
+      return "-";
+    String tableId = (String) obj;
+    return String.format("<a href='/tables?t=%s'>%s</a>", tableId, displayName(tableId));
+  }
+  
+  private String displayName(String tableId) {
+    if (tableId == null)
+      return "-";
+    return Tables.getPrintableTableNameFromId(tidToNameMap, tableId);
+  }
+  
+  @Override
+  public int compare(String o1, String o2) {
+    return displayName(o1).compareTo(displayName(o2));
+  }
+  
+  @Override
+  public String alignment() {
+    return "left";
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableStateType.java
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableStateType.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableStateType.java
new file mode 100644
index 0000000..22fb498
--- /dev/null
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/celltypes/TableStateType.java
@@ -0,0 +1,57 @@
+/*
+ * 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.accumulo.monitor.util.celltypes;
+
+import org.apache.accumulo.core.master.state.tables.TableState;
+
+public class TableStateType extends CellType<TableState> {
+  
+  @Override
+  public String alignment() {
+    return "center";
+  }
+  
+  @Override
+  public String format(Object obj) {
+    TableState state = obj == null ? TableState.UNKNOWN : (TableState) obj;
+    String style = null;
+    switch (state) {
+      case ONLINE:
+      case OFFLINE:
+        break;
+      case NEW:
+      case DELETING:
+        style = "warning";
+        break;
+      case UNKNOWN:
+      default:
+        style = "error";
+    }
+    style = style != null ? " class='" + style + "'" : "";
+    return String.format("<span%s>%s</span>", style, state);
+  }
+  
+  @Override
+  public int compare(TableState o1, TableState o2) {
+    if (o1 == null && o2 == null)
+      return 0;
+    else if (o1 == null)
+      return -1;
+    return o1.compareTo(o2);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/administration.html
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/administration.html b/server/monitor/src/main/resources/docs/administration.html
new file mode 100644
index 0000000..96f4a8b
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/administration.html
@@ -0,0 +1,148 @@
+<!--
+  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.
+-->
+<html>
+<head>
+<title>Accumulo Administration</title>
+<link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
+</head>
+<body>
+
+<h1>Apache Accumulo Documentation : Administration</h1>
+
+<h3>Starting accumulo for the first time</h3>
+
+<p>For the most part, accumulo is ready to go out of the box. To start it, first you must distribute and install
+the accumulo software to each machine in the cloud that you wish to run on. The software should be installed
+in the same directory on each machine and configured identically (or at least similarly... see the configuration
+sections for more details). Select one machine to be your bootstrap machine, the one that you will start accumulo
+with. Note that you must have passphrase-less ssh access to each machine from your bootstrap machine. On this machine,
+create a conf/masters and conf/slaves file. In the masters file, type the hostname of the machine you wish to run the master on (probably localhost).
+In the slaves file, type the hostnames, separated by newlines of each machine you wish to participate in accumulo as a tablet server. If you neglect
+to create these files, the startup scripts will assume you are trying to run on localhost only, and will instantiate a single-node instance only.
+It is probably a good idea to back up these files, or distribute them to the other nodes as well, so that you can easily boot up accumulo
+from another machine, if necessary. You can also make create a <code>conf/accumulo-env.sh</code> file if you want to configure any custom environment variables.
+
+<p>Once properly configured, you can initialize or prepare an instance of accumulo by running: <code>bin/accumulo&nbsp;init</code><br />
+Follow the prompts and you are ready to go. This step only prepares accumulo to run, it does not start up accumulo.
+
+<h3>Starting accumulo</h3>
+
+<p>Once you have configured accumulo to your liking, and distributed the appropriate configuration to each machine, you can start accumulo with
+bin/start-all.sh. If at any time, you wish to bring accumulo servers online after one or more have been shutdown, you can run bin/start-all.sh again.
+This step will only start services that are not already running. Be aware that if you run this command on more than one machine, you may unintentionally
+start an extra copy of the garbage collector service and the monitoring service, since each of these will run on the server on which you run this script.
+
+<h3>Stopping accumulo</h3>
+
+<p>Similar to the start-all.sh script, we provide a bin/stop-all.sh script to shut down accumulo. This will prompt for the root password so that it can
+ask the master to shut down the tablet servers gracefully. If the tablet servers do not respond, or the master takes too long, you can force a shutdown by hitting Ctrl-C
+at the password prompt, and waiting 15 seconds for the script to force a shutdown. Normally, once the shutdown happens gracefully, unresponsive tablet servers are
+forcibly shut down after 5 seconds.
+
+
+<h3>Configuration</h3>
+<p>Accumulo configuration information is stored in a xml file and ZooKeeper.  System wide
+configuration information is stored in accumulo-site.xml. In order for accumulo to
+find this file its directory must be on the classpath.  Accumulo will log a warning if it can not find 
+it, and will use built-in default values. The accumulo scripts try to put the config directory on the classpath.  
+
+<p>Starting with version 1.0, per-table configuration was
+introduced. This information is stored in ZooKeeper. This information
+can be manipulated using the config command in the accumulo
+shell. ZooKeeper will notify all tablet servers when config properties
+are modified. This makes it possible to change major compaction
+settings, for example, for a table while accumulo is running.
+
+<p>Per-table configuration settings override system settings. 
+
+<p>See the possible configuration options and their default values <a href='config.html'>here</a>
+
+<h3>Managing system resources</h3>
+
+<p>It is very important how disk and memory usage are allocated across the cluster and how servers processes are allocated across the cluster. 
+
+<ul>
+ <li> On larger clusters, run the namenode, secondary namenode, jobtracker, accumulo master, and zookeepers on dedicated nodes.  On a smaller cluster you may want to run all master processes on one node.  When doing this ensure that the max total memory that could be used by all master processes does not exceed system memory.  Swapping on your single master node would not be good.
+ <li> Accumulo 1.2 and earlier rely on zookeeper but do not use it heavily.  On a large cluster setting up 3 or 5 zookeepers should be plenty.  Since there is no performance gain when running more zookeepers, fault tolerance is the only benefit.
+ <li> On slave nodes ensure the memory used by all slave processes is less than system memory.  For example the following slave node config could use up to 38G of RAM : tablet server 3G, logger 1G, data node 2G, up to 10 mappers each using 2G, and up 6 reducers each using 2G.  If the slave nodes only have 32G, then using 38G will result in swapping which could cause tablet server to lose their lock in zookeeper and die.  Even if swapping does not cause tablet servers to die, it will kill performance.
+ <li>Accumulo and map reduce will work with less memory, but it has an impact.  Accumulo will minor compact more frequently when it has less map memory, resulting in more major compactions.  The minor and major compactions both use CPU and HDFS I/O.   The same goes for map reduce, the less memory you give it, the more it has to sort and spill.  Try to minimize spilling and compactions as much as possible without causing swapping.
+ <li>Accumulo writes data to disk before it sorts it in memory.  This allows data that was in memory when a tablet server crashes to be recovered.  Each slave node needs a local directory to write this data to.  Ensure the file system holding this directory has at least 100G free on all nodes.  Also, if this directory is in a filesystem used by map reduce or hdfs they may effect each others performance.
+</ul>
+
+<p>There are a few settings that determine how much memory accumulo tablet
+servers use.  In accumulo-env.sh there is a setting called
+ACCUMULO_TSERVER_OPTS.  By default this is set to something like "-Xmx512m
+-Xms512m".  These are Java jvm options asking Java to use 512 megabytes of
+memory.  By default accumulo stores data written to it outside of the Java
+memory space in order to avoid pauses caused by the Java garbage collector.  The
+amount of memory it uses for this data is determined by the accumulo setting
+"tserver.memory.maps.max".  Since this memory is outside of the Java managed
+memory, the process can grow larger than the -Xmx setting.  So if -Xmx is set
+to 512M and tserver.memory.maps.max is set to 1G, a tablet server process can
+be expected to use 1.5G.  If tserver.memory.maps.native.enabled is set to
+false, then accumulo will only use memory managed by Java and the process will
+not use more than what -Xmx is set to.  In this case the
+tserver.memory.maps.max setting should be 75% of the -Xmx setting. 
+
+<h3>Swappiness</h3>
+
+<p>The linux kernel will swap out memory of running programs to increase
+the size of the disk buffers.  This tendency to swap out is controlled by
+a kernel setting called "swappiness."  This behavior does not work well for
+large java servers.  When a java process runs a garbage collection, it touches
+lots of pages forcing all swapped out pages back into memory.  It is suggested
+that swappiness be set to zero.
+
+<pre>
+ # sysctl -w vm.swappiness=0
+ # echo "vm.swappiness = 0" &gt;&gt; /etc/sysctl.conf
+</pre>
+
+<h3>Hadoop timeouts</h3>
+
+<p>In order to detect failed datanodes, use shorter timeouts.  Add the following to your
+hdfs-site.xml file:
+
+<pre>
+
+  &lt;property&gt;
+    &lt;name&gt;dfs.socket.timeout&lt;/name&gt;
+    &lt;value&gt;3000&lt;/value&gt;
+  &lt;/property&gt;
+
+  &lt;property&gt;
+    &lt;name&gt;dfs.socket.write.timeout&lt;/name&gt;
+    &lt;value&gt;5000&lt;/value&gt;
+  &lt;/property&gt;
+
+  &lt;property&gt;
+    &lt;name&gt;ipc.client.connect.timeout&lt;/name&gt;
+    &lt;value&gt;1000&lt;/value&gt;
+  &lt;/property&gt;
+
+  &lt;property&gt;
+    &lt;name&gt;ipc.clident.connect.max.retries.on.timeouts&lt;/name&gt;
+    &lt;value&gt;2&lt;/value&gt;
+  &lt;/property&gt;
+
+
+
+</pre>
+
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/bulkIngest.html
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/bulkIngest.html b/server/monitor/src/main/resources/docs/bulkIngest.html
new file mode 100644
index 0000000..0c0ce70
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/bulkIngest.html
@@ -0,0 +1,114 @@
+<!--
+  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.
+-->
+<html>
+<head>
+<title>Accumulo Bulk Ingest</title>
+<link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
+</head>
+<body>
+
+<h1>Apache Accumulo Documentation : Bulk Ingest</h2>
+
+<p>Accumulo supports the ability to import sorted files produced by an
+external process into an online table.  Often, it is much faster to churn
+through large amounts of data using map/reduce to produce the these files. 
+The new files can be incorporated into Accumulo using bulk ingest.
+
+<ul>
+<li>Construct an <code>org.apache.accumulo.core.client.Connector</code> instance</li>
+<li>Call <code>connector.tableOperations().getSplits()</code></li>
+<li>Run a map/reduce job using <a href='apidocs/org/apache/accumulo/core/client/mapreduce/lib/partition/RangePartitioner.html'>RangePartitioner</a> 
+with splits from the previous step</li>
+<li>Call <code>connector.tableOperations().importDirectory()</code> passing the output directory of the MapReduce job</li>
+</ul> 
+
+<p>Files can also be imported using the "importdirectory" shell command.
+
+<p>A complete example is available in <a href='examples/README.bulkIngest'>README.bulkIngest</a>
+
+<p>Importing data using whole files of sorted data can be very efficient, but it differs
+from live ingest in the following ways:
+<ul>
+ <li>Table constraints are not applied against they data in the file.
+ <li>Adding new files to tables are likely to trigger major compactions.
+ <li>The timestamp in the file could contain strange values.  Accumulo can be asked to use the ingest timestamp for all values if this is a concern.
+ <li>It is possible to create invalid visibility values (for example "&|").  This will cause errors when the data is accessed.
+ <li>Bulk imports do not effect the entry counts in the monitor page until the files are compacted.
+</ul>
+
+<h2>Best Practices</h2>
+
+<p>Consider two approaches to creating ingest files using map/reduce.
+
+<ol>
+ <li>A large file containing the Key/Value pairs for only a single tablet.
+ <li>A set of small files containing Key/Value pairs for every tablet.
+<ol>
+
+<p>In the first case, adding the file requires telling a single tablet server about a single file.  Even if the file
+is 20G in size, it is one call to the tablet server.  The tablet server makes one extra file entry in the
+!METADATA table, and the data is now part of the tablet.
+
+<p>In the second case, an request must be made for each tablet for each file to be added.  If there
+100 files and 100 tablets, this will be 10K requests, and the number of files needed to be opened
+for scans on these tablets will be very large.  Major compactions will most likely start which will eventually 
+fix the problem, but a lot more work needs to be done by accumulo to read these files.
+
+<p>Getting good, fast, bulk import performance depends on creating files like the first, and avoiding files like
+the second.
+
+<p>For this reason, a RangePartitioner should be used to create files when
+writing with the AccumuloFileOutputFormat.
+
+<p>Hash partition is not recommended because it will put keys in random
+groups, exactly like our bad approach.
+
+<P>Any set of cut points for range partitioning can be used in a map
+reduce job, but using Accumulo's current splits is probably the most
+optimal thing to do.  However in some cases there may be too many
+splits.  For example if there are 2000 splits, you would need to run
+2001 reducers.  To overcome this problem use the
+<code>connector.tableOperations.getSplits(&lt;table name&gt;,&lt;max
+splits&gt;)</code> method.  This method will not return more than
+<code> &lt;max splits&gt; </code> splits, but the splits it returns
+will optimally partition the data for Accumulo.
+  
+<p>Remember that Accumulo never splits rows across tablets.
+Therefore the range partitioner only considers rows when partitioning.
+
+<p>When bulk importing many files into a new table, it might be good to pre-split the table to bring
+additional resources to accepting the data.  For example, if you know your data is indexed based on the
+date, pre-creating splits for each day will allow files to fall into natural splits.  Having more tablets
+accept the new data means that more resources can be used to import the data right away.
+
+<p>An alternative to bulk ingest is to have a map/reduce job use
+<code>AccumuloOutputFormat</code>, which can support billions of inserts per
+hour, depending on the size of your cluster. This is sufficient for
+most users, but bulk ingest remains the fastest way to incorporate
+data into Accumulo.  In addition, bulk ingest has one advantage over
+AccumuloOutputFormat: there is no duplicate data insertion.  When one uses
+map/reduce to output data to accumulo, restarted jobs may re-enter
+data from previous failed attempts. Generally, this only matters when
+there are aggregators. With bulk ingest, reducers are writing to new
+map files, so it does not matter. If a reduce fails, you create a new
+map file.  When all reducers finish, you bulk ingest the map files
+into Accumulo.  The disadvantage to bulk ingest over <code>AccumuloOutputFormat</code> is 
+greater latency: the entire map/reduce job must complete
+before any data is available.
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/combiners.html
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/combiners.html b/server/monitor/src/main/resources/docs/combiners.html
new file mode 100644
index 0000000..cf18e05
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/combiners.html
@@ -0,0 +1,85 @@
+<!--
+  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.
+-->
+<html>
+<head>
+<title>Accumulo Combiners</title>
+<link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
+</head>
+<body>
+
+<h1>Apache Accumulo Documentation : Combiners</h1>
+
+<p>Accumulo supports on the fly lazy aggregation of data using Combiners.  Aggregation is done at compaction and scan time.  No lookup is done at insert time, which` greatly speeds up ingest. 
+
+<p>Combiners are easy to use.  You use the setiters command to configure a combiner for a table.  Allowing a Combiner to apply to a whole column family is an interesting twist that gives the user great flexibility.  The example below demonstrates this flexibility.  
+
+<p><pre>
+
+Shell - Apache Accumulo Interactive Shell
+- version: 1.5.0
+- instance id: 863fc0d1-3623-4b6c-8c23-7d4fdb1c8a49
+- 
+- type 'help' for a list of available commands
+-
+user@instance&gt; createtable perDayCounts
+user@instance perDayCounts&gt; setiter -t perDayCounts -p 10 -scan -minc -majc -n daycount -class org.apache.accumulo.core.iterators.user.SummingCombiner
+TypedValueCombiner can interpret Values as a variety of number encodings (VLong, Long, or String) before combining
+----------&gt; set SummingCombiner parameter columns, &lt;col fam&gt;[:&lt;col qual&gt;]{,&lt;col fam&gt;[:&lt;col qual&gt;]} escape non aplhanum chars using %&lt;hex&gt;.: day
+----------&gt; set SummingCombiner parameter type, &lt;VARNUM|LONG|STRING&gt;: STRING
+user@instance perDayCounts&gt; insert foo day 20080101 1
+user@instance perDayCounts&gt; insert foo day 20080101 1
+user@instance perDayCounts&gt; insert foo day 20080103 1
+user@instance perDayCounts&gt; insert bar day 20080101 1
+user@instance perDayCounts&gt; insert bar day 20080101 1
+user@instance perDayCounts&gt; scan
+bar day:20080101 []    2
+foo day:20080101 []    2
+foo day:20080103 []    1
+</pre>
+
+
+<p>Implementing a new Combiner is a snap.  Simply write some Java code that extends <a href='apidocs/org/apache/accumulo/core/iterators/Combiner.html'>org.apache.accumulo.core.iterators.Combiner</a>. A good place to look for examples is the <a href='apidocs/org/apache/accumulo/core/iterators/user/package-summary.html'>org.apache.accumulo.core.iterators.user</a> package.  Also look at the example StatsCombiner.     
+
+<p>To deploy a new aggregator, jar it up and put the jar in accumulo/lib/ext.  To see an example look at <a href='examples/README.combiner'>README.combiner</a>
+
+<p>If you would like to see what iterators a table has you can use the config command like in the following example.
+
+<p><pre>
+user@instance perDayCounts&gt; config -t perDayCounts -f iterator
+---------+---------------------------------------------+-----------------------------------------------------------
+SCOPE    | NAME                                        | VALUE
+---------+---------------------------------------------+-----------------------------------------------------------
+table    | table.iterator.majc.daycount .............. | 10,org.apache.accumulo.core.iterators.user.SummingCombiner
+table    | table.iterator.majc.daycount.opt.columns .. | day
+table    | table.iterator.majc.daycount.opt.type ..... | STRING
+table    | table.iterator.majc.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator
+table    | table.iterator.majc.vers.opt.maxVersions .. | 1
+table    | table.iterator.minc.daycount .............. | 10,org.apache.accumulo.core.iterators.user.SummingCombiner
+table    | table.iterator.minc.daycount.opt.columns .. | day
+table    | table.iterator.minc.daycount.opt.type ..... | STRING
+table    | table.iterator.minc.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator
+table    | table.iterator.minc.vers.opt.maxVersions .. | 1
+table    | table.iterator.scan.daycount .............. | 10,org.apache.accumulo.core.iterators.user.SummingCombiner
+table    | table.iterator.scan.daycount.opt.columns .. | day
+table    | table.iterator.scan.daycount.opt.type ..... | STRING
+table    | table.iterator.scan.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator
+table    | table.iterator.scan.vers.opt.maxVersions .. | 1
+---------+---------------------------------------------+-----------------------------------------------------------
+</pre>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/constraints.html
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/constraints.html b/server/monitor/src/main/resources/docs/constraints.html
new file mode 100644
index 0000000..b227ed7
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/constraints.html
@@ -0,0 +1,49 @@
+<!--
+  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.
+-->
+<html>
+<head>
+<title>Accumulo Constraints</title>
+<link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
+</head>
+<body>
+
+<h1>Apache Accumulo Documentation : Constraints</h1>
+
+Accumulo supports constraints.  Constraints are applied to mutations at ingest time.  
+
+<p>Implementing a new constraint is a snap.  Simply write some Java code that implements <a href='apidocs/org/apache/accumulo/core/constraints/Constraint.html'>org.apache.accumulo.core.constraints.Constraint</a>.     
+
+<p>To deploy a new constraint, jar it up and put the jar in accumulo/lib/ext.
+
+<p>After creating a constraint, set a table specific property to use it.  The following example adds two constraints to table foo. In the example com.test.ExampleConstraint and com.test.AnotherConstraint are class names.
+
+<p><pre>
+user@instance:9999 perDayCounts&gt; createtable foo
+user@instance:9999 foo&gt; config -t foo -s table.constraint.1=com.test.ExampleConstraint
+user@instance:9999 foo&gt; config -t foo -s table.constraint.2=com.test.AnotherConstraint
+user@instance:9999 foo&gt; config -t foo -f constraint
+---------+------------------------------------------+-----------------------------------------
+SCOPE    | NAME                                     | VALUE
+---------+------------------------------------------+-----------------------------------------
+table    | table.constraint.1...................... | com.test.ExampleConstraint
+table    | table.constraint.2...................... | com.test.AnotherConstraint
+---------+------------------------------------------+-----------------------------------------
+user@instance:9999 foo&gt; 
+</pre>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/distributedTracing.html
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/distributedTracing.html b/server/monitor/src/main/resources/docs/distributedTracing.html
new file mode 100644
index 0000000..5d363f3
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/distributedTracing.html
@@ -0,0 +1,99 @@
+<!--
+  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.
+-->
+<html>
+<head>
+<title>Accumulo Distributed Tracing</title>
+<link rel='stylesheet' type='text/css' href='documentation.css' media='screen'/>
+</head>
+<body>
+
+<h1>Apache Accumulo Documentation : Distributed Tracing</h1>
+
+<p>It can be difficult to determine why some operations are taking longer than expected.  For example, you may be looking up items with 
+very low latency, but sometimes the lookups take much longer.  Determining the cause of the delay is difficult because the system is 
+distributed, and the typical lookup is fast.</p>
+
+<p>To provide insight into what accumulo is doing during your scan, you can turn on tracing before you do your operation:</p>
+
+<pre>
+   DistributedTrace.enable(instance, zooReader, hostname, "myApplication");
+   Trace scanTrace = Trace.on("client:scan");
+   BatchScanner scanner = conn.createBatchScanner(...);
+   // Configure your scanner
+   for (Entry<Key, Value> entry : scanner) {
+   }
+   Trace.off();
+</pre>
+
+
+<p>Accumulo has been instrumented to record the time that various operations take when tracing is turned on.  The fact that tracing is 
+enabled follows all the requests made on behalf of the user throughout the distributed infrastructure of accumulo, and across all 
+threads of execution.</p>
+
+<p>These time spans will be inserted into the trace accumulo table.  You can browse recent traces from the accumulo monitor page.  
+You can also read the trace table directly.</p>
+
+<p>Tracing is supported in the shell.  For example:
+
+<pre>
+root@test&gt; createtable test
+root@test test&gt; insert a b c d
+root@test test&gt; trace on              
+root@test test&gt; scan
+a b:c []    d
+root@test test&gt; trace off
+Waiting for trace information
+Waiting for trace information
+Waiting for trace information
+Trace started at 2011/03/16 09:20:31.387
+Time  Start  Service@Location       Name
+ 3355+0      shell@host2 shell:root
+    1+1        shell@host2 client:listUsers
+    1+1434     tserver@host2 getUserAuthorizations
+    1+1434     shell@host2 client:getUserAuthorizations
+   10+1550     shell@host2 scan
+    9+1551       shell@host2 scan:location
+    7+1552         shell@host2 client:startScan
+    6+1553         tserver@host2 startScan
+    5+1553           tserver@host2 tablet read ahead 11
+    1+1559         shell@host2 client:closeScan
+    1+1561     shell@host2 client:listUsers
+</pre>
+
+<p>Here we can see that the shell is getting the list of users (which is used for tab-completion) after every command.  While
+unexpected, it is a fast operation.  In fact, all the requests are very fast, and most of the time is spent waiting for the user
+to make a request while tracing is turned on.</p>
+
+<p>Spans are added to the trace table asynchronously.  The user may have to wait several seconds for all requests to complete before the 
+trace information is complete.</p>
+
+<p>You can extract the trace data out of the trace table.  Each span is a stored as a column in a row named for the trace id. 
+The following code will print out a trace:</p>
+
+<pre>
+String table = AccumuloConfiguration.getSystemConfiguration().get(Property.TRACE_TABLE);
+Scanner scanner = shellState.connector.createScanner(table, auths);
+scanner.setRange(new Range(new Text(Long.toHexString(scanTrace.traceId()))));
+TraceDump.printTrace(scanner, new Printer() {
+    void print(String line) {
+        System.out.println(line);
+    }
+});
+</pre>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/documentation.css
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/documentation.css b/server/monitor/src/main/resources/docs/documentation.css
new file mode 100644
index 0000000..99ed599
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/documentation.css
@@ -0,0 +1,112 @@
+/*
+* 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.
+*/
+html, body {
+    font-size: 10pt;
+    font-family: verdana, arial;
+}
+
+h1 {
+    font-size: 1.7em;
+    font-variant: small-caps;
+    text-align: left;
+}
+
+h2 {
+    font-size: 1.3em; 
+    text-align: left;
+}
+
+.highlight {
+    background-color: rgb(206,244,181);
+}
+
+.deprecated {
+    text-decoration: line-through;
+}
+
+table {
+    min-width: 60%;
+    border: 1px #333333 solid;
+    border-spacing-top: 0;
+    border-spacing-bottom: 0;
+    border: 1px #333333 solid;
+    border: 1px #333333 solid;
+}
+
+th {
+    border-top: 0;
+    border-bottom: 3px #333333 solid;
+    border-left: 1px #333333 dotted;
+    border-right: 0;
+    border-spacing-top: 0;
+    border-spacing-bottom: 0;
+    text-align: center;
+    font-variant: small-caps;
+    padding-left: 0.1em;
+    padding-right: 0.1em;
+    padding-top: 0.2em;
+    padding-bottom: 0.2em;
+    vertical-align: bottom;
+}
+
+td {
+    border-top: 0;
+    border-bottom: 0;
+    border-left: 0;
+    border-right: 0;
+    border-spacing-top: 0;
+    border-spacing-bottom: 0;
+    padding-left: 0.05em;
+    padding-right: 0.05em;
+    padding-top: 0.15em;
+    padding-bottom: 0.15em;
+}
+
+thead {
+    color: rgb(66,114,185);
+    text-align: center;
+    text-weight: bold;
+}
+
+td {
+    font-size: 10pt;
+    text-align:left;
+    padding-left:7pt;
+    padding-right:7pt;
+}
+
+pre {
+    font-size: 9pt;
+}
+
+a {
+    text-decoration: none;
+    color: #0000ff;
+    line-height: 1.5em;
+}
+
+a:hover {
+    color: #004400;
+    text-decoration: underline;
+}
+
+.large {
+    font-size: 1.5em;
+    font-variant: small-caps;
+    text-align: left;
+}
+

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/examples/README
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/examples/README b/server/monitor/src/main/resources/docs/examples/README
new file mode 100644
index 0000000..0aad866
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/examples/README
@@ -0,0 +1,95 @@
+Title: Apache Accumulo Examples
+Notice:    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.
+
+Before running any of the examples, the following steps must be performed.
+
+1. Install and run Accumulo via the instructions found in $ACCUMULO_HOME/README.
+   Remember the instance name.  It will be referred to as "instance" throughout 
+   the examples. A comma-separated list of zookeeper servers will be referred 
+   to as "zookeepers".
+
+2. Create an Accumulo user (see the [user manual][1]), or use the root user.
+   The "username" Accumulo user name with password "password" is used 
+   throughout the examples. This user needs the ability to create tables.
+
+In all commands, you will need to replace "instance", "zookeepers", 
+"username", and "password" with the values you set for your Accumulo instance.
+
+Commands intended to be run in bash are prefixed by '$'.  These are always 
+assumed to be run from the $ACCUMULO_HOME directory.
+
+Commands intended to be run in the Accumulo shell are prefixed by '>'.
+
+Each README in the examples directory highlights the use of particular 
+features of Apache Accumulo.
+
+   README.batch:       Using the batch writer and batch scanner.
+
+   README.bloom:       Creating a bloom filter enabled table to increase query 
+                       performance.
+
+   README.bulkIngest:  Ingesting bulk data using map/reduce jobs on Hadoop.
+
+   README.classpath:   Using per-table classpaths.
+
+   README.client:      Using table operations, reading and writing data in Java.
+
+   README.combiner:    Using example StatsCombiner to find min, max, sum, and 
+                       count.
+
+   README.constraints: Using constraints with tables.
+
+   README.dirlist:     Storing filesystem information.
+
+   README.export:      Exporting and importing tables.
+
+   README.filedata:    Storing file data.
+
+   README.filter:      Using the AgeOffFilter to remove records more than 30 
+                       seconds old.
+
+   README.helloworld:  Inserting records both inside map/reduce jobs and 
+                       outside. And reading records between two rows.
+
+   README.isolation:   Using the isolated scanner to ensure partial changes 
+                       are not seen.
+
+   README.mapred:      Using MapReduce to read from and write to Accumulo 
+                       tables.
+
+   README.maxmutation: Limiting mutation size to avoid running out of memory.
+
+   README.regex:       Using MapReduce and Accumulo to find data using regular
+                       expressions.
+
+   README.rowhash:     Using MapReduce to read a table and write to a new 
+                       column in the same table.
+
+   README.shard:       Using the intersecting iterator with a term index 
+                       partitioned by document.
+
+   README.tabletofile: Using MapReduce to read a table and write one of its
+                       columns to a file in HDFS.
+
+   README.terasort:    Generating random data and sorting it using Accumulo.  
+
+   README.visibility:  Using visibilities (or combinations of authorizations). 
+                       Also shows user permissions.
+
+
+[1]: /1.5/user_manual/Accumulo_Shell.html#User_Administration

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/monitor/src/main/resources/docs/examples/README.batch
----------------------------------------------------------------------
diff --git a/server/monitor/src/main/resources/docs/examples/README.batch b/server/monitor/src/main/resources/docs/examples/README.batch
new file mode 100644
index 0000000..e78e808
--- /dev/null
+++ b/server/monitor/src/main/resources/docs/examples/README.batch
@@ -0,0 +1,55 @@
+Title: Apache Accumulo Batch Writing and Scanning Example
+Notice:    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.
+
+This tutorial uses the following Java classes, which can be found in org.apache.accumulo.examples.simple.client in the examples-simple module:
+
+ * SequentialBatchWriter.java - writes mutations with sequential rows and random values
+ * RandomBatchWriter.java - used by SequentialBatchWriter to generate random values
+ * RandomBatchScanner.java - reads random rows and verifies their values
+
+This is an example of how to use the batch writer and batch scanner. To compile
+the example, run maven and copy the produced jar into the accumulo lib dir.
+This is already done in the tar distribution. 
+
+Below are commands that add 10000 entries to accumulo and then do 100 random
+queries.  The write command generates random 50 byte values. 
+
+Be sure to use the name of your instance (given as instance here) and the appropriate 
+list of zookeeper nodes (given as zookeepers here).
+
+Before you run this, you must ensure that the user you are running has the
+"exampleVis" authorization. (you can set this in the shell with "setauths -u username -s exampleVis")
+
+    $ ./bin/accumulo shell -u root -e "setauths -u username -s exampleVis"
+
+You must also create the table, batchtest1, ahead of time. (In the shell, use "createtable batchtest1")
+
+    $ ./bin/accumulo shell -u username -e "createtable batchtest1"
+    $ ./bin/accumulo org.apache.accumulo.examples.simple.client.SequentialBatchWriter -i instance -z zookeepers -u username -p password -t batchtest1 --start 0 --num 10000 --size 50 --batchMemory 20M --batchLatency 500 --batchThreads 20 --vis exampleVis
+    $ ./bin/accumulo org.apache.accumulo.examples.simple.client.RandomBatchScanner -i instance -z zookeepers -u username -p password -t batchtest1 --num 100 --min 0 --max 10000 --size 50 --scanThreads 20 --vis exampleVis
+    07 11:33:11,103 [client.CountingVerifyingReceiver] INFO : Generating 100 random queries...
+    07 11:33:11,112 [client.CountingVerifyingReceiver] INFO : finished
+    07 11:33:11,260 [client.CountingVerifyingReceiver] INFO : 694.44 lookups/sec   0.14 secs
+    
+    07 11:33:11,260 [client.CountingVerifyingReceiver] INFO : num results : 100
+    
+    07 11:33:11,364 [client.CountingVerifyingReceiver] INFO : Generating 100 random queries...
+    07 11:33:11,370 [client.CountingVerifyingReceiver] INFO : finished
+    07 11:33:11,416 [client.CountingVerifyingReceiver] INFO : 2173.91 lookups/sec   0.05 secs
+    
+    07 11:33:11,416 [client.CountingVerifyingReceiver] INFO : num results : 100