You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by om...@apache.org on 2011/03/15 17:23:20 UTC

svn commit: r1081836 [2/3] - in /hadoop/common/branches/branch-0.20-security: ./ src/core/org/apache/hadoop/classification/ src/core/org/apache/hadoop/log/ src/core/org/apache/hadoop/log/metrics/ src/core/org/apache/hadoop/metrics/ src/core/org/apache/...

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/jvm/JvmMetrics.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/jvm/JvmMetrics.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/jvm/JvmMetrics.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/jvm/JvmMetrics.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,201 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.metrics.jvm;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.metrics.MetricsContext;
+import org.apache.hadoop.metrics.MetricsRecord;
+import org.apache.hadoop.metrics.MetricsUtil;
+import org.apache.hadoop.metrics.Updater;
+
+import static java.lang.Thread.State.*;
+import java.lang.management.GarbageCollectorMXBean;
+import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Singleton class which reports Java Virtual Machine metrics to the metrics API.  
+ * Any application can create an instance of this class in order to emit
+ * Java VM metrics.  
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Private
+@InterfaceStability.Evolving
+public class JvmMetrics implements Updater {
+    
+    private static final float M = 1024*1024;
+    private static JvmMetrics theInstance = null;
+    private static Log log = LogFactory.getLog(JvmMetrics.class);
+    
+    private MetricsRecord metrics;
+    
+    // garbage collection counters
+    private long gcCount = 0;
+    private long gcTimeMillis = 0;
+    
+    // logging event counters
+    private long fatalCount = 0;
+    private long errorCount = 0;
+    private long warnCount  = 0;
+    private long infoCount  = 0;
+    
+    public synchronized static JvmMetrics init(String processName, String sessionId) {
+      return init(processName, sessionId, "metrics");
+    }
+    
+    public synchronized static JvmMetrics init(String processName, String sessionId,
+      String recordName) {
+        if (theInstance != null) {
+            log.info("Cannot initialize JVM Metrics with processName=" + 
+                     processName + ", sessionId=" + sessionId + 
+                     " - already initialized");
+        }
+        else {
+            log.info("Initializing JVM Metrics with processName=" 
+                    + processName + ", sessionId=" + sessionId);
+            theInstance = new JvmMetrics(processName, sessionId, recordName);
+        }
+        return theInstance;
+    }
+    
+    /** Creates a new instance of JvmMetrics */
+    private JvmMetrics(String processName, String sessionId,
+      String recordName) {
+        MetricsContext context = MetricsUtil.getContext("jvm");
+        metrics = MetricsUtil.createRecord(context, recordName);
+        metrics.setTag("processName", processName);
+        metrics.setTag("sessionId", sessionId);
+        context.registerUpdater(this);
+    }
+    
+    /**
+     * This will be called periodically (with the period being configuration
+     * dependent).
+     */
+    public void doUpdates(MetricsContext context) {
+        doMemoryUpdates();
+        doGarbageCollectionUpdates();
+        doThreadUpdates();
+        doEventCountUpdates();
+        metrics.update();
+    }
+    
+    private void doMemoryUpdates() {
+        MemoryMXBean memoryMXBean =
+               ManagementFactory.getMemoryMXBean();
+        MemoryUsage memNonHeap =
+                memoryMXBean.getNonHeapMemoryUsage();
+        MemoryUsage memHeap =
+                memoryMXBean.getHeapMemoryUsage();
+        Runtime runtime = Runtime.getRuntime();
+
+        metrics.setMetric("memNonHeapUsedM", memNonHeap.getUsed()/M);
+        metrics.setMetric("memNonHeapCommittedM", memNonHeap.getCommitted()/M);
+        metrics.setMetric("memHeapUsedM", memHeap.getUsed()/M);
+        metrics.setMetric("memHeapCommittedM", memHeap.getCommitted()/M);
+        metrics.setMetric("maxMemoryM", runtime.maxMemory()/M);
+    }
+    
+    private void doGarbageCollectionUpdates() {
+        List<GarbageCollectorMXBean> gcBeans =
+                ManagementFactory.getGarbageCollectorMXBeans();
+        long count = 0;
+        long timeMillis = 0;
+        for (GarbageCollectorMXBean gcBean : gcBeans) {
+            count += gcBean.getCollectionCount();
+            timeMillis += gcBean.getCollectionTime();
+        }
+        metrics.incrMetric("gcCount", (int)(count - gcCount));
+        metrics.incrMetric("gcTimeMillis", (int)(timeMillis - gcTimeMillis));
+        
+        gcCount = count;
+        gcTimeMillis = timeMillis;
+    }
+    
+    private void doThreadUpdates() {
+        ThreadMXBean threadMXBean =
+                ManagementFactory.getThreadMXBean();
+        long threadIds[] = 
+                threadMXBean.getAllThreadIds();
+        ThreadInfo[] threadInfos =
+                threadMXBean.getThreadInfo(threadIds, 0);
+        
+        int threadsNew = 0;
+        int threadsRunnable = 0;
+        int threadsBlocked = 0;
+        int threadsWaiting = 0;
+        int threadsTimedWaiting = 0;
+        int threadsTerminated = 0;
+        
+        for (ThreadInfo threadInfo : threadInfos) {
+            // threadInfo is null if the thread is not alive or doesn't exist
+            if (threadInfo == null) continue;
+            Thread.State state = threadInfo.getThreadState();
+            if (state == NEW) {
+                threadsNew++;
+            } 
+            else if (state == RUNNABLE) {
+                threadsRunnable++;
+            }
+            else if (state == BLOCKED) {
+                threadsBlocked++;
+            }
+            else if (state == WAITING) {
+                threadsWaiting++;
+            } 
+            else if (state == TIMED_WAITING) {
+                threadsTimedWaiting++;
+            }
+            else if (state == TERMINATED) {
+                threadsTerminated++;
+            }
+        }
+        metrics.setMetric("threadsNew", threadsNew);
+        metrics.setMetric("threadsRunnable", threadsRunnable);
+        metrics.setMetric("threadsBlocked", threadsBlocked);
+        metrics.setMetric("threadsWaiting", threadsWaiting);
+        metrics.setMetric("threadsTimedWaiting", threadsTimedWaiting);
+        metrics.setMetric("threadsTerminated", threadsTerminated);
+    }
+    
+    private void doEventCountUpdates() {
+        long newFatal = EventCounter.getFatal();
+        long newError = EventCounter.getError();
+        long newWarn  = EventCounter.getWarn();
+        long newInfo  = EventCounter.getInfo();
+        
+        metrics.incrMetric("logFatal", (int)(newFatal - fatalCount));
+        metrics.incrMetric("logError", (int)(newError - errorCount));
+        metrics.incrMetric("logWarn",  (int)(newWarn - warnCount));
+        metrics.incrMetric("logInfo",  (int)(newInfo - infoCount));
+        
+        fatalCount = newFatal;
+        errorCount = newError;
+        warnCount  = newWarn;
+        infoCount  = newInfo;
+    }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/package.html
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/package.html?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/package.html (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/package.html Tue Mar 15 16:23:19 2011
@@ -0,0 +1,160 @@
+<html>
+
+<!--
+   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.
+-->
+
+  <head>
+    <title>org.apache.hadoop.metrics</title>
+  </head>
+<body>
+  <p><em>Note, this package is deprecated in favor of
+    <code>org.apache.hadoop.metrics2</code> usage.</em></p>
+  <p>This package defines an API for reporting performance metric information.</p>
+  <p>The API is abstract so that it can be implemented on top of
+a variety of metrics client libraries.  The choice of 
+client library is a configuration option, and different 
+modules within the same application can use
+different metrics implementation libraries.</p>
+<p/>
+Sub-packages:
+<dl>
+    <dt><code>org.apache.hadoop.metrics.spi</code></dt>
+    <dd>The abstract Server Provider Interface package. Those wishing to
+    integrate the metrics API with a particular metrics client library should 
+    extend this package.</dd>
+    
+    <dt><code>org.apache.hadoop.metrics.file</code></dt>
+    <dd>An implementation package which writes the metric data to 
+    a file, or sends it to the standard output stream.</dd>
+ 
+    <dt> <code>org.apache.hadoop.metrics.ganglia</code></dt>
+    <dd>An implementation package which sends metric data to 
+    <a href="http://ganglia.sourceforge.net/">Ganglia</a>.</dd>
+</dl>
+
+<h3>Introduction to the Metrics API</h3>
+
+Here is a simple example of how to use this package to report a single
+metric value:
+<pre>
+    private ContextFactory contextFactory = ContextFactory.getFactory();
+    
+    void reportMyMetric(float myMetric) {
+        MetricsContext myContext = contextFactory.getContext("myContext");
+        MetricsRecord myRecord = myContext.getRecord("myRecord");
+        myRecord.setMetric("myMetric", myMetric);
+        myRecord.update();
+    }
+</pre>
+  
+In this example there are three names:
+<dl>
+  <dt><i>myContext</i></dt>
+  <dd>The context name will typically identify either the application, or else a
+  module within an application or library.</dd>
+  
+  <dt><i>myRecord</i></dt>
+  <dd>The record name generally identifies some entity for which a set of
+  metrics are to be reported.  For example, you could have a record named 
+  "cacheStats" for reporting a number of statistics relating to the usage of
+  some cache in your application.</dd>
+  
+  <dt><i>myMetric</i></dt>
+  <dd>This identifies a particular metric.  For example, you might have metrics
+  named "cache_hits" and "cache_misses".
+  </dd>
+</dl>
+
+<h3>Tags</h3>
+
+In some cases it is useful to have multiple records with the same name. For 
+example, suppose that you want to report statistics about each disk on a computer. 
+In this case, the record name would be something like "diskStats", but you also
+need to identify the disk which is done by adding a <i>tag</i> to the record.
+The code could look something like this:
+<pre>
+    private MetricsRecord diskStats =
+            contextFactory.getContext("myContext").getRecord("diskStats");
+            
+    void reportDiskMetrics(String diskName, float diskBusy, float diskUsed) {
+        diskStats.setTag("diskName", diskName);
+        diskStats.setMetric("diskBusy", diskBusy);
+        diskStats.setMetric("diskUsed", diskUsed);
+        diskStats.update();
+    }
+</pre>
+
+<h3>Buffering and Callbacks</h3>
+
+Data is not sent immediately to the metrics system when 
+<code>MetricsRecord.update()</code> is called. Instead it is stored in an
+internal table, and the contents of the table are sent periodically.
+This can be important for two reasons:
+<ol>
+    <li>It means that a programmer is free to put calls to this API in an 
+    inner loop, since updates can be very frequent without slowing down
+    the application significantly.</li>
+    <li>Some implementations can gain efficiency by combining many metrics 
+    into a single UDP message.</li>
+</ol>
+
+The API provides a timer-based callback via the 
+<code>registerUpdater()</code> method.  The benefit of this
+versus using <code>java.util.Timer</code> is that the callbacks will be done 
+immediately before sending the data, making the data as current as possible.
+
+<h3>Configuration</h3>
+
+It is possible to programmatically examine and modify configuration data
+before creating a context, like this:
+<pre>
+    ContextFactory factory = ContextFactory.getFactory();
+    ... examine and/or modify factory attributes ...
+    MetricsContext context = factory.getContext("myContext");
+</pre>
+The factory attributes can be examined and modified using the following
+<code>ContextFactory</code>methods:
+<ul>
+    <li><code>Object getAttribute(String attributeName)</code></li>
+    <li><code>String[] getAttributeNames()</code></li>
+    <li><code>void setAttribute(String name, Object value)</code></li>
+    <li><code>void removeAttribute(attributeName)</code></li>
+</ul>
+
+<p/>
+<code>ContextFactory.getFactory()</code> initializes the factory attributes by
+reading the properties file <code>hadoop-metrics.properties</code> if it exists 
+on the class path.
+
+<p/>
+A factory attribute named:
+<pre>
+<i>contextName</i>.class
+</pre>
+should have as its value the fully qualified name of the class to be 
+instantiated by a call of the <code>CodeFactory</code> method
+<code>getContext(<i>contextName</i>)</code>.  If this factory attribute is not 
+specified, the default is to instantiate 
+<code>org.apache.hadoop.metrics.file.FileContext</code>.
+
+<p/>
+Other factory attributes are specific to a particular implementation of this 
+API and are documented elsewhere.  For example, configuration attributes for
+the file and Ganglia implementations can be found in the javadoc for 
+their respective packages.
+</body>
+</html>

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/AbstractMetricsContext.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/AbstractMetricsContext.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/AbstractMetricsContext.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/AbstractMetricsContext.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,483 @@
+/*
+ * AbstractMetricsContext.java
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.metrics.spi;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.metrics.ContextFactory;
+import org.apache.hadoop.metrics.MetricsContext;
+import org.apache.hadoop.metrics.MetricsException;
+import org.apache.hadoop.metrics.MetricsRecord;
+import org.apache.hadoop.metrics.Updater;
+
+/**
+ * The main class of the Service Provider Interface.  This class should be
+ * extended in order to integrate the Metrics API with a specific metrics
+ * client library. <p/>
+ *
+ * This class implements the internal table of metric data, and the timer
+ * on which data is to be sent to the metrics system.  Subclasses must
+ * override the abstract <code>emitRecord</code> method in order to transmit
+ * the data. <p/>
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public abstract class AbstractMetricsContext implements MetricsContext {
+    
+  private int period = MetricsContext.DEFAULT_PERIOD;
+  private Timer timer = null;
+    
+  private Set<Updater> updaters = new HashSet<Updater>(1);
+  private volatile boolean isMonitoring = false;
+    
+  private ContextFactory factory = null;
+  private String contextName = null;
+    
+  @InterfaceAudience.Private
+  public static class TagMap extends TreeMap<String,Object> {
+    private static final long serialVersionUID = 3546309335061952993L;
+    TagMap() {
+      super();
+    }
+    TagMap(TagMap orig) {
+      super(orig);
+    }
+    /**
+     * Returns true if this tagmap contains every tag in other.
+     */
+    public boolean containsAll(TagMap other) {
+      for (Map.Entry<String,Object> entry : other.entrySet()) {
+        Object value = get(entry.getKey());
+        if (value == null || !value.equals(entry.getValue())) {
+          // either key does not exist here, or the value is different
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+  
+  @InterfaceAudience.Private
+  public static class MetricMap extends TreeMap<String,Number> {
+    private static final long serialVersionUID = -7495051861141631609L;
+    MetricMap() {
+      super();
+    }
+    MetricMap(MetricMap orig) {
+      super(orig);
+    }
+  }
+            
+  static class RecordMap extends HashMap<TagMap,MetricMap> {
+    private static final long serialVersionUID = 259835619700264611L;
+  }
+    
+  private Map<String,RecordMap> bufferedData = new HashMap<String,RecordMap>();
+    
+
+  /**
+   * Creates a new instance of AbstractMetricsContext
+   */
+  protected AbstractMetricsContext() {
+  }
+    
+  /**
+   * Initializes the context.
+   */
+  public void init(String contextName, ContextFactory factory) 
+  {
+    this.contextName = contextName;
+    this.factory = factory;
+  }
+    
+  /**
+   * Convenience method for subclasses to access factory attributes.
+   */
+  protected String getAttribute(String attributeName) {
+    String factoryAttribute = contextName + "." + attributeName;
+    return (String) factory.getAttribute(factoryAttribute);  
+  }
+    
+  /**
+   * Returns an attribute-value map derived from the factory attributes
+   * by finding all factory attributes that begin with 
+   * <i>contextName</i>.<i>tableName</i>.  The returned map consists of
+   * those attributes with the contextName and tableName stripped off.
+   */
+  protected Map<String,String> getAttributeTable(String tableName) {
+    String prefix = contextName + "." + tableName + ".";
+    Map<String,String> result = new HashMap<String,String>();
+    for (String attributeName : factory.getAttributeNames()) {
+      if (attributeName.startsWith(prefix)) {
+        String name = attributeName.substring(prefix.length());
+        String value = (String) factory.getAttribute(attributeName);
+        result.put(name, value);
+      }
+    }
+    return result;
+  }
+    
+  /**
+   * Returns the context name.
+   */
+  public String getContextName() {
+    return contextName;
+  }
+    
+  /**
+   * Returns the factory by which this context was created.
+   */
+  public ContextFactory getContextFactory() {
+    return factory;
+  }
+    
+  /**
+   * Starts or restarts monitoring, the emitting of metrics records.
+   */
+  public synchronized void startMonitoring()
+    throws IOException {
+    if (!isMonitoring) {
+      startTimer();
+      isMonitoring = true;
+    }
+  }
+    
+  /**
+   * Stops monitoring.  This does not free buffered data. 
+   * @see #close()
+   */
+  public synchronized void stopMonitoring() {
+    if (isMonitoring) {
+      stopTimer();
+      isMonitoring = false;
+    }
+  }
+    
+  /**
+   * Returns true if monitoring is currently in progress.
+   */
+  public boolean isMonitoring() {
+    return isMonitoring;
+  }
+    
+  /**
+   * Stops monitoring and frees buffered data, returning this
+   * object to its initial state.  
+   */
+  public synchronized void close() {
+    stopMonitoring();
+    clearUpdaters();
+  } 
+    
+  /**
+   * Creates a new AbstractMetricsRecord instance with the given <code>recordName</code>.
+   * Throws an exception if the metrics implementation is configured with a fixed
+   * set of record names and <code>recordName</code> is not in that set.
+   * 
+   * @param recordName the name of the record
+   * @throws MetricsException if recordName conflicts with configuration data
+   */
+  public final synchronized MetricsRecord createRecord(String recordName) {
+    if (bufferedData.get(recordName) == null) {
+      bufferedData.put(recordName, new RecordMap());
+    }
+    return newRecord(recordName);
+  }
+    
+  /**
+   * Subclasses should override this if they subclass MetricsRecordImpl.
+   * @param recordName the name of the record
+   * @return newly created instance of MetricsRecordImpl or subclass
+   */
+  protected MetricsRecord newRecord(String recordName) {
+    return new MetricsRecordImpl(recordName, this);
+  }
+    
+  /**
+   * Registers a callback to be called at time intervals determined by
+   * the configuration.
+   *
+   * @param updater object to be run periodically; it should update
+   * some metrics records 
+   */
+  public synchronized void registerUpdater(final Updater updater) {
+    if (!updaters.contains(updater)) {
+      updaters.add(updater);
+    }
+  }
+    
+  /**
+   * Removes a callback, if it exists.
+   *
+   * @param updater object to be removed from the callback list
+   */
+  public synchronized void unregisterUpdater(Updater updater) {
+    updaters.remove(updater);
+  }
+    
+  private synchronized void clearUpdaters() {
+    updaters.clear();
+  }
+    
+  /**
+   * Starts timer if it is not already started
+   */
+  private synchronized void startTimer() {
+    if (timer == null) {
+      timer = new Timer("Timer thread for monitoring " + getContextName(), 
+                        true);
+      TimerTask task = new TimerTask() {
+          public void run() {
+            try {
+              timerEvent();
+            }
+            catch (IOException ioe) {
+              ioe.printStackTrace();
+            }
+          }
+        };
+      long millis = period * 1000;
+      timer.scheduleAtFixedRate(task, millis, millis);
+    }
+  }
+    
+  /**
+   * Stops timer if it is running
+   */
+  private synchronized void stopTimer() {
+    if (timer != null) {
+      timer.cancel();
+      timer = null;
+    }
+  }
+    
+  /**
+   * Timer callback.
+   */
+  private void timerEvent() throws IOException {
+    if (isMonitoring) {
+      Collection<Updater> myUpdaters;
+      synchronized (this) {
+        myUpdaters = new ArrayList<Updater>(updaters);
+      }     
+      // Run all the registered updates without holding a lock
+      // on this context
+      for (Updater updater : myUpdaters) {
+        try {
+          updater.doUpdates(this);
+        }
+        catch (Throwable throwable) {
+          throwable.printStackTrace();
+        }
+      }
+      emitRecords();
+    }
+  }
+    
+  /**
+   *  Emits the records.
+   */
+  private synchronized void emitRecords() throws IOException {
+    for (String recordName : bufferedData.keySet()) {
+      RecordMap recordMap = bufferedData.get(recordName);
+      synchronized (recordMap) {
+        Set<Entry<TagMap, MetricMap>> entrySet = recordMap.entrySet ();
+        for (Entry<TagMap, MetricMap> entry : entrySet) {
+          OutputRecord outRec = new OutputRecord(entry.getKey(), entry.getValue());
+          emitRecord(contextName, recordName, outRec);
+        }
+      }
+    }
+    flush();
+  }
+  
+  /**
+   * Retrieves all the records managed by this MetricsContext.
+   * Useful for monitoring systems that are polling-based.
+   * @return A non-null collection of all monitoring records.
+   */
+  public synchronized Map<String, Collection<OutputRecord>> getAllRecords() {
+    Map<String, Collection<OutputRecord>> out = new TreeMap<String, Collection<OutputRecord>>();
+    for (String recordName : bufferedData.keySet()) {
+      RecordMap recordMap = bufferedData.get(recordName);
+      synchronized (recordMap) {
+        List<OutputRecord> records = new ArrayList<OutputRecord>();
+        Set<Entry<TagMap, MetricMap>> entrySet = recordMap.entrySet();
+        for (Entry<TagMap, MetricMap> entry : entrySet) {
+          OutputRecord outRec = new OutputRecord(entry.getKey(), entry.getValue());
+          records.add(outRec);
+        }
+        out.put(recordName, records);
+      }
+    }
+    return out;
+  }
+
+  /**
+   * Sends a record to the metrics system.
+   */
+  protected abstract void emitRecord(String contextName, String recordName, 
+                                     OutputRecord outRec) throws IOException;
+    
+  /**
+   * Called each period after all records have been emitted, this method does nothing.
+   * Subclasses may override it in order to perform some kind of flush.
+   */
+  protected void flush() throws IOException {
+  }
+    
+  /**
+   * Called by MetricsRecordImpl.update().  Creates or updates a row in
+   * the internal table of metric data.
+   */
+  protected void update(MetricsRecordImpl record) {
+    String recordName = record.getRecordName();
+    TagMap tagTable = record.getTagTable();
+    Map<String,MetricValue> metricUpdates = record.getMetricTable();
+        
+    RecordMap recordMap = getRecordMap(recordName);
+    synchronized (recordMap) {
+      MetricMap metricMap = recordMap.get(tagTable);
+      if (metricMap == null) {
+        metricMap = new MetricMap();
+        TagMap tagMap = new TagMap(tagTable); // clone tags
+        recordMap.put(tagMap, metricMap);
+      }
+
+      Set<Entry<String, MetricValue>> entrySet = metricUpdates.entrySet();
+      for (Entry<String, MetricValue> entry : entrySet) {
+        String metricName = entry.getKey ();
+        MetricValue updateValue = entry.getValue ();
+        Number updateNumber = updateValue.getNumber();
+        Number currentNumber = metricMap.get(metricName);
+        if (currentNumber == null || updateValue.isAbsolute()) {
+          metricMap.put(metricName, updateNumber);
+        }
+        else {
+          Number newNumber = sum(updateNumber, currentNumber);
+          metricMap.put(metricName, newNumber);
+        }
+      }
+    }
+  }
+    
+  private synchronized RecordMap getRecordMap(String recordName) {
+    return bufferedData.get(recordName);
+  }
+    
+  /**
+   * Adds two numbers, coercing the second to the type of the first.
+   *
+   */
+  private Number sum(Number a, Number b) {
+    if (a instanceof Integer) {
+      return Integer.valueOf(a.intValue() + b.intValue());
+    }
+    else if (a instanceof Float) {
+      return new Float(a.floatValue() + b.floatValue());
+    }
+    else if (a instanceof Short) {
+      return Short.valueOf((short)(a.shortValue() + b.shortValue()));
+    }
+    else if (a instanceof Byte) {
+      return Byte.valueOf((byte)(a.byteValue() + b.byteValue()));
+    }
+    else if (a instanceof Long) {
+      return Long.valueOf((a.longValue() + b.longValue()));
+    }
+    else {
+      // should never happen
+      throw new MetricsException("Invalid number type");
+    }
+            
+  }
+    
+  /**
+   * Called by MetricsRecordImpl.remove().  Removes all matching rows in
+   * the internal table of metric data.  A row matches if it has the same
+   * tag names and values as record, but it may also have additional
+   * tags.
+   */    
+  protected void remove(MetricsRecordImpl record) {
+    String recordName = record.getRecordName();
+    TagMap tagTable = record.getTagTable();
+        
+    RecordMap recordMap = getRecordMap(recordName);
+    synchronized (recordMap) {
+      Iterator<TagMap> it = recordMap.keySet().iterator();
+      while (it.hasNext()) {
+        TagMap rowTags = it.next();
+        if (rowTags.containsAll(tagTable)) {
+          it.remove();
+        }
+      }
+    }
+  }
+    
+  /**
+   * Returns the timer period.
+   */
+  public int getPeriod() {
+    return period;
+  }
+    
+  /**
+   * Sets the timer period
+   */
+  protected void setPeriod(int period) {
+    this.period = period;
+  }
+  
+  /**
+   * If a period is set in the attribute passed in, override
+   * the default with it.
+   */
+  protected void parseAndSetPeriod(String attributeName) {
+    String periodStr = getAttribute(attributeName);
+    if (periodStr != null) {
+      int period = 0;
+      try {
+        period = Integer.parseInt(periodStr);
+      } catch (NumberFormatException nfe) {
+      }
+      if (period <= 0) {
+        throw new MetricsException("Invalid period: " + periodStr);
+      }
+      setPeriod(period);
+    }
+  }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/CompositeContext.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/CompositeContext.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/CompositeContext.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/CompositeContext.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,205 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.metrics.spi;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.metrics.ContextFactory;
+import org.apache.hadoop.metrics.MetricsContext;
+import org.apache.hadoop.metrics.MetricsException;
+import org.apache.hadoop.metrics.MetricsRecord;
+import org.apache.hadoop.metrics.MetricsUtil;
+import org.apache.hadoop.metrics.Updater;
+
+/**
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class CompositeContext extends AbstractMetricsContext {
+
+  private static final Log LOG = LogFactory.getLog(CompositeContext.class);
+  private static final String ARITY_LABEL = "arity";
+  private static final String SUB_FMT = "%s.sub%d";
+  private final ArrayList<MetricsContext> subctxt =
+    new ArrayList<MetricsContext>();
+
+  @InterfaceAudience.Private
+  public CompositeContext() {
+  }
+
+  @InterfaceAudience.Private
+  public void init(String contextName, ContextFactory factory) {
+    super.init(contextName, factory);
+    int nKids;
+    try {
+      String sKids = getAttribute(ARITY_LABEL);
+      nKids = Integer.valueOf(sKids);
+    } catch (Exception e) {
+      LOG.error("Unable to initialize composite metric " + contextName +
+                ": could not init arity", e);
+      return;
+    }
+    for (int i = 0; i < nKids; ++i) {
+      MetricsContext ctxt = MetricsUtil.getContext(
+          String.format(SUB_FMT, contextName, i), contextName);
+      if (null != ctxt) {
+        subctxt.add(ctxt);
+      }
+    }
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  public MetricsRecord newRecord(String recordName) {
+    return (MetricsRecord) Proxy.newProxyInstance(
+        MetricsRecord.class.getClassLoader(),
+        new Class[] { MetricsRecord.class },
+        new MetricsRecordDelegator(recordName, subctxt));
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  protected void emitRecord(String contextName, String recordName,
+      OutputRecord outRec) throws IOException {
+    for (MetricsContext ctxt : subctxt) {
+      try {
+        ((AbstractMetricsContext)ctxt).emitRecord(
+          contextName, recordName, outRec);
+        if (contextName == null || recordName == null || outRec == null) {
+          throw new IOException(contextName + ":" + recordName + ":" + outRec);
+        }
+      } catch (IOException e) {
+        LOG.warn("emitRecord failed: " + ctxt.getContextName(), e);
+      }
+    }
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  protected void flush() throws IOException {
+    for (MetricsContext ctxt : subctxt) {
+      try {
+        ((AbstractMetricsContext)ctxt).flush();
+      } catch (IOException e) {
+        LOG.warn("flush failed: " + ctxt.getContextName(), e);
+      }
+    }
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  public void startMonitoring() throws IOException {
+    for (MetricsContext ctxt : subctxt) {
+      try {
+        ctxt.startMonitoring();
+      } catch (IOException e) {
+        LOG.warn("startMonitoring failed: " + ctxt.getContextName(), e);
+      }
+    }
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  public void stopMonitoring() {
+    for (MetricsContext ctxt : subctxt) {
+      ctxt.stopMonitoring();
+    }
+  }
+
+  /**
+   * Return true if all subcontexts are monitoring.
+   */
+  @InterfaceAudience.Private
+  @Override
+  public boolean isMonitoring() {
+    boolean ret = true;
+    for (MetricsContext ctxt : subctxt) {
+      ret &= ctxt.isMonitoring();
+    }
+    return ret;
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  public void close() {
+    for (MetricsContext ctxt : subctxt) {
+      ctxt.close();
+    }
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  public void registerUpdater(Updater updater) {
+    for (MetricsContext ctxt : subctxt) {
+      ctxt.registerUpdater(updater);
+    }
+  }
+
+  @InterfaceAudience.Private
+  @Override
+  public void unregisterUpdater(Updater updater) {
+    for (MetricsContext ctxt : subctxt) {
+      ctxt.unregisterUpdater(updater);
+    }
+  }
+
+  private static class MetricsRecordDelegator implements InvocationHandler {
+    private static final Method m_getRecordName = initMethod();
+    private static Method initMethod() {
+      try {
+        return MetricsRecord.class.getMethod("getRecordName", new Class[0]);
+      } catch (Exception e) {
+        throw new RuntimeException("Internal error", e);
+      }
+    }
+
+    private final String recordName;
+    private final ArrayList<MetricsRecord> subrecs;
+
+    MetricsRecordDelegator(String recordName, ArrayList<MetricsContext> ctxts) {
+      this.recordName = recordName;
+      this.subrecs = new ArrayList<MetricsRecord>(ctxts.size());
+      for (MetricsContext ctxt : ctxts) {
+        subrecs.add(ctxt.createRecord(recordName));
+      }
+    }
+
+    public Object invoke(Object p, Method m, Object[] args) throws Throwable {
+      if (m_getRecordName.equals(m)) {
+        return recordName;
+      }
+      assert Void.TYPE.equals(m.getReturnType());
+      for (MetricsRecord rec : subrecs) {
+        m.invoke(rec, args);
+      }
+      return null;
+    }
+  }
+
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricValue.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricValue.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricValue.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricValue.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,59 @@
+/*
+ * MetricValue.java
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.metrics.spi;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * A Number that is either an absolute or an incremental amount.
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class MetricValue {
+    
+  public static final boolean ABSOLUTE = false;
+  public static final boolean INCREMENT = true;
+    
+  private boolean isIncrement;
+  private Number number;
+    
+  /** Creates a new instance of MetricValue */
+  public MetricValue(Number number, boolean isIncrement) {
+    this.number = number;
+    this.isIncrement = isIncrement;
+  }
+
+  public boolean isIncrement() {
+    return isIncrement;
+  }
+    
+  public boolean isAbsolute() {
+    return !isIncrement;
+  }
+
+  public Number getNumber() {
+    return number;
+  }
+    
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricsRecordImpl.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricsRecordImpl.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricsRecordImpl.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/MetricsRecordImpl.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,283 @@
+/*
+ * MetricsRecordImpl.java
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.metrics.spi;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.metrics.MetricsException;
+import org.apache.hadoop.metrics.MetricsRecord;
+import org.apache.hadoop.metrics.spi.AbstractMetricsContext.TagMap;
+
+/**
+ * An implementation of MetricsRecord.  Keeps a back-pointer to the context
+ * from which it was created, and delegates back to it on <code>update</code>
+ * and <code>remove()</code>.
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class MetricsRecordImpl implements MetricsRecord {
+    
+  private TagMap tagTable = new TagMap();
+  private Map<String,MetricValue> metricTable = new LinkedHashMap<String,MetricValue>();
+    
+  private String recordName;
+  private AbstractMetricsContext context;
+    
+    
+  /** Creates a new instance of FileRecord */
+  protected MetricsRecordImpl(String recordName, AbstractMetricsContext context)
+  {
+    this.recordName = recordName;
+    this.context = context;
+  }
+    
+  /**
+   * Returns the record name. 
+   *
+   * @return the record name
+   */
+  public String getRecordName() {
+    return recordName;
+  }
+    
+  /**
+   * Sets the named tag to the specified value.
+   *
+   * @param tagName name of the tag
+   * @param tagValue new value of the tag
+   * @throws MetricsException if the tagName conflicts with the configuration
+   */
+  public void setTag(String tagName, String tagValue) {
+    if (tagValue == null) {
+      tagValue = "";
+    }
+    tagTable.put(tagName, tagValue);
+  }
+    
+  /**
+   * Sets the named tag to the specified value.
+   *
+   * @param tagName name of the tag
+   * @param tagValue new value of the tag
+   * @throws MetricsException if the tagName conflicts with the configuration
+   */
+  public void setTag(String tagName, int tagValue) {
+    tagTable.put(tagName, Integer.valueOf(tagValue));
+  }
+    
+  /**
+   * Sets the named tag to the specified value.
+   *
+   * @param tagName name of the tag
+   * @param tagValue new value of the tag
+   * @throws MetricsException if the tagName conflicts with the configuration
+   */
+  public void setTag(String tagName, long tagValue) {
+    tagTable.put(tagName, Long.valueOf(tagValue));
+  }
+    
+  /**
+   * Sets the named tag to the specified value.
+   *
+   * @param tagName name of the tag
+   * @param tagValue new value of the tag
+   * @throws MetricsException if the tagName conflicts with the configuration
+   */
+  public void setTag(String tagName, short tagValue) {
+    tagTable.put(tagName, Short.valueOf(tagValue));
+  }
+    
+  /**
+   * Sets the named tag to the specified value.
+   *
+   * @param tagName name of the tag
+   * @param tagValue new value of the tag
+   * @throws MetricsException if the tagName conflicts with the configuration
+   */
+  public void setTag(String tagName, byte tagValue) {
+    tagTable.put(tagName, Byte.valueOf(tagValue));
+  }
+    
+  /**
+   * Removes any tag of the specified name.
+   */
+  public void removeTag(String tagName) {
+    tagTable.remove(tagName);
+  }
+  
+  /**
+   * Sets the named metric to the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue new value of the metric
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void setMetric(String metricName, int metricValue) {
+    setAbsolute(metricName, Integer.valueOf(metricValue));
+  }
+    
+  /**
+   * Sets the named metric to the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue new value of the metric
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void setMetric(String metricName, long metricValue) {
+    setAbsolute(metricName, Long.valueOf(metricValue));
+  }
+    
+  /**
+   * Sets the named metric to the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue new value of the metric
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void setMetric(String metricName, short metricValue) {
+    setAbsolute(metricName, Short.valueOf(metricValue));
+  }
+    
+  /**
+   * Sets the named metric to the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue new value of the metric
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void setMetric(String metricName, byte metricValue) {
+    setAbsolute(metricName, Byte.valueOf(metricValue));
+  }
+    
+  /**
+   * Sets the named metric to the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue new value of the metric
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void setMetric(String metricName, float metricValue) {
+    setAbsolute(metricName, new Float(metricValue));
+  }
+    
+  /**
+   * Increments the named metric by the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue incremental value
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void incrMetric(String metricName, int metricValue) {
+    setIncrement(metricName, Integer.valueOf(metricValue));
+  }
+    
+  /**
+   * Increments the named metric by the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue incremental value
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void incrMetric(String metricName, long metricValue) {
+    setIncrement(metricName, Long.valueOf(metricValue));
+  }
+    
+  /**
+   * Increments the named metric by the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue incremental value
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void incrMetric(String metricName, short metricValue) {
+    setIncrement(metricName, Short.valueOf(metricValue));
+  }
+    
+  /**
+   * Increments the named metric by the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue incremental value
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void incrMetric(String metricName, byte metricValue) {
+    setIncrement(metricName, Byte.valueOf(metricValue));
+  }
+    
+  /**
+   * Increments the named metric by the specified value.
+   *
+   * @param metricName name of the metric
+   * @param metricValue incremental value
+   * @throws MetricsException if the metricName or the type of the metricValue 
+   * conflicts with the configuration
+   */
+  public void incrMetric(String metricName, float metricValue) {
+    setIncrement(metricName, new Float(metricValue));
+  }
+    
+  private void setAbsolute(String metricName, Number metricValue) {
+    metricTable.put(metricName, new MetricValue(metricValue, MetricValue.ABSOLUTE));
+  }
+    
+  private void setIncrement(String metricName, Number metricValue) {
+    metricTable.put(metricName, new MetricValue(metricValue, MetricValue.INCREMENT));
+  }
+    
+  /**
+   * Updates the table of buffered data which is to be sent periodically.
+   * If the tag values match an existing row, that row is updated; 
+   * otherwise, a new row is added.
+   */
+  public void update() {
+    context.update(this);
+  }
+    
+  /**
+   * Removes the row, if it exists, in the buffered data table having tags 
+   * that equal the tags that have been set on this record. 
+   */
+  public void remove() {
+    context.remove(this);
+  }
+
+  TagMap getTagTable() {
+    return tagTable;
+  }
+
+  Map<String, MetricValue> getMetricTable() {
+    return metricTable;
+  }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NoEmitMetricsContext.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NoEmitMetricsContext.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NoEmitMetricsContext.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NoEmitMetricsContext.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.metrics.spi;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.metrics.ContextFactory;
+import org.apache.hadoop.metrics.MetricsServlet;
+
+/** 
+ * A MetricsContext that does not emit data, but, unlike NullContextWithUpdate,
+ * does save it for retrieval with getAllRecords().
+ * 
+ * This is useful if you want to support {@link MetricsServlet}, but
+ * not emit metrics in any other way.
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class NoEmitMetricsContext extends AbstractMetricsContext {
+    
+    private static final String PERIOD_PROPERTY = "period";
+      
+    /** Creates a new instance of NullContextWithUpdateThread */
+    @InterfaceAudience.Private
+    public NoEmitMetricsContext() {
+    }
+    
+    @InterfaceAudience.Private
+    public void init(String contextName, ContextFactory factory) {
+      super.init(contextName, factory);
+      parseAndSetPeriod(PERIOD_PROPERTY);
+    }
+     
+    /**
+     * Do-nothing version of emitRecord
+     */
+    @InterfaceAudience.Private
+    protected void emitRecord(String contextName, String recordName,
+                              OutputRecord outRec) {
+    }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContext.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContext.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContext.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContext.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,70 @@
+/*
+ * NullContext.java
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.metrics.spi;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * Null metrics context: a metrics context which does nothing.  Used as the
+ * default context, so that no performance data is emitted if no configuration
+ * data is found.
+ * 
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class NullContext extends AbstractMetricsContext {
+    
+  /** Creates a new instance of NullContext */
+  @InterfaceAudience.Private
+  public NullContext() {
+  }
+    
+  /**
+   * Do-nothing version of startMonitoring
+   */
+  @InterfaceAudience.Private
+  public void startMonitoring() {
+  }
+    
+  /**
+   * Do-nothing version of emitRecord
+   */
+  @InterfaceAudience.Private
+  protected void emitRecord(String contextName, String recordName,
+                            OutputRecord outRec) 
+  {}
+    
+  /**
+   * Do-nothing version of update
+   */
+  @InterfaceAudience.Private
+  protected void update(MetricsRecordImpl record) {
+  }
+    
+  /**
+   * Do-nothing version of remove
+   */
+  @InterfaceAudience.Private
+  protected void remove(MetricsRecordImpl record) {
+  }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContextWithUpdateThread.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContextWithUpdateThread.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContextWithUpdateThread.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/NullContextWithUpdateThread.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.metrics.spi;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.metrics.ContextFactory;
+import org.apache.hadoop.metrics.MetricsException;
+
+/**
+ * A null context which has a thread calling 
+ * periodically when monitoring is started. This keeps the data sampled 
+ * correctly.
+ * In all other respects, this is like the NULL context: No data is emitted.
+ * This is suitable for Monitoring systems like JMX which reads the metrics
+ *  when someone reads the data from JMX.
+ * 
+ * The default impl of start and stop monitoring:
+ *  is the AbstractMetricsContext is good enough.
+ * 
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class NullContextWithUpdateThread extends AbstractMetricsContext {
+  
+  private static final String PERIOD_PROPERTY = "period";
+    
+  /** Creates a new instance of NullContextWithUpdateThread */
+  @InterfaceAudience.Private
+  public NullContextWithUpdateThread() {
+  }
+  
+  @InterfaceAudience.Private
+  public void init(String contextName, ContextFactory factory) {
+    super.init(contextName, factory);
+    parseAndSetPeriod(PERIOD_PROPERTY);
+  }
+   
+    
+  /**
+   * Do-nothing version of emitRecord
+   */
+  @InterfaceAudience.Private
+  protected void emitRecord(String contextName, String recordName,
+                            OutputRecord outRec) 
+  {}
+    
+  /**
+   * Do-nothing version of update
+   */
+  @InterfaceAudience.Private
+  protected void update(MetricsRecordImpl record) {
+  }
+    
+  /**
+   * Do-nothing version of remove
+   */
+  @InterfaceAudience.Private
+  protected void remove(MetricsRecordImpl record) {
+  }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/OutputRecord.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/OutputRecord.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/OutputRecord.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/OutputRecord.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,96 @@
+/*
+ * OutputRecord.java
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.metrics.spi;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.metrics.spi.AbstractMetricsContext.MetricMap;
+import org.apache.hadoop.metrics.spi.AbstractMetricsContext.TagMap;
+
+/**
+ * Represents a record of metric data to be sent to a metrics system.
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class OutputRecord {
+    
+  private TagMap tagMap;
+  private MetricMap metricMap;
+    
+  /** Creates a new instance of OutputRecord */
+  OutputRecord(TagMap tagMap, MetricMap metricMap) {
+    this.tagMap = tagMap;
+    this.metricMap = metricMap;
+  }
+    
+  /**
+   * Returns the set of tag names
+   */
+  public Set<String> getTagNames() {
+    return Collections.unmodifiableSet(tagMap.keySet());
+  }
+    
+  /**
+   * Returns a tag object which is can be a String, Integer, Short or Byte.
+   *
+   * @return the tag value, or null if there is no such tag
+   */
+  public Object getTag(String name) {
+    return tagMap.get(name);
+  }
+    
+  /**
+   * Returns the set of metric names.
+   */
+  public Set<String> getMetricNames() {
+    return Collections.unmodifiableSet(metricMap.keySet());
+  }
+    
+  /**
+   * Returns the metric object which can be a Float, Integer, Short or Byte.
+   */
+  public Number getMetric(String name) {
+    return metricMap.get(name);
+  }
+  
+
+  /**
+   * Returns a copy of this record's tags.
+   */
+  public TagMap getTagsCopy() {
+    return new TagMap(tagMap);
+  }
+  
+  /**
+   * Returns a copy of this record's metrics.
+   */
+  public MetricMap getMetricsCopy() {
+    return new MetricMap(metricMap);
+  }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/Util.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/Util.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/Util.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/Util.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,72 @@
+/*
+ * Util.java
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.hadoop.metrics.spi;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * Static utility methods
+ */
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public class Util {
+    
+  /**
+   * This class is not intended to be instantiated
+   */
+  private Util() {}
+    
+  /**
+   * Parses a space and/or comma separated sequence of server specifications
+   * of the form <i>hostname</i> or <i>hostname:port</i>.  If 
+   * the specs string is null, defaults to localhost:defaultPort.
+   * 
+   * @return a list of InetSocketAddress objects.
+   */
+  public static List<InetSocketAddress> parse(String specs, int defaultPort) {
+    List<InetSocketAddress> result = new ArrayList<InetSocketAddress>(1);
+    if (specs == null) {
+      result.add(new InetSocketAddress("localhost", defaultPort));
+    }
+    else {
+      String[] specStrings = specs.split("[ ,]+");
+      for (String specString : specStrings) {
+        int colon = specString.indexOf(':');
+        if (colon < 0 || colon == specString.length() - 1) {
+          result.add(new InetSocketAddress(specString, defaultPort));
+        } else {
+          String hostname = specString.substring(0, colon);
+          int port = Integer.parseInt(specString.substring(colon+1));
+          result.add(new InetSocketAddress(hostname, port));
+        }
+      }
+    }
+    return result;
+  }
+    
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/package.html
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/package.html?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/package.html (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/spi/package.html Tue Mar 15 16:23:19 2011
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<!--
+   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.
+-->
+
+  <head>
+    <title>org.apache.hadoop.metrics.spi</title>
+  </head>
+  <body>
+    <p><em>Note, this package is deprecated in favor of
+      <code>org.apache.hadoop.metrics2</code> usage.</em></p>
+      <p>The Service Provider Interface for the Metrics API.  This package provides
+an interface allowing a variety of metrics reporting implementations to be
+plugged in to the Metrics API.  Examples of such implementations can be found 
+in the packages <code>org.apache.hadoop.metrics.file</code> and
+<code>org.apache.hadoop.metrics.ganglia</code>.</p>
+
+      <p>Plugging in an implementation involves writing a concrete subclass of
+<code>AbstractMetricsContext</code>.  The subclass should get its
+ configuration information using the <code>getAttribute(<i>attributeName</i>)</code>
+ method.</p>
+  </body>
+</html>

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MBeanUtil.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MBeanUtil.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MBeanUtil.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MBeanUtil.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.metrics.util;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.InstanceAlreadyExistsException;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+
+
+/**
+ * This util class provides a method to register an MBean using
+ * our standard naming convention as described in the doc
+ *  for {@link #registerMBean(String, String, Object)}
+ *
+ * @deprecated in favor of {@link org.apache.hadoop.metrics2.util.MBeans}.
+ */
+@Deprecated
+@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
+public class MBeanUtil {
+	
+  /**
+   * Register the MBean using our standard MBeanName format
+   * "hadoop:service=<serviceName>,name=<nameName>"
+   * Where the <serviceName> and <nameName> are the supplied parameters
+   *    
+   * @param serviceName
+   * @param nameName
+   * @param theMbean - the MBean to register
+   * @return the named used to register the MBean
+   */	
+  static public ObjectName registerMBean(final String serviceName, 
+		  							final String nameName,
+		  							final Object theMbean) {
+    final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+    ObjectName name = getMBeanName(serviceName, nameName);
+    try {
+      mbs.registerMBean(theMbean, name);
+      return name;
+    } catch (InstanceAlreadyExistsException ie) {
+      // Ignore if instance already exists 
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+  
+  static public void unregisterMBean(ObjectName mbeanName) {
+    final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+    if (mbeanName == null) 
+        return;
+    try {
+      mbs.unregisterMBean(mbeanName);
+    } catch (InstanceNotFoundException e ) {
+      // ignore
+    } catch (Exception e) {
+      e.printStackTrace();
+    } 
+  }
+  
+  static private ObjectName getMBeanName(final String serviceName,
+		  								 final String nameName) {
+    ObjectName name = null;
+    try {
+      name = new ObjectName("hadoop:" +
+                  "service=" + serviceName + ",name=" + nameName);
+    } catch (MalformedObjectNameException e) {
+      e.printStackTrace();
+    }
+    return name;
+  }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsBase.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsBase.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsBase.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsBase.java Tue Mar 15 16:23:19 2011
@@ -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.hadoop.metrics.util;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.metrics.MetricsRecord;
+
+/**
+ * 
+ * This is base class for all metrics
+ *
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.Private
+public abstract class MetricsBase {
+  public static final String NO_DESCRIPTION = "NoDescription";
+  final private String name;
+  final private String description;
+  
+  protected MetricsBase(final String nam) {
+    name = nam;
+    description = NO_DESCRIPTION;
+  }
+  
+  protected MetricsBase(final String nam, final String desc) {
+    name = nam;
+    description = desc;
+  }
+  
+  public abstract void pushMetric(final MetricsRecord mr);
+  
+  public String getName() { return name; }
+  public String getDescription() { return description; };
+
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsDynamicMBeanBase.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsDynamicMBeanBase.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsDynamicMBeanBase.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsDynamicMBeanBase.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,229 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.metrics.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ReflectionException;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.metrics.MetricsUtil;
+
+
+
+/**
+ * This abstract base class facilitates creating dynamic mbeans automatically from
+ * metrics. 
+ * The metrics constructors registers metrics in a registry. 
+ * Different categories of metrics should be in differnt classes with their own
+ * registry (as in NameNodeMetrics and DataNodeMetrics).
+ * Then the MBean can be created passing the registry to the constructor.
+ * The MBean should be then registered using a mbean name (example):
+ *  MetricsHolder myMetrics = new MetricsHolder(); // has metrics and registry
+ *  MetricsTestMBean theMBean = new MetricsTestMBean(myMetrics.mregistry);
+ *  ObjectName mbeanName = MBeanUtil.registerMBean("ServiceFoo",
+ *                "TestStatistics", theMBean);
+ * 
+ * @deprecated in favor of <code>org.apache.hadoop.metrics2</code> usage.
+ */
+@Deprecated
+@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
+public abstract class MetricsDynamicMBeanBase implements DynamicMBean {
+  private final static String AVG_TIME = "AvgTime";
+  private final static String MIN_TIME = "MinTime";
+  private final static String MAX_TIME = "MaxTime";
+  private final static String NUM_OPS = "NumOps";
+  private final static String RESET_ALL_MIN_MAX_OP = "resetAllMinMax";
+  private MetricsRegistry metricsRegistry;
+  private MBeanInfo mbeanInfo;
+  private Map<String, MetricsBase> metricsRateAttributeMod;
+  private int numEntriesInRegistry = 0;
+  private String mbeanDescription;
+  
+  protected MetricsDynamicMBeanBase(final MetricsRegistry mr, final String aMBeanDescription) {
+    metricsRegistry = mr;
+    mbeanDescription = aMBeanDescription;
+    createMBeanInfo();
+  }
+  
+  private void updateMbeanInfoIfMetricsListChanged()  {
+    if (numEntriesInRegistry != metricsRegistry.size())
+      createMBeanInfo();
+  }
+  
+  private void createMBeanInfo() {
+    metricsRateAttributeMod = new HashMap<String, MetricsBase>();
+    boolean needsMinMaxResetOperation = false;
+    List<MBeanAttributeInfo> attributesInfo = new ArrayList<MBeanAttributeInfo>();
+    MBeanOperationInfo[] operationsInfo = null;
+    numEntriesInRegistry = metricsRegistry.size();
+    
+    for (MetricsBase o : metricsRegistry.getMetricsList()) {
+
+      if (MetricsTimeVaryingRate.class.isInstance(o)) {
+        // For each of the metrics there are 3 different attributes
+        attributesInfo.add(new MBeanAttributeInfo(o.getName() + NUM_OPS, "java.lang.Integer",
+            o.getDescription(), true, false, false));
+        attributesInfo.add(new MBeanAttributeInfo(o.getName() + AVG_TIME, "java.lang.Long",
+            o.getDescription(), true, false, false));
+        attributesInfo.add(new MBeanAttributeInfo(o.getName() + MIN_TIME, "java.lang.Long",
+            o.getDescription(), true, false, false));
+        attributesInfo.add(new MBeanAttributeInfo(o.getName() + MAX_TIME, "java.lang.Long",
+            o.getDescription(), true, false, false));
+        needsMinMaxResetOperation = true;  // the min and max can be reset.
+        
+        // Note the special attributes (AVG_TIME, MIN_TIME, ..) are derived from metrics 
+        // Rather than check for the suffix we store them in a map.
+        metricsRateAttributeMod.put(o.getName() + NUM_OPS, o);
+        metricsRateAttributeMod.put(o.getName() + AVG_TIME, o);
+        metricsRateAttributeMod.put(o.getName() + MIN_TIME, o);
+        metricsRateAttributeMod.put(o.getName() + MAX_TIME, o);
+        
+      }  else if ( MetricsIntValue.class.isInstance(o) || MetricsTimeVaryingInt.class.isInstance(o) ) {
+        attributesInfo.add(new MBeanAttributeInfo(o.getName(), "java.lang.Integer",
+            o.getDescription(), true, false, false)); 
+      } else if ( MetricsLongValue.class.isInstance(o) || MetricsTimeVaryingLong.class.isInstance(o) ) {
+        attributesInfo.add(new MBeanAttributeInfo(o.getName(), "java.lang.Long",
+            o.getDescription(), true, false, false));     
+      } else {
+        MetricsUtil.LOG.error("unknown metrics type: " + o.getClass().getName());
+      }
+
+      if (needsMinMaxResetOperation) {
+        operationsInfo = new MBeanOperationInfo[] {
+            new MBeanOperationInfo(RESET_ALL_MIN_MAX_OP, "Reset (zero) All Min Max",
+                    null, "void", MBeanOperationInfo.ACTION) };
+      }
+    }
+    MBeanAttributeInfo[] attrArray = new MBeanAttributeInfo[attributesInfo.size()];
+    mbeanInfo =  new MBeanInfo(this.getClass().getName(), mbeanDescription, 
+        attributesInfo.toArray(attrArray), null, operationsInfo, null);
+  }
+  
+  @Override
+  public Object getAttribute(String attributeName) throws AttributeNotFoundException,
+      MBeanException, ReflectionException {
+    if (attributeName == null || attributeName.equals("")) 
+      throw new IllegalArgumentException();
+    
+    updateMbeanInfoIfMetricsListChanged();
+    
+    Object o = metricsRateAttributeMod.get(attributeName);
+    if (o == null) {
+      o = metricsRegistry.get(attributeName);
+    }
+    if (o == null)
+      throw new AttributeNotFoundException();
+    
+    if (o instanceof MetricsIntValue)
+      return ((MetricsIntValue) o).get();
+    else if (o instanceof MetricsLongValue)
+      return ((MetricsLongValue) o).get();
+    else if (o instanceof MetricsTimeVaryingInt)
+      return ((MetricsTimeVaryingInt) o).getPreviousIntervalValue();
+    else if (o instanceof MetricsTimeVaryingLong)
+      return ((MetricsTimeVaryingLong) o).getPreviousIntervalValue();
+    else if (o instanceof MetricsTimeVaryingRate) {
+      MetricsTimeVaryingRate or = (MetricsTimeVaryingRate) o;
+      if (attributeName.endsWith(NUM_OPS))
+        return or.getPreviousIntervalNumOps();
+      else if (attributeName.endsWith(AVG_TIME))
+        return or.getPreviousIntervalAverageTime();
+      else if (attributeName.endsWith(MIN_TIME))
+        return or.getMinTime();
+      else if (attributeName.endsWith(MAX_TIME))
+        return or.getMaxTime();
+      else {
+        MetricsUtil.LOG.error("Unexpected attrubute suffix");
+        throw new AttributeNotFoundException();
+      }
+    } else {
+        MetricsUtil.LOG.error("unknown metrics type: " + o.getClass().getName());
+        throw new AttributeNotFoundException();
+    }
+  }
+
+  @Override
+  public AttributeList getAttributes(String[] attributeNames) {
+    if (attributeNames == null || attributeNames.length == 0) 
+      throw new IllegalArgumentException();
+    
+    updateMbeanInfoIfMetricsListChanged();
+    
+    AttributeList result = new AttributeList(attributeNames.length);
+    for (String iAttributeName : attributeNames) {
+      try {
+        Object value = getAttribute(iAttributeName);
+        result.add(new Attribute(iAttributeName, value));
+      } catch (Exception e) {
+        continue;
+      } 
+    }
+    return result;
+  }
+
+  @Override
+  public MBeanInfo getMBeanInfo() {
+    return mbeanInfo;
+  }
+
+  @Override
+  public Object invoke(String actionName, Object[] parms, String[] signature)
+      throws MBeanException, ReflectionException {
+    
+    if (actionName == null || actionName.equals("")) 
+      throw new IllegalArgumentException();
+    
+    
+    // Right now we support only one fixed operation (if it applies)
+    if (!(actionName.equals(RESET_ALL_MIN_MAX_OP)) || 
+        mbeanInfo.getOperations().length != 1) {
+      throw new ReflectionException(new NoSuchMethodException(actionName));
+    }
+    for (MetricsBase m : metricsRegistry.getMetricsList())  {
+      if ( MetricsTimeVaryingRate.class.isInstance(m) ) {
+        MetricsTimeVaryingRate.class.cast(m).resetMinMax();
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public void setAttribute(Attribute attribute)
+      throws AttributeNotFoundException, InvalidAttributeValueException,
+      MBeanException, ReflectionException {
+    throw new ReflectionException(new NoSuchMethodException("set" + attribute));
+  }
+
+  @Override
+  public AttributeList setAttributes(AttributeList attributes) {
+    return null;
+  }
+}

Added: hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsIntValue.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsIntValue.java?rev=1081836&view=auto
==============================================================================
--- hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsIntValue.java (added)
+++ hadoop/common/branches/branch-0.20-security/src/core/org/apache/hadoop/metrics/util/MetricsIntValue.java Tue Mar 15 16:23:19 2011
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.metrics.util;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.metrics.MetricsRecord;
+import org.apache.hadoop.util.StringUtils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The MetricsIntValue class is for a metric that is not time varied
+ * but changes only when it is set. 
+ * Each time its value is set, it is published only *once* at the next update
+ * call.
+ *
+ * @deprecated in favor of {@link org.apache.hadoop.metrics2.lib.MutableGaugeInt}.
+ */
+@Deprecated
+@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
+public class MetricsIntValue extends MetricsBase {  
+
+  private static final Log LOG =
+    LogFactory.getLog("org.apache.hadoop.metrics.util");
+
+  private int value;
+  private boolean changed;
+  
+  
+  /**
+   * Constructor - create a new metric
+   * @param nam the name of the metrics to be used to publish the metric
+   * @param registry - where the metrics object will be registered
+   */
+  public MetricsIntValue(final String nam, final MetricsRegistry registry, final String description) {
+    super(nam, description);
+    value = 0;
+    changed = false;
+    registry.add(nam, this);
+  }
+  
+  /**
+   * Constructor - create a new metric
+   * @param nam the name of the metrics to be used to publish the metric
+   * @param registry - where the metrics object will be registered
+   * A description of {@link #NO_DESCRIPTION} is used
+   */
+  public MetricsIntValue(final String nam, MetricsRegistry registry) {
+    this(nam, registry, NO_DESCRIPTION);
+  }
+  
+  
+  
+  /**
+   * Set the value
+   * @param newValue
+   */
+  public synchronized void set(final int newValue) {
+    value = newValue;
+    changed = true;
+  }
+  
+  /**
+   * Get value
+   * @return the value last set
+   */
+  public synchronized int get() { 
+    return value;
+  } 
+  
+
+  /**
+   * Push the metric to the mr.
+   * The metric is pushed only if it was updated since last push
+   * 
+   * Note this does NOT push to JMX
+   * (JMX gets the info via {@link #get()}
+   *
+   * @param mr
+   */
+  public synchronized void pushMetric(final MetricsRecord mr) {
+    if (changed) {
+      try {
+        mr.setMetric(getName(), value);
+      } catch (Exception e) {
+        LOG.info("pushMetric failed for " + getName() + "\n" +
+            StringUtils.stringifyException(e));
+      }
+    }
+    changed = false;
+  }
+}