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   * Note: UNAVAILABLE will be returned in case when CPU usage is not
191   * available. It is NOT advised to return any other error code.
192   *
193   * @return percentage CPU usage since the process-tree was created,
194   * {@link #UNAVAILABLE} if CPU usage cannot be calculated or not available.
195   */
196  public float getCpuUsagePercent() {
197    return UNAVAILABLE;
198  }
199
200  /** Verify that the tree process id is same as its process group id.
201   * @return true if the process id matches else return false.
202   */
203  public abstract boolean checkPidPgrpidForMatch();
204
205  /**
206   * Create the ResourceCalculatorProcessTree rooted to specified process 
207   * from the class name and configure it. If class name is null, this method
208   * will try and return a process tree plugin available for this system.
209   *
210   * @param pid process pid of the root of the process tree
211   * @param clazz class-name
212   * @param conf configure the plugin with this.
213   *
214   * @return ResourceCalculatorProcessTree or null if ResourceCalculatorPluginTree
215   *         is not available for this system.
216   */
217  public static ResourceCalculatorProcessTree getResourceCalculatorProcessTree(
218    String pid, Class<? extends ResourceCalculatorProcessTree> clazz, Configuration conf) {
219
220    if (clazz != null) {
221      try {
222        Constructor <? extends ResourceCalculatorProcessTree> c = clazz.getConstructor(String.class);
223        ResourceCalculatorProcessTree rctree = c.newInstance(pid);
224        rctree.setConf(conf);
225        return rctree;
226      } catch(Exception e) {
227        throw new RuntimeException(e);
228      }
229    }
230
231    // No class given, try a os specific class
232    if (ProcfsBasedProcessTree.isAvailable()) {
233      return new ProcfsBasedProcessTree(pid);
234    }
235    if (WindowsBasedProcessTree.isAvailable()) {
236      return new WindowsBasedProcessTree(pid);
237    }
238
239    // Not supported on this system.
240    return null;
241  }
242}