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:55:51 UTC

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

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileInputFormat.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileInputFormat.java b/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileInputFormat.java
deleted file mode 100644
index f67eaa0..0000000
--- a/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileInputFormat.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.server.metanalysis;
-
-import java.io.EOFException;
-import java.io.IOException;
-
-import org.apache.accumulo.server.logger.LogFileKey;
-import org.apache.accumulo.server.logger.LogFileValue;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FSDataInputStream;
-import org.apache.hadoop.fs.FileStatus;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.mapreduce.InputSplit;
-import org.apache.hadoop.mapreduce.JobContext;
-import org.apache.hadoop.mapreduce.RecordReader;
-import org.apache.hadoop.mapreduce.TaskAttemptContext;
-import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
-import org.apache.hadoop.mapreduce.lib.input.FileSplit;
-
-/**
- * Input format for Accumulo write ahead logs
- */
-public class LogFileInputFormat extends FileInputFormat<LogFileKey,LogFileValue> {
-  
-  private static class LogFileRecordReader extends RecordReader<LogFileKey,LogFileValue> {
-    
-    private FSDataInputStream fsdis;
-    private LogFileKey key;
-    private LogFileValue value;
-    private long length;
-    
-    @Override
-    public void close() throws IOException {
-      fsdis.close();
-    }
-    
-    @Override
-    public LogFileKey getCurrentKey() throws IOException, InterruptedException {
-      return key;
-    }
-    
-    @Override
-    public LogFileValue getCurrentValue() throws IOException, InterruptedException {
-      return value;
-    }
-    
-    @Override
-    public float getProgress() throws IOException, InterruptedException {
-      float progress = (length - fsdis.getPos()) / (float) length;
-      if (progress < 0)
-        return 0;
-      return progress;
-    }
-    
-    @Override
-    public void initialize(InputSplit is, TaskAttemptContext context) throws IOException, InterruptedException {
-      FileSplit fileSplit = (FileSplit) is;
-      
-      Configuration conf = new Configuration();
-      FileSystem fs = FileSystem.get(conf);
-      
-      key = new LogFileKey();
-      value = new LogFileValue();
-      
-      fsdis = fs.open(fileSplit.getPath());
-      FileStatus status = fs.getFileStatus(fileSplit.getPath());
-      length = status.getLen();
-    }
-
-    @Override
-    public boolean nextKeyValue() throws IOException, InterruptedException {
-      if (key == null)
-        return false;
-      
-      try {
-        key.readFields(fsdis);
-        value.readFields(fsdis);
-        return true;
-      } catch (EOFException ex) {
-        key = null;
-        value = null;
-        return false;
-      }
-    }
-    
-  }
-
-  
-  @Override
-  public RecordReader<LogFileKey,LogFileValue> createRecordReader(InputSplit arg0, TaskAttemptContext arg1) throws IOException, InterruptedException {
-    return new LogFileRecordReader();
-  }
-  
-  @Override
-  protected boolean isSplitable(JobContext context, Path filename) {
-    return false;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileOutputFormat.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileOutputFormat.java b/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileOutputFormat.java
deleted file mode 100644
index 829d7bc..0000000
--- a/server/src/main/java/org/apache/accumulo/server/metanalysis/LogFileOutputFormat.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.server.metanalysis;
-
-import java.io.IOException;
-
-import org.apache.accumulo.server.logger.LogFileKey;
-import org.apache.accumulo.server.logger.LogFileValue;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FSDataOutputStream;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.mapreduce.RecordWriter;
-import org.apache.hadoop.mapreduce.TaskAttemptContext;
-import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
-
-/**
- * Output format for Accumulo write ahead logs.
- */
-public class LogFileOutputFormat extends FileOutputFormat<LogFileKey,LogFileValue> {
-  
-  private static class LogFileRecordWriter extends RecordWriter<LogFileKey,LogFileValue> {
-    
-    private FSDataOutputStream out;
-    
-    /**
-     * @param outputPath
-     * @throws IOException
-     */
-    public LogFileRecordWriter(Path outputPath) throws IOException {
-      Configuration conf = new Configuration();
-      FileSystem fs = FileSystem.get(conf);
-      
-      out = fs.create(outputPath);
-    }
-
-    @Override
-    public void close(TaskAttemptContext arg0) throws IOException, InterruptedException {
-      out.close();
-    }
-    
-    @Override
-    public void write(LogFileKey key, LogFileValue val) throws IOException, InterruptedException {
-      key.write(out);
-      val.write(out);
-    }
-    
-  }
-
-  @Override
-  public RecordWriter<LogFileKey,LogFileValue> getRecordWriter(TaskAttemptContext context) throws IOException, InterruptedException {
-    Path outputPath = getDefaultWorkFile(context, "");
-    return new LogFileRecordWriter(outputPath);
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/metanalysis/PrintEvents.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/metanalysis/PrintEvents.java b/server/src/main/java/org/apache/accumulo/server/metanalysis/PrintEvents.java
deleted file mode 100644
index 9de5d2e..0000000
--- a/server/src/main/java/org/apache/accumulo/server/metanalysis/PrintEvents.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.server.metanalysis;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map.Entry;
-
-import org.apache.accumulo.core.client.Connector;
-import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.data.ColumnUpdate;
-import org.apache.accumulo.core.data.Key;
-import org.apache.accumulo.core.data.Mutation;
-import org.apache.accumulo.core.data.PartialKey;
-import org.apache.accumulo.core.data.Range;
-import org.apache.accumulo.core.data.Value;
-import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
-import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.server.cli.ClientOpts;
-import org.apache.accumulo.server.logger.LogFileValue;
-import org.apache.hadoop.io.Text;
-
-import com.beust.jcommander.Parameter;
-
-/**
- * Looks up and prints mutations indexed by IndexMeta
- */
-public class PrintEvents {
-  
-  static class Opts extends ClientOpts {
-    @Parameter(names = {"-t", "--tableId"}, description = "table id", required = true)
-    String tableId;
-    @Parameter(names = {"-e", "--endRow"}, description = "end row")
-    String endRow;
-    @Parameter(names = {"-t", "--time"}, description = "time, in milliseconds", required = true)
-    long time;
-  }
-  
-  /**
-   * @param args
-   */
-  public static void main(String[] args) throws Exception {
-    Opts opts = new Opts();
-    opts.parseArgs(PrintEvents.class.getName(), args);
-    
-    Connector conn = opts.getConnector();
-    
-    printEvents(conn, opts.tableId, opts.endRow, opts.time);
-  }
-  
-  /**
-   * @param conn
-   * @param tablePrefix
-   * @param tableId
-   * @param endRow
-   * @param time
-   */
-  private static void printEvents(Connector conn, String tableId, String endRow, Long time) throws Exception {
-    Scanner scanner = conn.createScanner("tabletEvents", new Authorizations());
-    String metaRow = tableId + (endRow == null ? "<" : ";" + endRow);
-    scanner.setRange(new Range(new Key(metaRow, String.format("%020d", time)), true, new Key(metaRow).followingKey(PartialKey.ROW), false));
-    int count = 0;
-    
-    String lastLog = null;
-    
-    loop1: for (Entry<Key,Value> entry : scanner) {
-      if (entry.getKey().getColumnQualifier().toString().equals("log")) {
-        if (lastLog == null || !lastLog.equals(entry.getValue().toString()))
-          System.out.println("Log : " + entry.getValue());
-        lastLog = entry.getValue().toString();
-      } else if (entry.getKey().getColumnQualifier().toString().equals("mut")) {
-        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(entry.getValue().get()));
-        Mutation m = new Mutation();
-        m.readFields(dis);
-        
-        LogFileValue lfv = new LogFileValue();
-        lfv.mutations = Collections.singletonList(m);
-        
-        System.out.println(LogFileValue.format(lfv, 1));
-        
-        List<ColumnUpdate> columnsUpdates = m.getUpdates();
-        for (ColumnUpdate cu : columnsUpdates) {
-          if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.equals(new Text(cu.getColumnFamily()), new Text(cu.getColumnQualifier())) && count > 0) {
-            System.out.println("Saw change to prevrow, stopping printing events.");
-            break loop1;
-          }
-        }
-        count++;
-      }
-    }
-    
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/metanalysis/package-info.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/metanalysis/package-info.java b/server/src/main/java/org/apache/accumulo/server/metanalysis/package-info.java
deleted file mode 100644
index 4d404ed..0000000
--- a/server/src/main/java/org/apache/accumulo/server/metanalysis/package-info.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-/**
- * Provides programs to analyze metadata mutations written to write ahead logs.  
- * 
- * <p>
- * These programs can be used when write ahead logs are archived.   The best way to find
- * which write ahead logs contain metadata mutations is to grep the tablet server logs.  
- * Grep for events where walogs were added to metadata tablets, then take the unique set 
- * of walogs.
- *
- * <p>
- * To use these programs, use IndexMeta to index the metadata mutations in walogs into 
- * Accumulo tables.  Then use FindTable and PrintEvents to analyze those indexes.  
- * FilterMetaiallows filtering walogs down to just metadata events.  This is useful for the
- * case where the walogs need to be exported from the cluster for analysis.
- *
- * @since 1.5
- */
-package org.apache.accumulo.server.metanalysis;

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/metrics/AbstractMetricsImpl.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/metrics/AbstractMetricsImpl.java b/server/src/main/java/org/apache/accumulo/server/metrics/AbstractMetricsImpl.java
deleted file mode 100644
index 9735371..0000000
--- a/server/src/main/java/org/apache/accumulo/server/metrics/AbstractMetricsImpl.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * 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.server.metrics;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.StandardMBean;
-
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.time.DateUtils;
-
-public abstract class AbstractMetricsImpl {
-  
-  public class Metric {
-    
-    private long count = 0;
-    private long avg = 0;
-    private long min = 0;
-    private long max = 0;
-    
-    public long getCount() {
-      return count;
-    }
-    
-    public long getAvg() {
-      return avg;
-    }
-    
-    public long getMin() {
-      return min;
-    }
-    
-    public long getMax() {
-      return max;
-    }
-    
-    public void incCount() {
-      count++;
-    }
-    
-    public void addAvg(long a) {
-      if (a < 0)
-        return;
-      avg = (long) ((avg * .8) + (a * .2));
-    }
-    
-    public void addMin(long a) {
-      if (a < 0)
-        return;
-      min = Math.min(min, a);
-    }
-    
-    public void addMax(long a) {
-      if (a < 0)
-        return;
-      max = Math.max(max, a);
-    }
-    
-    @Override
-    public String toString() {
-      return new ToStringBuilder(this).append("count", count).append("average", avg).append("minimum", min).append("maximum", max).toString();
-    }
-    
-  }
-  
-  static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(AbstractMetricsImpl.class);
-  
-  private static ConcurrentHashMap<String,Metric> registry = new ConcurrentHashMap<String,Metric>();
-  
-  private boolean currentlyLogging = false;
-  
-  private File logDir = null;
-  
-  private String metricsPrefix = null;
-  
-  private Date today = new Date();
-  
-  private File logFile = null;
-  
-  private FileWriter logWriter = null;
-  
-  private SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
-  
-  private SimpleDateFormat logFormatter = new SimpleDateFormat("yyyyMMddhhmmssz");
-  
-  private MetricsConfiguration config = null;
-  
-  public AbstractMetricsImpl() {
-    this.metricsPrefix = getMetricsPrefix();
-    config = new MetricsConfiguration(metricsPrefix);
-  }
-  
-  /**
-   * Registers a StandardMBean with the MBean Server
-   * 
-   * @throws Exception
-   */
-  public void register(StandardMBean mbean) throws Exception {
-    // Register this object with the MBeanServer
-    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-    if (null == getObjectName())
-      throw new IllegalArgumentException("MBean object name must be set.");
-    mbs.registerMBean(mbean, getObjectName());
-    
-    setupLogging();
-  }
-  
-  /**
-   * Registers this MBean with the MBean Server
-   * 
-   * @throws Exception
-   */
-  public void register() throws Exception {
-    // Register this object with the MBeanServer
-    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-    if (null == getObjectName())
-      throw new IllegalArgumentException("MBean object name must be set.");
-    mbs.registerMBean(this, getObjectName());
-    setupLogging();
-  }
-  
-  public void createMetric(String name) {
-    registry.put(name, new Metric());
-  }
-  
-  public Metric getMetric(String name) {
-    return registry.get(name);
-  }
-  
-  public long getMetricCount(String name) {
-    return registry.get(name).getCount();
-  }
-  
-  public long getMetricAvg(String name) {
-    return registry.get(name).getAvg();
-  }
-  
-  public long getMetricMin(String name) {
-    return registry.get(name).getMin();
-  }
-  
-  public long getMetricMax(String name) {
-    return registry.get(name).getMax();
-  }
-  
-  private void setupLogging() throws IOException {
-    if (null == config.getMetricsConfiguration())
-      return;
-    // If we are already logging, then return
-    if (!currentlyLogging && config.getMetricsConfiguration().getBoolean(metricsPrefix + ".logging", false)) {
-      // Check to see if directory exists, else make it
-      String mDir = config.getMetricsConfiguration().getString("logging.dir");
-      if (null != mDir) {
-        File dir = new File(mDir);
-        if (!dir.isDirectory())
-          dir.mkdir();
-        logDir = dir;
-        // Create new log file
-        startNewLog();
-      }
-      currentlyLogging = true;
-    }
-  }
-  
-  private void startNewLog() throws IOException {
-    if (null != logWriter) {
-      logWriter.flush();
-      logWriter.close();
-    }
-    logFile = new File(logDir, metricsPrefix + "-" + formatter.format(today) + ".log");
-    if (!logFile.exists()) {
-      if (!logFile.createNewFile()) {
-        log.error("Unable to create new log file");
-        currentlyLogging = false;
-        return;
-      }
-    }
-    logWriter = new FileWriter(logFile, true);
-  }
-  
-  private void writeToLog(String name) throws IOException {
-    if (null == logWriter)
-      return;
-    // Increment the date if we have to
-    Date now = new Date();
-    if (!DateUtils.isSameDay(today, now)) {
-      today = now;
-      startNewLog();
-    }
-    logWriter.append(logFormatter.format(now)).append(" Metric: ").append(name).append(": ").append(registry.get(name).toString()).append("\n");
-  }
-  
-  public void add(String name, long time) {
-    if (isEnabled()) {
-      registry.get(name).incCount();
-      registry.get(name).addAvg(time);
-      registry.get(name).addMin(time);
-      registry.get(name).addMax(time);
-      // If we are not currently logging and should be, then initialize
-      if (!currentlyLogging && config.getMetricsConfiguration().getBoolean(metricsPrefix + ".logging", false)) {
-        try {
-          setupLogging();
-        } catch (IOException ioe) {
-          log.error("Error setting up log", ioe);
-        }
-      } else if (currentlyLogging && !config.getMetricsConfiguration().getBoolean(metricsPrefix + ".logging", false)) {
-        // if we are currently logging and shouldn't be, then close logs
-        try {
-          logWriter.flush();
-          logWriter.close();
-          logWriter = null;
-          logFile = null;
-        } catch (Exception e) {
-          log.error("Error stopping metrics logging", e);
-        }
-        currentlyLogging = false;
-      }
-      if (currentlyLogging) {
-        try {
-          writeToLog(name);
-        } catch (IOException ioe) {
-          log.error("Error writing to metrics log", ioe);
-        }
-      }
-    }
-  }
-  
-  public boolean isEnabled() {
-    return config.isEnabled();
-  }
-  
-  protected abstract ObjectName getObjectName();
-  
-  protected abstract String getMetricsPrefix();
-  
-  @Override
-  protected void finalize() {
-    if (null != logWriter) {
-      try {
-        logWriter.close();
-      } catch (Exception e) {
-        // do nothing
-      } finally {
-        logWriter = null;
-      }
-    }
-    logFile = null;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/metrics/MetricsConfiguration.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/metrics/MetricsConfiguration.java b/server/src/main/java/org/apache/accumulo/server/metrics/MetricsConfiguration.java
deleted file mode 100644
index 446a548..0000000
--- a/server/src/main/java/org/apache/accumulo/server/metrics/MetricsConfiguration.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * 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.server.metrics;
-
-import java.io.File;
-import java.util.Iterator;
-
-import org.apache.accumulo.core.util.Daemon;
-import org.apache.commons.configuration.AbstractFileConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.EnvironmentConfiguration;
-import org.apache.commons.configuration.SystemConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.commons.configuration.event.ConfigurationEvent;
-import org.apache.commons.configuration.event.ConfigurationListener;
-import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
-import org.apache.commons.lang.builder.ToStringBuilder;
-
-public class MetricsConfiguration {
-  
-  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(MetricsConfiguration.class);
-  
-  private static final String metricsFileName = "accumulo-metrics.xml";
-  
-  private static boolean alreadyWarned = false;
-  
-  private boolean notFound = false;
-  
-  private int notFoundCount = 0;
-  
-  private static SystemConfiguration sysConfig = null;
-  
-  private static EnvironmentConfiguration envConfig = null;
-  
-  private XMLConfiguration xConfig = null;
-  
-  private Configuration config = null;
-  
-  private final Object lock = new Object();
-  
-  private boolean needsReloading = false;
-  
-  private long lastCheckTime = 0;
-  
-  private static long CONFIG_FILE_CHECK_INTERVAL = 1000 * 60 * 10; // 10 minutes
-  
-  private static int CONFIG_FILE_CHECK_COUNTER = 100;
-  
-  public final static long CONFIG_FILE_RELOAD_DELAY = 60000;
-  
-  private MetricsConfigWatcher watcher = null;
-  
-  private boolean enabled = false;
-  
-  private String enabledName = null;
-  
-  /**
-   * Background thread that pokes the XMLConfiguration file to see if it has changed. If it has, then the Configuration Listener will get an event.
-   * 
-   */
-  private class MetricsConfigWatcher extends Daemon {
-    public MetricsConfigWatcher() {}
-    
-    public void run() {
-      while (this.isAlive()) {
-        try {
-          Thread.sleep(MetricsConfiguration.CONFIG_FILE_RELOAD_DELAY);
-        } catch (InterruptedException ie) {
-          // Do Nothing
-        }
-        xConfig.getBoolean("master.enabled");
-      }
-    }
-  }
-  
-  /**
-   * ConfigurationListener that sets a flag to reload the XML config file
-   */
-  private class MetricsConfigListener implements ConfigurationListener {
-    public void configurationChanged(ConfigurationEvent event) {
-      if (event.getType() == AbstractFileConfiguration.EVENT_RELOAD)
-        needsReloading = true;
-    }
-  }
-  
-  public MetricsConfiguration(String name) {
-    // We are going to store the "enabled" parameter for this
-    // name as a shortcut so that it doesn't have to be looked
-    // up in the configuration so much.
-    this.enabledName = name + ".enabled";
-    getMetricsConfiguration();
-  }
-  
-  public Configuration getEnvironmentConfiguration() {
-    if (null == envConfig)
-      envConfig = new EnvironmentConfiguration();
-    return envConfig;
-  }
-  
-  public Configuration getSystemConfiguration() {
-    if (null == sysConfig)
-      sysConfig = new SystemConfiguration();
-    return sysConfig;
-  }
-  
-  public Configuration getMetricsConfiguration() {
-    if (notFound) {
-      if (notFoundCount <= CONFIG_FILE_CHECK_COUNTER) {
-        return null;
-      } else if ((notFoundCount > CONFIG_FILE_CHECK_COUNTER) && ((System.currentTimeMillis() - lastCheckTime) > CONFIG_FILE_CHECK_INTERVAL)) {
-        notFoundCount = 0;
-        lastCheckTime = System.currentTimeMillis();
-        notFound = false;
-      } else {
-        notFoundCount++;
-      }
-    }
-    if (null == config || needsReloading)
-      synchronized (lock) {
-        if (needsReloading) {
-          loadConfiguration();
-        } else if (null == config) {
-          loadConfiguration();
-        }
-        needsReloading = false;
-      }
-    return config;
-  }
-  
-  private void loadConfiguration() {
-    // Check to see if ACCUMULO_HOME environment variable is set.
-    String ACUHOME = getEnvironmentConfiguration().getString("ACCUMULO_CONF_DIR");
-    if (null != ACUHOME) {
-      // Try to load the metrics properties file
-      File mFile = new File(ACUHOME, metricsFileName);
-      if (mFile.exists()) {
-        if (log.isDebugEnabled())
-          log.debug("Loading config file: " + mFile.getAbsolutePath());
-        try {
-          xConfig = new XMLConfiguration(mFile);
-          xConfig.append(getEnvironmentConfiguration());
-          xConfig.addConfigurationListener(new MetricsConfigListener());
-          xConfig.setReloadingStrategy(new FileChangedReloadingStrategy());
-          
-          // Start a background Thread that checks a property from the XMLConfiguration
-          // every so often to force the FileChangedReloadingStrategy to fire.
-          if (null == watcher || !watcher.isAlive()) {
-            watcher = new MetricsConfigWatcher();
-            watcher.start();
-          }
-          notFound = false;
-          alreadyWarned = false;
-        } catch (ConfigurationException ce) {
-          log.error("Error reading accumulo-metrics.xml file.");
-          notFound = true;
-          return;
-        }
-      } else {
-        if (!alreadyWarned)
-          log.warn("Unable to find metrics file: " + mFile.getAbsolutePath());
-        alreadyWarned = true;
-        notFound = true;
-        return;
-      }
-    } else {
-      if (!alreadyWarned)
-        log.warn("ACCUMULO_CONF_DIR variable not found in environment. Metrics collection will be disabled.");
-      alreadyWarned = true;
-      notFound = true;
-      return;
-    }
-    if (xConfig != null) {
-      config = xConfig.interpolatedConfiguration();
-      // set the enabled boolean from the configuration
-      enabled = config.getBoolean(enabledName);
-      if (log.isDebugEnabled())
-        log.debug("Metrics collection enabled=" + enabled);
-    } else {
-      enabled = false;
-    }
-    
-  }
-  
-  public boolean isEnabled() {
-    // Force reload if necessary
-    if (null == getMetricsConfiguration())
-      return false;
-    return enabled;
-  }
-  
-  public static String toStringValue(Configuration config) {
-    ToStringBuilder tsb = new ToStringBuilder(MetricsConfiguration.class);
-    Iterator<?> keys = config.getKeys();
-    while (keys.hasNext()) {
-      tsb.append("\n");
-      String k = (String) keys.next();
-      Object v = config.getString(k);
-      if (null == v)
-        v = config.getList(k);
-      tsb.append(k, v.toString());
-    }
-    return tsb.toString();
-  }
-  
-  public static void main(String[] args) throws Exception {
-    MetricsConfiguration mc = new MetricsConfiguration("master");
-    while (true) {
-      // System.out.println(MetricsConfiguration.toStringValue(getSystemConfiguration()));
-      System.out.println("------------------------------------------------------------------------------------------------");
-      // System.out.println(MetricsConfiguration.toStringValue());
-      long t1 = System.currentTimeMillis();
-      System.out.println(mc.isEnabled() + " took: " + (System.currentTimeMillis() - t1));
-      Thread.sleep(1000);
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/monitor/DedupedLogEvent.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/monitor/DedupedLogEvent.java b/server/src/main/java/org/apache/accumulo/server/monitor/DedupedLogEvent.java
deleted file mode 100644
index 4acb1a9..0000000
--- a/server/src/main/java/org/apache/accumulo/server/monitor/DedupedLogEvent.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.server.monitor;
-
-import org.apache.log4j.spi.LoggingEvent;
-
-public class DedupedLogEvent {
-  
-  private LoggingEvent event;
-  private int count = 0;
-  private int hash = -1;
-  
-  public DedupedLogEvent(LoggingEvent event) {
-    this(event, 1);
-  }
-  
-  public DedupedLogEvent(LoggingEvent event, int count) {
-    this.event = event;
-    this.count = count;
-  }
-  
-  public LoggingEvent getEvent() {
-    return event;
-  }
-  
-  public int getCount() {
-    return count;
-  }
-  
-  public void setCount(int count) {
-    this.count = count;
-  }
-  
-  @Override
-  public int hashCode() {
-    if (hash == -1) {
-      String eventId = event.getMDC("application").toString() + ":" + event.getLevel().toString() + ":" + event.getMessage().toString();
-      hash = eventId.hashCode();
-    }
-    return hash;
-  }
-  
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof DedupedLogEvent)
-      return this.event.equals(((DedupedLogEvent) obj).event);
-    return false;
-  }
-  
-  @Override
-  public String toString() {
-    return event.getMDC("application").toString() + ":" + event.getLevel().toString() + ":" + event.getMessage().toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/monitor/LogService.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/monitor/LogService.java b/server/src/main/java/org/apache/accumulo/server/monitor/LogService.java
deleted file mode 100644
index ce5dab8..0000000
--- a/server/src/main/java/org/apache/accumulo/server/monitor/LogService.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.server.monitor;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.Daemon;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeExistsPolicy;
-import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.apache.log4j.net.SocketNode;
-import org.apache.log4j.spi.LoggingEvent;
-
-/**
- * Hijack log4j and capture log events for display.
- * 
- */
-public class LogService extends org.apache.log4j.AppenderSkeleton {
-  
-  private static final Logger log = Logger.getLogger(LogService.class);
-  
-  /**
-   * Read logging events forward to us over the net.
-   * 
-   */
-  static class SocketServer implements Runnable {
-    private ServerSocket server = null;
-    
-    public SocketServer(int port) {
-      try {
-        server = new ServerSocket(port);
-      } catch (IOException io) {
-        throw new RuntimeException(io);
-      }
-    }
-    
-    public int getLocalPort() {
-      return server.getLocalPort();
-    }
-    
-    public void run() {
-      try {
-        while (true) {
-          log.debug("Waiting for log message senders");
-          Socket socket = server.accept();
-          log.debug("Got a new connection");
-          Thread t = new Daemon(new SocketNode(socket, LogManager.getLoggerRepository()));
-          t.start();
-        }
-      } catch (IOException io) {
-        log.error(io, io);
-      }
-    }
-  }
-  
-  static void startLogListener(AccumuloConfiguration conf, String instanceId) {
-    try {
-      SocketServer server = new SocketServer(conf.getPort(Property.MONITOR_LOG4J_PORT));
-      ZooReaderWriter.getInstance().putPersistentData(ZooUtil.getRoot(instanceId) + Constants.ZMONITOR_LOG4J_PORT,
-          Integer.toString(server.getLocalPort()).getBytes(), NodeExistsPolicy.OVERWRITE);
-      new Daemon(server).start();
-    } catch (Throwable t) {
-      log.info("Unable to listen to cluster-wide ports", t);
-    }
-  }
-  
-  static private LogService instance = null;
-  
-  synchronized public static LogService getInstance() {
-    if (instance == null)
-      return new LogService();
-    return instance;
-  }
-  
-  private static final int MAX_LOGS = 50;
-  
-  private LinkedHashMap<String,DedupedLogEvent> events = new LinkedHashMap<String,DedupedLogEvent>(MAX_LOGS + 1, (float) .75, true) {
-    
-    private static final long serialVersionUID = 1L;
-    
-    @Override
-    @SuppressWarnings("rawtypes")
-    protected boolean removeEldestEntry(Map.Entry eldest) {
-      return size() > MAX_LOGS;
-    }
-  };
-  
-  public LogService() {
-    synchronized (LogService.class) {
-      instance = this;
-    }
-  }
-  
-  @Override
-  synchronized protected void append(LoggingEvent ev) {
-    Object application = ev.getMDC("application");
-    if (application == null || application.toString().isEmpty())
-      return;
-    
-    DedupedLogEvent dev = new DedupedLogEvent(ev);
-    
-    // if event is present, increase the count
-    if (events.containsKey(dev.toString())) {
-      DedupedLogEvent oldDev = events.remove(dev.toString());
-      dev.setCount(oldDev.getCount() + 1);
-    }
-    events.put(dev.toString(), dev);
-  }
-  
-  @Override
-  public void close() {
-    events = null;
-  }
-  
-  @Override
-  public synchronized void doAppend(LoggingEvent event) {
-    super.doAppend(event);
-  }
-  
-  @Override
-  public boolean requiresLayout() {
-    return false;
-  }
-  
-  synchronized public List<DedupedLogEvent> getEvents() {
-    return new ArrayList<DedupedLogEvent>(events.values());
-  }
-  
-  synchronized public void clear() {
-    events.clear();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java b/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java
deleted file mode 100644
index 650f5b9..0000000
--- a/server/src/main/java/org/apache/accumulo/server/monitor/Monitor.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * 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.server.monitor;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.impl.MasterClient;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.gc.thrift.GCMonitorService;
-import org.apache.accumulo.core.gc.thrift.GCStatus;
-import org.apache.accumulo.core.master.thrift.Compacting;
-import org.apache.accumulo.core.master.thrift.MasterClientService;
-import org.apache.accumulo.core.master.thrift.MasterMonitorInfo;
-import org.apache.accumulo.core.master.thrift.TableInfo;
-import org.apache.accumulo.core.master.thrift.TabletServerStatus;
-import org.apache.accumulo.core.security.SecurityUtil;
-import org.apache.accumulo.core.util.Daemon;
-import org.apache.accumulo.core.util.LoggingRunnable;
-import org.apache.accumulo.core.util.Pair;
-import org.apache.accumulo.core.util.ServerServices;
-import org.apache.accumulo.core.util.ServerServices.Service;
-import org.apache.accumulo.core.util.ThriftUtil;
-import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
-import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeExistsPolicy;
-import org.apache.accumulo.server.Accumulo;
-import org.apache.accumulo.server.ServerOpts;
-import org.apache.accumulo.server.client.HdfsZooInstance;
-import org.apache.accumulo.server.conf.ServerConfiguration;
-import org.apache.accumulo.server.fs.VolumeManager;
-import org.apache.accumulo.server.fs.VolumeManagerImpl;
-import org.apache.accumulo.server.monitor.servlets.DefaultServlet;
-import org.apache.accumulo.server.monitor.servlets.GcStatusServlet;
-import org.apache.accumulo.server.monitor.servlets.JSONServlet;
-import org.apache.accumulo.server.monitor.servlets.LogServlet;
-import org.apache.accumulo.server.monitor.servlets.MasterServlet;
-import org.apache.accumulo.server.monitor.servlets.OperationServlet;
-import org.apache.accumulo.server.monitor.servlets.ProblemServlet;
-import org.apache.accumulo.server.monitor.servlets.ShellServlet;
-import org.apache.accumulo.server.monitor.servlets.TServersServlet;
-import org.apache.accumulo.server.monitor.servlets.TablesServlet;
-import org.apache.accumulo.server.monitor.servlets.VisServlet;
-import org.apache.accumulo.server.monitor.servlets.XMLServlet;
-import org.apache.accumulo.server.monitor.servlets.trace.ListType;
-import org.apache.accumulo.server.monitor.servlets.trace.ShowTrace;
-import org.apache.accumulo.server.monitor.servlets.trace.Summary;
-import org.apache.accumulo.server.problems.ProblemReports;
-import org.apache.accumulo.server.problems.ProblemType;
-import org.apache.accumulo.server.security.SystemCredentials;
-import org.apache.accumulo.server.util.EmbeddedWebServer;
-import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
-import org.apache.accumulo.trace.instrument.Tracer;
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooKeeper;
-
-import com.google.common.net.HostAndPort;
-
-/**
- * Serve master statistics with an embedded web server.
- */
-public class Monitor {
-  private static final Logger log = Logger.getLogger(Monitor.class);
-  
-  public static final int REFRESH_TIME = 5;
-  private static long lastRecalc = 0L;
-  private static double totalIngestRate = 0.0;
-  private static double totalIngestByteRate = 0.0;
-  private static double totalQueryRate = 0.0;
-  private static double totalScanRate = 0.0;
-  private static double totalQueryByteRate = 0.0;
-  private static long totalEntries = 0L;
-  private static int totalTabletCount = 0;
-  private static int onlineTabletCount = 0;
-  private static long totalHoldTime = 0;
-  private static long totalLookups = 0;
-  private static int totalTables = 0;
-  
-  private static class MaxList<T> extends LinkedList<Pair<Long,T>> {
-    private static final long serialVersionUID = 1L;
-    
-    private long maxDelta;
-    
-    public MaxList(long maxDelta) {
-      this.maxDelta = maxDelta;
-    }
-    
-    @Override
-    public boolean add(Pair<Long,T> obj) {
-      boolean result = super.add(obj);
-      
-      if (obj.getFirst() - get(0).getFirst() > maxDelta)
-        remove(0);
-      
-      return result;
-    }
-    
-  }
-  
-  private static final int MAX_TIME_PERIOD = 60 * 60 * 1000;
-  private static final List<Pair<Long,Double>> loadOverTime = Collections.synchronizedList(new MaxList<Double>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Double>> ingestRateOverTime = Collections.synchronizedList(new MaxList<Double>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Double>> ingestByteRateOverTime = Collections.synchronizedList(new MaxList<Double>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Integer>> recoveriesOverTime = Collections.synchronizedList(new MaxList<Integer>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Integer>> minorCompactionsOverTime = Collections.synchronizedList(new MaxList<Integer>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Integer>> majorCompactionsOverTime = Collections.synchronizedList(new MaxList<Integer>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Double>> lookupsOverTime = Collections.synchronizedList(new MaxList<Double>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Integer>> queryRateOverTime = Collections.synchronizedList(new MaxList<Integer>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Integer>> scanRateOverTime = Collections.synchronizedList(new MaxList<Integer>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Double>> queryByteRateOverTime = Collections.synchronizedList(new MaxList<Double>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Double>> indexCacheHitRateOverTime = Collections.synchronizedList(new MaxList<Double>(MAX_TIME_PERIOD));
-  private static final List<Pair<Long,Double>> dataCacheHitRateOverTime = Collections.synchronizedList(new MaxList<Double>(MAX_TIME_PERIOD));
-  private static EventCounter lookupRateTracker = new EventCounter();
-  private static EventCounter indexCacheHitTracker = new EventCounter();
-  private static EventCounter indexCacheRequestTracker = new EventCounter();
-  private static EventCounter dataCacheHitTracker = new EventCounter();
-  private static EventCounter dataCacheRequestTracker = new EventCounter();
-  
-  private static volatile boolean fetching = false;
-  private static MasterMonitorInfo mmi;
-  private static Map<String,Map<ProblemType,Integer>> problemSummary = Collections.emptyMap();
-  private static Exception problemException;
-  private static GCStatus gcStatus;
-  
-  private static Instance instance;
-  
-  private static ServerConfiguration config;
-  
-  private static EmbeddedWebServer server;
-  
-  public static Map<String,Double> summarizeTableStats(MasterMonitorInfo mmi) {
-    Map<String,Double> compactingByTable = new HashMap<String,Double>();
-    if (mmi != null && mmi.tServerInfo != null) {
-      for (TabletServerStatus status : mmi.tServerInfo) {
-        if (status != null && status.tableMap != null) {
-          for (String table : status.tableMap.keySet()) {
-            Double holdTime = compactingByTable.get(table);
-            compactingByTable.put(table, Math.max(holdTime == null ? 0. : holdTime.doubleValue(), status.holdTime));
-          }
-        }
-      }
-    }
-    return compactingByTable;
-  }
-  
-  public static void add(TableInfo total, TableInfo more) {
-    if (total.minors == null)
-      total.minors = new Compacting();
-    if (total.majors == null)
-      total.majors = new Compacting();
-    if (total.scans == null)
-      total.scans = new Compacting();
-    if (more.minors != null) {
-      total.minors.running += more.minors.running;
-      total.minors.queued += more.minors.queued;
-    }
-    if (more.majors != null) {
-      total.majors.running += more.majors.running;
-      total.majors.queued += more.majors.queued;
-    }
-    if (more.scans != null) {
-      total.scans.running += more.scans.running;
-      total.scans.queued += more.scans.queued;
-    }
-    total.onlineTablets += more.onlineTablets;
-    total.recs += more.recs;
-    total.recsInMemory += more.recsInMemory;
-    total.tablets += more.tablets;
-    total.ingestRate += more.ingestRate;
-    total.ingestByteRate += more.ingestByteRate;
-    total.queryRate += more.queryRate;
-    total.queryByteRate += more.queryByteRate;
-    total.scanRate += more.scanRate;
-  }
-  
-  public static TableInfo summarizeTableStats(TabletServerStatus status) {
-    TableInfo summary = new TableInfo();
-    summary.majors = new Compacting();
-    summary.minors = new Compacting();
-    summary.scans = new Compacting();
-    for (TableInfo rates : status.tableMap.values()) {
-      add(summary, rates);
-    }
-    return summary;
-  }
-  
-  private static class EventCounter {
-    
-    Map<String,Pair<Long,Long>> prevSamples = new HashMap<String,Pair<Long,Long>>();
-    Map<String,Pair<Long,Long>> samples = new HashMap<String,Pair<Long,Long>>();
-    Set<String> serversUpdated = new HashSet<String>();
-    
-    void startingUpdates() {
-      serversUpdated.clear();
-    }
-    
-    void updateTabletServer(String name, long sampleTime, long numEvents) {
-      Pair<Long,Long> newSample = new Pair<Long,Long>(sampleTime, numEvents);
-      Pair<Long,Long> lastSample = samples.get(name);
-      
-      if (lastSample == null || !lastSample.equals(newSample)) {
-        samples.put(name, newSample);
-        if (lastSample != null) {
-          prevSamples.put(name, lastSample);
-        }
-      }
-      serversUpdated.add(name);
-    }
-    
-    void finishedUpdating() {
-      // remove any tablet servers not updated
-      samples.keySet().retainAll(serversUpdated);
-      prevSamples.keySet().retainAll(serversUpdated);
-    }
-    
-    double calculateRate() {
-      double totalRate = 0;
-      
-      for (Entry<String,Pair<Long,Long>> entry : prevSamples.entrySet()) {
-        Pair<Long,Long> prevSample = entry.getValue();
-        Pair<Long,Long> sample = samples.get(entry.getKey());
-        
-        totalRate += (sample.getSecond() - prevSample.getSecond()) / ((sample.getFirst() - prevSample.getFirst()) / (double) 1000);
-      }
-      
-      return totalRate;
-    }
-    
-    long calculateCount() {
-      long count = 0;
-      
-      for (Entry<String,Pair<Long,Long>> entry : prevSamples.entrySet()) {
-        Pair<Long,Long> prevSample = entry.getValue();
-        Pair<Long,Long> sample = samples.get(entry.getKey());
-        
-        count += sample.getSecond() - prevSample.getSecond();
-      }
-      
-      return count;
-    }
-  }
-  
-  public static void fetchData() {
-    double totalIngestRate = 0.;
-    double totalIngestByteRate = 0.;
-    double totalQueryRate = 0.;
-    double totalQueryByteRate = 0.;
-    double totalScanRate = 0.;
-    long totalEntries = 0;
-    int totalTabletCount = 0;
-    int onlineTabletCount = 0;
-    long totalHoldTime = 0;
-    long totalLookups = 0;
-    boolean retry = true;
-    
-    // only recalc every so often
-    long currentTime = System.currentTimeMillis();
-    if (currentTime - lastRecalc < REFRESH_TIME * 1000)
-      return;
-    
-    synchronized (Monitor.class) {
-      if (fetching)
-        return;
-      fetching = true;
-    }
-    
-    try {
-      while (retry) {
-        MasterClientService.Iface client = null;
-        try {
-          client = MasterClient.getConnection(HdfsZooInstance.getInstance());
-          if (client != null) {
-            mmi = client.getMasterStats(Tracer.traceInfo(), SystemCredentials.get().toThrift(HdfsZooInstance.getInstance()));
-            retry = false;
-          } else {
-            mmi = null;
-          }
-          Monitor.gcStatus = fetchGcStatus();
-        } catch (Exception e) {
-          mmi = null;
-          log.info("Error fetching stats: " + e);
-        } finally {
-          if (client != null) {
-            MasterClient.close(client);
-          }
-        }
-        if (mmi == null)
-          UtilWaitThread.sleep(1000);
-      }
-      if (mmi != null) {
-        int majorCompactions = 0;
-        int minorCompactions = 0;
-        
-        lookupRateTracker.startingUpdates();
-        indexCacheHitTracker.startingUpdates();
-        indexCacheRequestTracker.startingUpdates();
-        dataCacheHitTracker.startingUpdates();
-        dataCacheRequestTracker.startingUpdates();
-        
-        for (TabletServerStatus server : mmi.tServerInfo) {
-          TableInfo summary = Monitor.summarizeTableStats(server);
-          totalIngestRate += summary.ingestRate;
-          totalIngestByteRate += summary.ingestByteRate;
-          totalQueryRate += summary.queryRate;
-          totalScanRate += summary.scanRate;
-          totalQueryByteRate += summary.queryByteRate;
-          totalEntries += summary.recs;
-          totalHoldTime += server.holdTime;
-          totalLookups += server.lookups;
-          majorCompactions += summary.majors.running;
-          minorCompactions += summary.minors.running;
-          lookupRateTracker.updateTabletServer(server.name, server.lastContact, server.lookups);
-          indexCacheHitTracker.updateTabletServer(server.name, server.lastContact, server.indexCacheHits);
-          indexCacheRequestTracker.updateTabletServer(server.name, server.lastContact, server.indexCacheRequest);
-          dataCacheHitTracker.updateTabletServer(server.name, server.lastContact, server.dataCacheHits);
-          dataCacheRequestTracker.updateTabletServer(server.name, server.lastContact, server.dataCacheRequest);
-        }
-        
-        lookupRateTracker.finishedUpdating();
-        indexCacheHitTracker.finishedUpdating();
-        indexCacheRequestTracker.finishedUpdating();
-        dataCacheHitTracker.finishedUpdating();
-        dataCacheRequestTracker.finishedUpdating();
-        
-        int totalTables = 0;
-        for (TableInfo tInfo : mmi.tableMap.values()) {
-          totalTabletCount += tInfo.tablets;
-          onlineTabletCount += tInfo.onlineTablets;
-          totalTables++;
-        }
-        Monitor.totalIngestRate = totalIngestRate;
-        Monitor.totalTables = totalTables;
-        totalIngestByteRate = totalIngestByteRate / 1000000.0;
-        Monitor.totalIngestByteRate = totalIngestByteRate;
-        Monitor.totalQueryRate = totalQueryRate;
-        Monitor.totalScanRate = totalScanRate;
-        totalQueryByteRate = totalQueryByteRate / 1000000.0;
-        Monitor.totalQueryByteRate = totalQueryByteRate;
-        Monitor.totalEntries = totalEntries;
-        Monitor.totalTabletCount = totalTabletCount;
-        Monitor.onlineTabletCount = onlineTabletCount;
-        Monitor.totalHoldTime = totalHoldTime;
-        Monitor.totalLookups = totalLookups;
-        
-        ingestRateOverTime.add(new Pair<Long,Double>(currentTime, totalIngestRate));
-        ingestByteRateOverTime.add(new Pair<Long,Double>(currentTime, totalIngestByteRate));
-        
-        double totalLoad = 0.;
-        for (TabletServerStatus status : mmi.tServerInfo) {
-          if (status != null)
-            totalLoad += status.osLoad;
-        }
-        loadOverTime.add(new Pair<Long,Double>(currentTime, totalLoad));
-        
-        minorCompactionsOverTime.add(new Pair<Long,Integer>(currentTime, minorCompactions));
-        majorCompactionsOverTime.add(new Pair<Long,Integer>(currentTime, majorCompactions));
-        
-        lookupsOverTime.add(new Pair<Long,Double>(currentTime, lookupRateTracker.calculateRate()));
-        
-        queryRateOverTime.add(new Pair<Long,Integer>(currentTime, (int) totalQueryRate));
-        queryByteRateOverTime.add(new Pair<Long,Double>(currentTime, totalQueryByteRate));
-        
-        scanRateOverTime.add(new Pair<Long,Integer>(currentTime, (int) totalScanRate));
-        
-        calcCacheHitRate(indexCacheHitRateOverTime, currentTime, indexCacheHitTracker, indexCacheRequestTracker);
-        calcCacheHitRate(dataCacheHitRateOverTime, currentTime, dataCacheHitTracker, dataCacheRequestTracker);
-      }
-      try {
-        Monitor.problemSummary = ProblemReports.getInstance().summarize();
-        Monitor.problemException = null;
-      } catch (Exception e) {
-        log.info("Failed to obtain problem reports ", e);
-        Monitor.problemSummary = Collections.emptyMap();
-        Monitor.problemException = e;
-      }
-      
-    } finally {
-      synchronized (Monitor.class) {
-        fetching = false;
-        lastRecalc = currentTime;
-      }
-    }
-  }
-  
-  private static void calcCacheHitRate(List<Pair<Long,Double>> hitRate, long currentTime, EventCounter cacheHits, EventCounter cacheReq) {
-    long req = cacheReq.calculateCount();
-    if (req > 0)
-      hitRate.add(new Pair<Long,Double>(currentTime, cacheHits.calculateCount() / (double) cacheReq.calculateCount()));
-    else
-      hitRate.add(new Pair<Long,Double>(currentTime, null));
-  }
-  
-  private static GCStatus fetchGcStatus() {
-    GCStatus result = null;
-    HostAndPort address = null;
-    try {
-      // Read the gc location from its lock
-      Instance instance = HdfsZooInstance.getInstance();
-      String zooKeepers = instance.getZooKeepers();
-      log.debug("connecting to zookeepers " + zooKeepers);
-      ZooKeeper zk = new ZooKeeper(zooKeepers, (int) config.getConfiguration().getTimeInMillis(Property.INSTANCE_ZK_TIMEOUT), new Watcher() {
-        @Override
-        public void process(WatchedEvent event) {}
-      });
-      try {
-        String path = ZooUtil.getRoot(HdfsZooInstance.getInstance()) + Constants.ZGC_LOCK;
-        List<String> locks = zk.getChildren(path, null);
-        if (locks != null && locks.size() > 0) {
-          Collections.sort(locks);
-          address = new ServerServices(new String(zk.getData(path + "/" + locks.get(0), null, null))).getAddress(Service.GC_CLIENT);
-          GCMonitorService.Client client = ThriftUtil.getClient(new GCMonitorService.Client.Factory(), address, config.getConfiguration());
-          try {
-            result = client.getStatus(Tracer.traceInfo(), SystemCredentials.get().toThrift(instance));
-          } finally {
-            ThriftUtil.returnClient(client);
-          }
-        }
-      } finally {
-        zk.close();
-      }
-    } catch (Exception ex) {
-      log.warn("Unable to contact the garbage collector at " + address, ex);
-    }
-    return result;
-  }
-  
-  public static void main(String[] args) throws Exception {
-    SecurityUtil.serverLogin();
-    
-    VolumeManager fs = VolumeManagerImpl.get();
-    ServerOpts opts = new ServerOpts();
-    opts.parseArgs("monitor", args);
-    String hostname = opts.getAddress();
-    instance = HdfsZooInstance.getInstance();
-    config = new ServerConfiguration(instance);
-    Accumulo.init(fs, config, "monitor");
-    Monitor monitor = new Monitor();
-    Accumulo.enableTracing(hostname, "monitor");
-    monitor.run(hostname);
-  }
-  
-  private static long START_TIME;
-  
-  public void run(String hostname) {
-    Monitor.START_TIME = System.currentTimeMillis();
-    int port = config.getConfiguration().getPort(Property.MONITOR_PORT);
-    try {
-      log.debug("Creating monitor on port " + port);
-      server = new EmbeddedWebServer(hostname, port);
-    } catch (Throwable ex) {
-      log.error("Unable to start embedded web server", ex);
-      throw new RuntimeException(ex);
-    }
-    
-    server.addServlet(DefaultServlet.class, "/");
-    server.addServlet(OperationServlet.class, "/op");
-    server.addServlet(MasterServlet.class, "/master");
-    server.addServlet(TablesServlet.class, "/tables");
-    server.addServlet(TServersServlet.class, "/tservers");
-    server.addServlet(ProblemServlet.class, "/problems");
-    server.addServlet(GcStatusServlet.class, "/gc");
-    server.addServlet(LogServlet.class, "/log");
-    server.addServlet(XMLServlet.class, "/xml");
-    server.addServlet(JSONServlet.class, "/json");
-    server.addServlet(VisServlet.class, "/vis");
-    server.addServlet(Summary.class, "/trace/summary");
-    server.addServlet(ListType.class, "/trace/listType");
-    server.addServlet(ShowTrace.class, "/trace/show");
-    if (server.isUsingSsl())
-      server.addServlet(ShellServlet.class, "/shell");
-    server.start();
-    
-    try {
-      String monitorAddress = HostAndPort.fromParts(hostname, server.getPort()).toString();
-      ZooReaderWriter.getInstance().putPersistentData(ZooUtil.getRoot(instance) + Constants.ZMONITOR, monitorAddress.getBytes(),
-          NodeExistsPolicy.OVERWRITE);
-      log.info("Set monitor address in zookeeper to " + monitorAddress);
-    } catch (Exception ex) {
-      log.error("Unable to set monitor address in zookeeper");
-    }
-    LogService.startLogListener(Monitor.getSystemConfiguration(), instance.getInstanceID());
-    
-    new Daemon(new LoggingRunnable(log, new ZooKeeperStatus()), "ZooKeeperStatus").start();
-    
-    // need to regularly fetch data so plot data is updated
-    new Daemon(new LoggingRunnable(log, new Runnable() {
-      
-      @Override
-      public void run() {
-        while (true) {
-          try {
-            Monitor.fetchData();
-          } catch (Exception e) {
-            log.warn(e.getMessage(), e);
-          }
-          
-          UtilWaitThread.sleep(333);
-        }
-        
-      }
-    }), "Data fetcher").start();
-  }
-  
-  public static MasterMonitorInfo getMmi() {
-    return mmi;
-  }
-  
-  public static int getTotalTables() {
-    return totalTables;
-  }
-  
-  public static int getTotalTabletCount() {
-    return totalTabletCount;
-  }
-  
-  public static int getOnlineTabletCount() {
-    return onlineTabletCount;
-  }
-  
-  public static long getTotalEntries() {
-    return totalEntries;
-  }
-  
-  public static double getTotalIngestRate() {
-    return totalIngestRate;
-  }
-  
-  public static double getTotalIngestByteRate() {
-    return totalIngestByteRate;
-  }
-  
-  public static double getTotalQueryRate() {
-    return totalQueryRate;
-  }
-  
-  public static double getTotalScanRate() {
-    return totalScanRate;
-  }
-  
-  public static double getTotalQueryByteRate() {
-    return totalQueryByteRate;
-  }
-  
-  public static long getTotalHoldTime() {
-    return totalHoldTime;
-  }
-  
-  public static Exception getProblemException() {
-    return problemException;
-  }
-  
-  public static Map<String,Map<ProblemType,Integer>> getProblemSummary() {
-    return problemSummary;
-  }
-  
-  public static GCStatus getGcStatus() {
-    return gcStatus;
-  }
-  
-  public static long getTotalLookups() {
-    return totalLookups;
-  }
-  
-  public static long getStartTime() {
-    return START_TIME;
-  }
-  
-  public static List<Pair<Long,Double>> getLoadOverTime() {
-    synchronized (loadOverTime) {
-      return new ArrayList<Pair<Long,Double>>(loadOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Double>> getIngestRateOverTime() {
-    synchronized (ingestRateOverTime) {
-      return new ArrayList<Pair<Long,Double>>(ingestRateOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Double>> getIngestByteRateOverTime() {
-    synchronized (ingestByteRateOverTime) {
-      return new ArrayList<Pair<Long,Double>>(ingestByteRateOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Integer>> getRecoveriesOverTime() {
-    synchronized (recoveriesOverTime) {
-      return new ArrayList<Pair<Long,Integer>>(recoveriesOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Integer>> getMinorCompactionsOverTime() {
-    synchronized (minorCompactionsOverTime) {
-      return new ArrayList<Pair<Long,Integer>>(minorCompactionsOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Integer>> getMajorCompactionsOverTime() {
-    synchronized (majorCompactionsOverTime) {
-      return new ArrayList<Pair<Long,Integer>>(majorCompactionsOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Double>> getLookupsOverTime() {
-    synchronized (lookupsOverTime) {
-      return new ArrayList<Pair<Long,Double>>(lookupsOverTime);
-    }
-  }
-  
-  public static double getLookupRate() {
-    return lookupRateTracker.calculateRate();
-  }
-  
-  public static List<Pair<Long,Integer>> getQueryRateOverTime() {
-    synchronized (queryRateOverTime) {
-      return new ArrayList<Pair<Long,Integer>>(queryRateOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Integer>> getScanRateOverTime() {
-    synchronized (scanRateOverTime) {
-      return new ArrayList<Pair<Long,Integer>>(scanRateOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Double>> getQueryByteRateOverTime() {
-    synchronized (queryByteRateOverTime) {
-      return new ArrayList<Pair<Long,Double>>(queryByteRateOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Double>> getIndexCacheHitRateOverTime() {
-    synchronized (indexCacheHitRateOverTime) {
-      return new ArrayList<Pair<Long,Double>>(indexCacheHitRateOverTime);
-    }
-  }
-  
-  public static List<Pair<Long,Double>> getDataCacheHitRateOverTime() {
-    synchronized (dataCacheHitRateOverTime) {
-      return new ArrayList<Pair<Long,Double>>(dataCacheHitRateOverTime);
-    }
-  }
-  
-  public static AccumuloConfiguration getSystemConfiguration() {
-    return config.getConfiguration();
-  }
-  
-  public static Instance getInstance() {
-    return instance;
-  }
-  
-  public static boolean isUsingSsl() {
-    return server.isUsingSsl();
-  }
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/monitor/ZooKeeperStatus.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/monitor/ZooKeeperStatus.java b/server/src/main/java/org/apache/accumulo/server/monitor/ZooKeeperStatus.java
deleted file mode 100644
index 2eff791..0000000
--- a/server/src/main/java/org/apache/accumulo/server/monitor/ZooKeeperStatus.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.server.monitor;
-
-import java.util.Collection;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.util.TTimeoutTransport;
-import org.apache.accumulo.core.util.UtilWaitThread;
-import org.apache.accumulo.server.conf.ServerConfiguration;
-import org.apache.log4j.Logger;
-import org.apache.thrift.transport.TTransport;
-import org.apache.thrift.transport.TTransportException;
-
-import com.google.common.net.HostAndPort;
-
-public class ZooKeeperStatus implements Runnable {
-  
-  private static final Logger log = Logger.getLogger(ZooKeeperStatus.class);
-  
-  private volatile boolean stop = false;
-  
-  public static class ZooKeeperState implements Comparable<ZooKeeperState> {
-    public final String keeper;
-    public final String mode;
-    public final int clients;
-    
-    public ZooKeeperState(String keeper, String mode, int clients) {
-      this.keeper = keeper;
-      this.mode = mode;
-      this.clients = clients;
-    }
-    
-    @Override
-    public int compareTo(ZooKeeperState other) {
-      if (this == other) {
-        return 0;
-      } else if (other == null) {
-        return 1;
-      } else {
-        if (this.keeper == other.keeper) {
-          return 0;
-        } else if (null == this.keeper) {
-          return -1;
-        } else if (null == other.keeper) {
-          return 1;
-        } else {
-          return this.keeper.compareTo(other.keeper);
-        }
-      }
-    }
-  }
-  
-  private static SortedSet<ZooKeeperState> status = new TreeSet<ZooKeeperState>();
-  
-  public static Collection<ZooKeeperState> getZooKeeperStatus() {
-    return status;
-  }
-  
-  public void stop() {
-    this.stop = true;
-  }
-  
-  @Override
-  public void run() {
-    
-    while (!stop) {
-      
-      TreeSet<ZooKeeperState> update = new TreeSet<ZooKeeperState>();
-      
-      String zookeepers[] = ServerConfiguration.getSiteConfiguration().get(Property.INSTANCE_ZK_HOST).split(",");
-      for (String keeper : zookeepers) {
-        int clients = 0;
-        String mode = "unknown";
-        
-        String[] parts = keeper.split(":");
-        TTransport transport = null;
-        try {
-          HostAndPort addr;
-          if (parts.length > 1)
-            addr = HostAndPort.fromParts(parts[0], Integer.parseInt(parts[1]));
-          else
-            addr = HostAndPort.fromParts(parts[0], 2181);
-          
-          transport = TTimeoutTransport.create(addr, 10 * 1000l);
-          transport.write("stat\n".getBytes(), 0, 5);
-          StringBuilder response = new StringBuilder();
-          try {
-            transport.flush();
-            byte[] buffer = new byte[1024 * 100];
-            int n = 0;
-            while ((n = transport.read(buffer, 0, buffer.length)) > 0) {
-              response.append(new String(buffer, 0, n));
-            }
-          } catch (TTransportException ex) {
-            // happens at EOF
-          }
-          for (String line : response.toString().split("\n")) {
-            if (line.startsWith(" "))
-              clients++;
-            if (line.startsWith("Mode"))
-              mode = line.split(":")[1];
-          }
-          update.add(new ZooKeeperState(keeper, mode, clients));
-        } catch (Exception ex) {
-          log.info("Exception talking to zookeeper " + keeper, ex);
-          update.add(new ZooKeeperState(keeper, "Down", -1));
-        } finally {
-          if (transport != null) {
-            try {
-              transport.close();
-            } catch (Exception ex) {
-              log.error(ex, ex);
-            }
-          }
-        }
-      }
-      status = update;
-      UtilWaitThread.sleep(1000);
-    }
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/598821cd/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java b/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java
deleted file mode 100644
index 81bfa4c..0000000
--- a/server/src/main/java/org/apache/accumulo/server/monitor/servlets/BasicServlet.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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.server.monitor.servlets;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.Date;
-import java.util.List;
-import java.util.TimerTask;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.accumulo.core.Constants;
-import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.server.client.HdfsZooInstance;
-import org.apache.accumulo.server.monitor.DedupedLogEvent;
-import org.apache.accumulo.server.monitor.LogService;
-import org.apache.accumulo.server.monitor.Monitor;
-import org.apache.accumulo.server.util.time.SimpleTimer;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-
-abstract public class BasicServlet extends HttpServlet {
-  
-  private static final long serialVersionUID = 1L;
-  protected static final Logger log = Logger.getLogger(BasicServlet.class);
-  static String cachedInstanceName = null;
-  private static String bannerText;
-  private static String bannerColor;
-  private static String bannerBackground;
-  
-  abstract protected String getTitle(HttpServletRequest req);
-  
-  @Override
-  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-    StringBuilder sb = new StringBuilder();
-    try {
-      Monitor.fetchData();
-      bannerText = sanitize(Monitor.getSystemConfiguration().get(Property.MONITOR_BANNER_TEXT));
-      bannerColor = Monitor.getSystemConfiguration().get(Property.MONITOR_BANNER_COLOR).replace("'", "&#39;");
-      bannerBackground = Monitor.getSystemConfiguration().get(Property.MONITOR_BANNER_BACKGROUND).replace("'", "&#39;");
-      pageStart(req, resp, sb);
-      pageBody(req, resp, sb);
-      pageEnd(req, resp, sb);
-    } catch (Throwable t) {
-      log.error("Error building page " + req.getRequestURI(), t);
-      sb.append("\n<pre>\n");
-      StringWriter sw = new StringWriter();
-      t.printStackTrace(new PrintWriter(sw));
-      sb.append(sanitize(sw.getBuffer().toString()));
-      sb.append("</pre>\n");
-    } finally {
-      resp.getWriter().print(sb);
-      resp.getWriter().flush();
-    }
-  }
-  
-  @Override
-  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-    doGet(req, resp);
-  }
-  
-  private static final String DEFAULT_CONTENT_TYPE = "text/html";
-  
-  public static final Cookie getCookie(HttpServletRequest req, String name) {
-    if (req.getCookies() != null)
-      for (Cookie c : req.getCookies())
-        if (c.getName().equals(name))
-          return c;
-    return null;
-  }
-  
-  protected void pageStart(HttpServletRequest req, HttpServletResponse resp, StringBuilder sb) throws Exception {
-    resp.setContentType(DEFAULT_CONTENT_TYPE);
-    int refresh = -1;
-    Cookie c = getCookie(req, "page.refresh.rate");
-    if (c != null && c.getValue() != null) {
-      try {
-        refresh = Integer.parseInt(c.getValue());
-      } catch (NumberFormatException e) {
-        // ignore improperly formatted user cookie
-      }
-    }
-    synchronized (BasicServlet.class) {
-      // Learn our instance name asynchronously so we don't hang up if zookeeper is down
-      if (cachedInstanceName == null) {
-        SimpleTimer.getInstance().schedule(new TimerTask() {
-          @Override
-          public void run() {
-            synchronized (BasicServlet.class) {
-              if (cachedInstanceName == null) {
-                cachedInstanceName = HdfsZooInstance.getInstance().getInstanceName();
-              }
-            }
-          }
-        }, 1000);
-      }
-    }
-    
-    // BEGIN PAGE
-    sb.append("<!--\n");
-    sb.append("  Licensed to the Apache Software Foundation (ASF) under one or more\n");
-    sb.append("  contributor license agreements.  See the NOTICE file distributed with\n");
-    sb.append("  this work for additional information regarding copyright ownership.\n");
-    sb.append("  The ASF licenses this file to You under the Apache License, Version 2.0\n");
-    sb.append("  (the \"License\"); you may not use this file except in compliance with\n");
-    sb.append("  the License.  You may obtain a copy of the License at\n");
-    sb.append("\n");
-    sb.append("    http://www.apache.org/licenses/LICENSE-2.0\n");
-    sb.append("\n");
-    sb.append("  Unless required by applicable law or agreed to in writing, software\n");
-    sb.append("  distributed under the License is distributed on an \"AS IS\" BASIS,\n");
-    sb.append("  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n");
-    sb.append("  See the License for the specific language governing permissions and\n");
-    sb.append("  limitations under the License.\n");
-    sb.append("-->\n");
-    sb.append("<html>\n");
-    
-    // BEGIN HEADER
-    sb.append("<head>\n");
-    sb.append("<title>").append(getTitle(req)).append(" - Accumulo ").append(Constants.VERSION).append("</title>\n");
-    if ((refresh > 0) && (req.getRequestURI().startsWith("/docs") == false) && (req.getRequestURI().startsWith("/vis") == false)
-        && (req.getRequestURI().startsWith("/shell") == false))
-      sb.append("<meta http-equiv='refresh' content='" + refresh + "' />\n");
-    sb.append("<meta http-equiv='Content-Type' content='").append(DEFAULT_CONTENT_TYPE).append("' />\n");
-    sb.append("<meta http-equiv='Content-Script-Type' content='text/javascript' />\n");
-    sb.append("<meta http-equiv='Content-Style-Type' content='text/css' />\n");
-    sb.append("<link rel='shortcut icon' type='image/jpg' href='/web/favicon.png' />\n");
-    sb.append("<link rel='stylesheet' type='text/css' href='/web/screen.css' media='screen' />\n");
-    sb.append("<script src='/web/functions.js' type='text/javascript'></script>\n");
-    
-    sb.append("<!--[if lte IE 8]><script language=\"javascript\" type=\"text/javascript\" src=\"/web/flot/excanvas.min.js\"></script><![endif]-->\n");
-    sb.append("<script language=\"javascript\" type=\"text/javascript\" src=\"/web/flot/jquery.js\"></script>\n");
-    sb.append("<script language=\"javascript\" type=\"text/javascript\" src=\"/web/flot/jquery.flot.js\"></script>\n");
-    
-    sb.append("</head>\n");
-    
-    // BEGIN BODY OPENING
-    sb.append("\n<body ").append(getBodyAttributes()).append(">\n");
-    sb.append("<div id='content-wrapper'>\n");
-    sb.append("<div id='content'>\n");
-    sb.append("<div id='header'>");
-    if (!bannerText.isEmpty()) {
-      sb.append("<div id='banner' style='color:").append(bannerColor).append(";background:").append(bannerBackground).append("'>").append(bannerText)
-          .append("</div>\n");
-    }
-    sb.append("<div id='headertitle'>");
-    sb.append("<h1>").append(getTitle(req)).append("</h1></div>\n");
-    sb.append("<div id='subheader'>Instance&nbsp;Name:&nbsp;").append(cachedInstanceName).append("&nbsp;&nbsp;&nbsp;Version:&nbsp;").append(Constants.VERSION)
-        .append("\n");
-    sb.append("<br><span class='smalltext'>Instance&nbsp;ID:&nbsp;").append(HdfsZooInstance.getInstance().getInstanceID()).append("</span>\n");
-    sb.append("<br><span class='smalltext'>").append(new Date().toString().replace(" ", "&nbsp;")).append("</span>");
-    sb.append("</div>\n"); // end <div id='subheader'>
-    sb.append("</div>\n"); // end <div id='header'>
-    
-    // BEGIN LEFT SIDE
-    sb.append("<div id='nav'>\n");
-    sb.append("<span id='nav-title'><a href='/'>Overview</a></span><br />\n");
-    sb.append("<hr />\n");
-    sb.append("<a href='/master'>Master&nbsp;Server</a><br />\n");
-    sb.append("<a href='/tservers'>Tablet&nbsp;Servers</a><br />\n");
-    sb.append("<a href='/vis'>Server Activity</a><br />\n");
-    sb.append("<a href='/gc'>Garbage&nbsp;Collector</a><br />\n");
-    sb.append("<a href='/tables'>Tables</a><br />\n");
-    sb.append("<a href='/trace/summary?minutes=10'>Recent&nbsp;Traces</a><br />\n");
-    sb.append("<a href='/docs'>Documentation</a><br />\n");
-    List<DedupedLogEvent> dedupedLogEvents = LogService.getInstance().getEvents();
-    int numLogs = dedupedLogEvents.size();
-    boolean logsHaveError = false;
-    for (DedupedLogEvent dedupedLogEvent : dedupedLogEvents)
-      if (dedupedLogEvent.getEvent().getLevel().isGreaterOrEqual(Level.ERROR)) {
-        logsHaveError = true;
-        break;
-      }
-    if (numLogs > 0)
-      sb.append("<span class='" + (logsHaveError ? "error" : "warning") + "'><a href='/log'>Recent&nbsp;Logs&nbsp;<span class='smalltext'>(" + numLogs + ")</a></span></span><br />\n");
-    int numProblems = Monitor.getProblemSummary().entrySet().size();
-    if (numProblems > 0)
-      sb.append("<span class='error'><a href='/problems'>Table&nbsp;Problems&nbsp;<span class='smalltext'>(" + numProblems + ")</a></span></span><br />\n");
-    sb.append("<hr />\n");
-    sb.append("<a href='/xml'>XML</a><br />\n");
-    sb.append("<a href='/json'>JSON</a><hr />\n");
-    if (Monitor.isUsingSsl())
-      sb.append("<a href='/shell'>Shell</a><hr />\n");
-    sb.append("<div class='smalltext'>[<a href='").append("/op?action=refresh&value=").append(refresh < 1 ? "5" : "-1");
-    sb.append("&redir=").append(currentPage(req)).append("'>");
-    sb.append(refresh < 1 ? "en" : "dis").append("able&nbsp;auto-refresh</a>]</div>\n");
-    sb.append("</div>\n"); // end <div id='nav'>
-    
-    sb.append("<div id='main'");
-    if (bannerText.isEmpty())
-      sb.append(" style='bottom:0'");
-    sb.append(">\n");
-    sb.append("<!-- BEGIN MAIN BODY CONTENT -->\n\n");
-  }
-  
-  protected void pageBody(HttpServletRequest req, HttpServletResponse resp, StringBuilder sb) throws Exception {
-    sb.append("This page intentionally left blank.");
-  }
-  
-  protected void pageEnd(HttpServletRequest req, HttpServletResponse resp, StringBuilder sb) throws Exception {
-    sb.append("\n<!-- END MAIN BODY CONTENT -->\n");
-    sb.append("</div>\n"); // end <div id='main'>
-    
-    // BEGIN FOOTER
-    sb.append("</div>\n"); // end <div id='content'>
-    sb.append("</div>\n"); // end <div id='content-wrapper'>
-    if (!bannerText.isEmpty()) {
-      sb.append("<div id='footer' style='color:").append(bannerColor).append(";background:").append(bannerBackground).append("'>").append(bannerText)
-          .append("</div>\n");
-    }
-    sb.append("</body>\n");
-    sb.append("</html>\n");
-  }
-  
-  /**
-   * Allow the concrete servlet implementation to provide attributes on the body HTML tag, such as 'onload', which can be used to call Javascript methods on
-   * page load. By default, nothing is specified.
-   */
-  protected String getBodyAttributes() {
-    return "";
-  }
-  
-  public static String encode(String s) {
-    try {
-      return URLEncoder.encode(s, Constants.UTF8.name());
-    } catch (UnsupportedEncodingException e) {
-      Logger.getLogger(BasicServlet.class).fatal(Constants.UTF8.name() + " is not a recognized encoding", e);
-      throw new RuntimeException(e);
-    }
-  }
-  
-  public static String decode(String s) {
-    try {
-      return URLDecoder.decode(s, Constants.UTF8.name());
-    } catch (UnsupportedEncodingException e) {
-      Logger.getLogger(BasicServlet.class).fatal(Constants.UTF8.name() + " is not a recognized encoding", e);
-      throw new RuntimeException(e);
-    }
-  }
-  
-  public static String sanitize(String xml) {
-    return xml.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
-  }
-  
-  public static String currentPage(HttpServletRequest req) {
-    String redir = req.getRequestURI();
-    if (req.getQueryString() != null)
-      redir += "?" + req.getQueryString();
-    return encode(redir);
-  }
-  
-  protected static void banner(StringBuilder sb, String klass, String text) {
-    sb.append("<br />\n<h2 class='").append(klass).append("'>").append(text).append("</h2>\n");
-  }
-  
-}