Environment.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:13k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.contrib.failmon;
  19. import java.io.File;
  20. import java.io.FileInputStream;
  21. import java.io.FileNotFoundException;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.util.ArrayList;
  25. import java.util.Properties;
  26. import java.util.regex.Matcher;
  27. import java.util.regex.Pattern;
  28. import org.apache.commons.logging.*;
  29. import org.apache.log4j.PropertyConfigurator;
  30. /**********************************************************
  31.  * This class provides various methods for interaction with
  32.  * the configuration and the operating system environment. Also
  33.  * provides some helper methods for use by other classes in
  34.  * the package.
  35.  **********************************************************/
  36. public class Environment {
  37.   public static final int DEFAULT_LOG_INTERVAL = 3600;
  38.   public static final int DEFAULT_POLL_INTERVAL = 360;
  39.   public static int MIN_INTERVAL = 5;
  40.   public static final int MAX_OUTPUT_LENGTH = 51200;
  41.   public static Log LOG;
  42.   
  43.   static Properties fmProperties = new Properties();
  44.   static boolean superuser = false;
  45.   static boolean ready = false;
  46.   /**
  47.    * Initializes structures needed by other methods. Also determines
  48.    * whether the executing user has superuser privileges. 
  49.    *  
  50.    */
  51.   public static void prepare(String fname) {
  52.     if (!"Linux".equalsIgnoreCase(System.getProperty("os.name"))) {
  53.       System.err.println("Linux system required for FailMon. Exiting...");
  54.       System.exit(0);
  55.     }
  56.     System.setProperty("log4j.configuration", "conf/log4j.properties");
  57.     PropertyConfigurator.configure("conf/log4j.properties");
  58.     LOG = LogFactory.getLog("org.apache.hadoop.contrib.failmon");
  59.     logInfo("********** FailMon started ***********");
  60.     // read parseState file
  61.     PersistentState.readState("conf/parsing.state");
  62.     
  63.     try {
  64.       FileInputStream propFile = new FileInputStream(fname);
  65.       fmProperties.load(propFile);
  66.       propFile.close();
  67.     } catch (FileNotFoundException e1) {
  68.       e1.printStackTrace();
  69.     } catch (IOException e) {
  70.       e.printStackTrace();
  71.     }
  72.     ready = true;
  73.     try {
  74.       String sudo_prompt = "passwd_needed:";
  75.       String echo_txt = "access_ok";
  76.       
  77.       Process p = Runtime.getRuntime().exec("sudo -S -p " + sudo_prompt + " echo " + echo_txt );
  78.       InputStream inps = p.getInputStream();
  79.       InputStream errs = p.getErrorStream();
  80.       
  81.       while (inps.available() < echo_txt.length() && errs.available() < sudo_prompt.length())
  82. Thread.sleep(100);
  83.       byte [] buf;
  84.       String s;
  85.       
  86.       if (inps.available() >= echo_txt.length()) {
  87.         buf = new byte[inps.available()];
  88.         inps.read(buf);
  89.         s = new String(buf);
  90.         if (s.startsWith(echo_txt)) {
  91.           superuser = true;
  92.   logInfo("Superuser privileges found!");
  93. } else {
  94.   // no need to read errs
  95.   superuser = false;
  96.   logInfo("Superuser privileges not found.");
  97. }
  98.       }
  99.     } catch (IOException e) {
  100.       e.printStackTrace();
  101.     } catch (InterruptedException e) {
  102.       e.printStackTrace();
  103.     }
  104.   }
  105.   /**
  106.    * Fetches the value of a property from the configuration file.
  107.    * 
  108.    *  @param key the name of the property
  109.    *  
  110.    *  @return the value of the property, if it exists and
  111.    *  null otherwise
  112.    */
  113.   public static String getProperty(String key) {
  114.     if (!ready)
  115.       prepare("conf/failmon.properties");
  116.     return fmProperties.getProperty(key);
  117.   }
  118.   /**
  119.    * Sets the value of a property inthe configuration file.
  120.    * 
  121.    *  @param key the name of the property
  122.    *  @param value the new value for the property
  123.    *  
  124.    */
  125.   
  126.   public static void setProperty(String key, String value) {
  127.     fmProperties.setProperty(key, value);
  128.   }
  129.   /**
  130.    * Scans the configuration file to determine which monitoring
  131.    * utilities are available in the system. For each one of them, a
  132.    * job is created. All such jobs are scheduled and executed by
  133.    * Executor.
  134.    * 
  135.    * @return an ArrayList that contains jobs to be executed by theExecutor. 
  136.    */
  137.   public static ArrayList<MonitorJob> getJobs() {
  138.     ArrayList<MonitorJob> monitors = new ArrayList<MonitorJob>();
  139.     int timeInt = 0;
  140.     // for Hadoop Log parsing
  141.     String [] fnames_r = getProperty("log.hadoop.filenames").split(",\s*");
  142.     String tmp = getProperty("log.hadoop.enabled");
  143.     String [] fnames = expandDirs(fnames_r, ".*(.log).*");
  144.     timeInt = setValue("log.hadoop.interval", DEFAULT_LOG_INTERVAL);
  145.     
  146.     if ("true".equalsIgnoreCase(tmp) && fnames[0] != null)
  147.       for (String fname : fnames) {
  148.         File f = new File(fname);
  149.         if (f.exists() && f.canRead()) {
  150.           monitors.add(new MonitorJob(new HadoopLogParser(fname), "hadoopLog", timeInt));
  151.   logInfo("Created Monitor for Hadoop log file: " + f.getAbsolutePath());
  152. } else if (!f.exists())
  153.   logInfo("Skipping Hadoop log file " + fname + " (file not found)");
  154. else
  155.   logInfo("Skipping Hadoop log file " + fname + " (permission denied)");
  156.     }
  157.     
  158.     
  159.     // for System Log parsing
  160.     fnames_r = getProperty("log.system.filenames").split(",\s*");
  161.     tmp = getProperty("log.system.enabled");
  162.     fnames = expandDirs(fnames_r, ".*(messages).*");
  163.     timeInt = setValue("log.system.interval", DEFAULT_LOG_INTERVAL);
  164.     
  165.     if ("true".equalsIgnoreCase(tmp))
  166.       for (String fname : fnames) {
  167.         File f = new File(fname);
  168.         if (f.exists() && f.canRead()) {
  169.           monitors.add(new MonitorJob(new SystemLogParser(fname), "systemLog", timeInt));
  170.   logInfo("Created Monitor for System log file: " + f.getAbsolutePath());
  171.         } else if (!f.exists())
  172.   logInfo("Skipping system log file " + fname + " (file not found)");
  173. else
  174.   logInfo("Skipping system log file " + fname + " (permission denied)");
  175.       }
  176.         
  177.     // for network interfaces
  178.     tmp = getProperty("nic.enabled");
  179.     timeInt = setValue("nics.interval", DEFAULT_POLL_INTERVAL);
  180.     
  181.     if ("true".equalsIgnoreCase(tmp)) {
  182.       monitors.add(new MonitorJob(new NICParser(), "nics", timeInt));
  183.       logInfo("Created Monitor for NICs");
  184.     }
  185.     // for cpu
  186.     tmp = getProperty("cpu.enabled");
  187.     timeInt = setValue("cpu.interval", DEFAULT_POLL_INTERVAL);
  188.     
  189.     if ("true".equalsIgnoreCase(tmp)) {
  190.       monitors.add(new MonitorJob(new CPUParser(), "cpu", timeInt));
  191.       logInfo("Created Monitor for CPUs");
  192.     }
  193.     // for disks
  194.     tmp = getProperty("disks.enabled");
  195.     timeInt = setValue("disks.interval", DEFAULT_POLL_INTERVAL);
  196.     
  197.     if ("true".equalsIgnoreCase(tmp)) {
  198.       // check privileges if a disk with no disks./dev/xxx/.source is found
  199.       boolean smart_present = checkExistence("smartctl");
  200.       int disks_ok = 0;
  201.       String devicesStr = getProperty("disks.list");
  202.       String[] devices = null;
  203.       if (devicesStr != null)
  204.         devices = devicesStr.split(",\s*");
  205.       
  206.       for (int i = 0; i< devices.length; i++) {
  207.         boolean file_present = false;
  208.         boolean disk_present = false;
  209.         
  210.         String fileloc = getProperty("disks." + devices[i] + ".source");
  211.         if (fileloc != null && fileloc.equalsIgnoreCase("true"))
  212.           file_present = true;
  213.         
  214.         if (!file_present) 
  215.           if (superuser) {
  216.               StringBuffer sb = runCommand("sudo smartctl -i " + devices[i]);
  217.               String patternStr = "[(failed)(device not supported)]";
  218.               Pattern pattern = Pattern.compile(patternStr);
  219.               Matcher matcher = pattern.matcher(sb.toString());
  220.               if (matcher.find(0))
  221.                 disk_present = false;
  222.               else
  223.                 disk_present = true;            
  224.           }
  225.         if (file_present || (disk_present && smart_present)) {
  226.           disks_ok++;
  227.         } else
  228.           devices[i] = null;
  229.       } 
  230.       
  231.       // now remove disks that dont exist
  232.       StringBuffer resetSB = new StringBuffer();
  233.       for (int j = 0; j < devices.length; j++) {
  234.         resetSB.append(devices[j] == null ? "" : devices[j] + ", ");
  235. if (devices[j] != null)
  236.     logInfo("Found S.M.A.R.T. attributes for disk " + devices[j]);
  237.       }
  238.       // fix the property
  239.       if (resetSB.length() >= 2)
  240.         setProperty("disks.list", resetSB.substring(0, resetSB.length() - 2));
  241.       
  242.       if (disks_ok > 0) {
  243.         monitors.add(new MonitorJob(new SMARTParser(), "disks", timeInt));
  244. logInfo("Created Monitor for S.M.A.R.T disk attributes");
  245.       }
  246.     }
  247.     // for lm-sensors
  248.     tmp = getProperty("sensors.enabled");
  249.     timeInt = setValue("sensors.interval", DEFAULT_POLL_INTERVAL);
  250.     
  251.     if ("true".equalsIgnoreCase(tmp) && checkExistence("sensors")) {
  252.       monitors.add(new MonitorJob(new SensorsParser(), "sensors", timeInt));
  253.       logInfo("Created Monitor for lm-sensors output");
  254.     }
  255.     return monitors;
  256.   }
  257.   /**
  258.    * Determines the minimum interval at which the executor thread
  259.    * needs to wake upto execute jobs. Essentially, this is interval 
  260.    * equals the GCD of intervals of all scheduled jobs. 
  261.    * 
  262.    *  @param monitors the list of scheduled jobs
  263.    *  
  264.    *  @return the minimum interval between two scheduled jobs
  265.    */
  266.   public static int getInterval(ArrayList<MonitorJob> monitors) {
  267.     String tmp = getProperty("executor.interval.min");
  268.     if (tmp != null)
  269.       MIN_INTERVAL = Integer.parseInt(tmp);
  270.     int[] monIntervals = new int[monitors.size()];
  271.     for (int i = 0; i < monitors.size(); i++)
  272.       monIntervals[i] = monitors.get(i).interval;
  273.     return Math.max(MIN_INTERVAL, gcd(monIntervals));
  274.   }
  275.   /**
  276.    * Checks whether a specific shell command is available
  277.    * in the system. 
  278.    * 
  279.    *  @param cmd the command to check against
  280.    *
  281.    *  @return true, if the command is availble, false otherwise
  282.    */
  283.   public static boolean checkExistence(String cmd) {
  284.     StringBuffer sb = runCommand("which " + cmd);
  285.     if (sb.length() > 1)
  286.       return true;
  287.     return false;
  288.   }
  289.   /**
  290.    * Runs a shell command in the system and provides a StringBuffer
  291.    * with the output of the command.
  292.    * 
  293.    *  @param cmd an array of string that form the command to run 
  294.    *  
  295.    *  @return a StringBuffer that contains the output of the command 
  296.    */
  297.   public static StringBuffer runCommand(String[] cmd) {
  298.     StringBuffer retval = new StringBuffer(MAX_OUTPUT_LENGTH);
  299.     Process p;
  300.     try {
  301.       p = Runtime.getRuntime().exec(cmd);
  302.       InputStream tmp = p.getInputStream();
  303.       p.waitFor();
  304.       int c;
  305.       while ((c = tmp.read()) != -1)
  306.         retval.append((char) c);
  307.     } catch (IOException e) {
  308.       e.printStackTrace();
  309.     } catch (InterruptedException e) {
  310.       e.printStackTrace();
  311.     }
  312.     return retval;
  313.   }
  314.   /**
  315.    * Runs a shell command in the system and provides a StringBuffer
  316.    * with the output of the command.
  317.    * 
  318.    *  @param cmd the command to run 
  319.    *  
  320.    *  @return a StringBuffer that contains the output of the command 
  321.    */
  322.   public static StringBuffer runCommand(String cmd) {
  323.     return runCommand(cmd.split("\s+"));
  324.   }
  325.   /**
  326.    * Determines the greatest common divisor (GCD) of two integers.
  327.    * 
  328.    *  @param m the first integer
  329.    *  @param n the second integer
  330.    *  
  331.    *  @return the greatest common divisor of m and n
  332.    */
  333.   public static int gcd(int m, int n) {
  334.     if (m == 0 && n == 0)
  335.       return 0;
  336.     if (m < n) {
  337.       int t = m;
  338.       m = n;
  339.       n = t;
  340.     }
  341.     int r = m % n;
  342.     if (r == 0) {
  343.       return n;
  344.     } else {
  345.       return gcd(n, r);
  346.     }
  347.   }
  348.   /**
  349.    * Determines the greatest common divisor (GCD) of a list
  350.    * of integers.
  351.    * 
  352.    *  @param numbers the list of integers to process
  353.    *  
  354.    *  @return the greatest common divisor of all numbers
  355.    */
  356.   public static int gcd(int[] numbers) {
  357.     if (numbers.length == 1)
  358.       return numbers[0];
  359.     int g = gcd(numbers[0], numbers[1]);
  360.     for (int i = 2; i < numbers.length; i++)
  361.       g = gcd(g, numbers[i]);
  362.     return g;
  363.   }
  364.   private static String [] expandDirs(String [] input, String patternStr) {
  365.     ArrayList<String> fnames = new ArrayList<String>();
  366.     Pattern pattern = Pattern.compile(patternStr);
  367.     Matcher matcher;
  368.     File f;
  369.     
  370.     for (String fname : input) {
  371.       f = new File(fname);
  372.       if (f.exists()) {
  373. if (f.isDirectory()) {
  374.   // add all matching files
  375.   File [] fcs = f.listFiles();
  376.   for (File fc : fcs) {
  377.     matcher = pattern.matcher(fc.getName());
  378.     if (matcher.find() && fc.isFile())
  379.       fnames.add(fc.getAbsolutePath());
  380.   }
  381. } else {
  382.   // normal file, just add to output
  383.   fnames.add(f.getAbsolutePath());
  384. }
  385.       }
  386.     }
  387.     return fnames.toArray(input);
  388.   }
  389.   private static int setValue(String propname, int defaultValue) {
  390.     String v = getProperty(propname);
  391.     if (v != null)
  392.       return Integer.parseInt(v);
  393.     else
  394.       return defaultValue;
  395.   }
  396.   
  397.   public static void logInfo(String str) {
  398.     LOG.info(str);
  399.   }
  400. }