001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.yarn.util;
020
021import java.lang.reflect.Constructor;
022
023import org.apache.commons.logging.Log;
024import org.apache.commons.logging.LogFactory;
025import org.apache.hadoop.classification.InterfaceAudience.Public;
026import org.apache.hadoop.classification.InterfaceAudience.Private;
027import org.apache.hadoop.classification.InterfaceStability.Evolving;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.conf.Configured;
030
031/**
032 * Interface class to obtain process resource usage
033 * NOTE: This class should not be used by external users, but only by external
034 * developers to extend and include their own process-tree implementation, 
035 * especially for platforms other than Linux and Windows.
036 */
037@Public
038@Evolving
039public abstract class ResourceCalculatorProcessTree extends Configured {
040  static final Log LOG = LogFactory
041      .getLog(ResourceCalculatorProcessTree.class);
042  public static final int UNAVAILABLE = -1;
043
044  /**
045   * Create process-tree instance with specified root process.
046   *
047   * Subclass must override this.
048   * @param root process-tree root-process
049   */
050  public ResourceCalculatorProcessTree(String root) {
051  }
052
053  /**
054   * Update the process-tree with latest state.
055   *
056   * Each call to this function should increment the age of the running
057   * processes that already exist in the process tree. Age is used other API's
058   * of the interface.
059   *
060   */
061  public abstract void updateProcessTree();
062
063  /**
064   * Get a dump of the process-tree.
065   *
066   * @return a string concatenating the dump of information of all the processes
067   *         in the process-tree
068   */
069  public abstract String getProcessTreeDump();
070
071  /**
072   * Get the virtual memory used by all the processes in the
073   * process-tree.
074   *
075   * @return virtual memory used by the process-tree in bytes,
076   * {@link #UNAVAILABLE} if it cannot be calculated.
077   */
078  public long getVirtualMemorySize() {
079    return getVirtualMemorySize(0);
080  }
081  
082  /**
083   * Get the virtual memory used by all the processes in the
084   * process-tree.
085   *
086   * @return virtual memory used by the process-tree in bytes,
087   * {@link #UNAVAILABLE} if it cannot be calculated.
088   */
089  @Deprecated
090  public long getCumulativeVmem() {
091    return getCumulativeVmem(0);
092  }
093
094  /**
095   * Get the resident set size (rss) memory used by all the processes
096   * in the process-tree.
097   *
098   * @return rss memory used by the process-tree in bytes,
099   * {@link #UNAVAILABLE} if it cannot be calculated.
100   */
101  public long getRssMemorySize() {
102    return getRssMemorySize(0);
103  }
104  
105  /**
106   * Get the resident set size (rss) memory used by all the processes
107   * in the process-tree.
108   *
109   * @return rss memory used by the process-tree in bytes,
110   * {@link #UNAVAILABLE} if it cannot be calculated.
111   */
112  @Deprecated
113  public long getCumulativeRssmem() {
114    return getCumulativeRssmem(0);
115  }
116
117  /**
118   * Get the virtual memory used by all the processes in the
119   * process-tree that are older than the passed in age.
120   *
121   * @param olderThanAge processes above this age are included in the
122   *                     memory addition
123   * @return virtual memory used by the process-tree in bytes for
124   * processes older than the specified age, {@link #UNAVAILABLE} if it
125   * cannot be calculated.
126   */
127  public long getVirtualMemorySize(int olderThanAge) {
128    return UNAVAILABLE;
129  }
130  
131  /**
132   * Get the virtual memory used by all the processes in the
133   * process-tree that are older than the passed in age.
134   *
135   * @param olderThanAge processes above this age are included in the
136   *                     memory addition
137   * @return virtual memory used by the process-tree in bytes for
138   * processes older than the specified age, {@link #UNAVAILABLE} if it
139   * cannot be calculated.
140   */
141  @Deprecated
142  public long getCumulativeVmem(int olderThanAge) {
143    return UNAVAILABLE;
144  }
145
146  /**
147   * Get the resident set size (rss) memory used by all the processes
148   * in the process-tree that are older than the passed in age.
149   *
150   * @param olderThanAge processes above this age are included in the
151   *                     memory addition
152   * @return rss memory used by the process-tree in bytes for
153   * processes older than specified age, {@link #UNAVAILABLE} if it cannot be
154   * calculated.
155   */
156  public long getRssMemorySize(int olderThanAge) {
157    return UNAVAILABLE;
158  }
159  
160  /**
161   * Get the resident set size (rss) memory used by all the processes
162   * in the process-tree that are older than the passed in age.
163   *
164   * @param olderThanAge processes above this age are included in the
165   *                     memory addition
166   * @return rss memory used by the process-tree in bytes for
167   * processes older than specified age, {@link #UNAVAILABLE} if it cannot be
168   * calculated.
169   */
170  @Deprecated
171  public long getCumulativeRssmem(int olderThanAge) {
172    return UNAVAILABLE;
173  }
174
175  /**
176   * Get the CPU time in millisecond used by all the processes in the
177   * process-tree since the process-tree was created
178   *
179   * @return cumulative CPU time in millisecond since the process-tree
180   * created, {@link #UNAVAILABLE} if it cannot be calculated.
181   */
182  public long getCumulativeCpuTime() {
183    return UNAVAILABLE;
184  }
185
186  /**
187   * Get the CPU usage by all the processes in the process-tree based on
188   * average between samples as a ratio of overall CPU cycles similar to top.
189   * Thus, if 2 out of 4 cores are used this should return 200.0.
190   *
191   * @return percentage CPU usage since the process-tree was created,
192   * {@link #UNAVAILABLE} if it cannot be calculated.
193   */
194  public float getCpuUsagePercent() {
195    return UNAVAILABLE;
196  }
197
198  /** Verify that the tree process id is same as its process group id.
199   * @return true if the process id matches else return false.
200   */
201  public abstract boolean checkPidPgrpidForMatch();
202
203  /**
204   * Create the ResourceCalculatorProcessTree rooted to specified process 
205   * from the class name and configure it. If class name is null, this method
206   * will try and return a process tree plugin available for this system.
207   *
208   * @param pid process pid of the root of the process tree
209   * @param clazz class-name
210   * @param conf configure the plugin with this.
211   *
212   * @return ResourceCalculatorProcessTree or null if ResourceCalculatorPluginTree
213   *         is not available for this system.
214   */
215  public static ResourceCalculatorProcessTree getResourceCalculatorProcessTree(
216    String pid, Class<? extends ResourceCalculatorProcessTree> clazz, Configuration conf) {
217
218    if (clazz != null) {
219      try {
220        Constructor <? extends ResourceCalculatorProcessTree> c = clazz.getConstructor(String.class);
221        ResourceCalculatorProcessTree rctree = c.newInstance(pid);
222        rctree.setConf(conf);
223        return rctree;
224      } catch(Exception e) {
225        throw new RuntimeException(e);
226      }
227    }
228
229    // No class given, try a os specific class
230    if (ProcfsBasedProcessTree.isAvailable()) {
231      return new ProcfsBasedProcessTree(pid);
232    }
233    if (WindowsBasedProcessTree.isAvailable()) {
234      return new WindowsBasedProcessTree(pid);
235    }
236
237    // Not supported on this system.
238    return null;
239  }
240}