All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.counters.linux.SysstatUtil Maven / Gradle / Ivy

/*

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/
/*
 * Created on May 9, 2008
 */

package com.bigdata.counters.linux;

import org.apache.log4j.Logger;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * Some utility methods related to integration with sysstat.
 * 
 * @author Bryan Thompson
 * @version $Id$
 */
public class SysstatUtil {

    final private static Logger log = Logger.getLogger(SysstatUtil.class);

    public interface Options {
        /**
         * The name of the optional property whose value specifies the default
         * location of the SYSSTAT package (pidstat, iostat, etc) (default
         * {@value #DEFAULT_PATH}).
         * 
         * @see #DEFAULT_PATH
         */
        String PATH = "com.bigdata.counters.linux.sysstat.path";
    	
        String DEFAULT_PATH = "/usr/bin";
    }

	/**
	 * Returns the path to the specified sysstat utility (pidstat, sar, etc).
	 * The default is directory is {@value Options#DEFAULT_PATH}. This may be
	 * overridden using the {@value Options#PATH} property. The following
	 * directories are also searched if the program is not found in the
	 * configured default location:
	 * 
    *
  • /usr/bin
  • *
  • /usr/local/bin
  • *
* * @return The path to the specified utility. If the utility was not found, * then the configured path to the utility will be returned anyway. */ static public final File getPath(final String cmd) { File f, path; final File configuredPath = path = new File(System.getProperty( Options.PATH, Options.DEFAULT_PATH)); if (log.isInfoEnabled()) log.info(Options.PATH + "=" + configuredPath); if (!(f=new File(path, cmd)).exists() && true) { log.warn("Not found: " + f); path = new File("/usr/bin"); if (!(f = new File(path, cmd)).exists()) { log.warn("Not found: " + f); path = new File("/usr/local/bin"); if (!(f = new File(path, cmd)).exists()) { log.warn("Not found: " + f); log.error("Could not locate: '" + cmd + "'. Set '-D" + Options.PATH + "=
'"); // restore default even though not found. path = configuredPath; } } } if (configuredPath != path) { log.warn("Using effective path: " + Options.PATH + "=" + path); } return new File(path, cmd); } /** * Splits a data line into fields based on whitespace and skipping over the * date field (index zero (0) is the index of the first non-date field). *

* Note: Some fields can overflow, e.g., RSS. When this happens the fields * in the data lines wind up eating into the whitespace to their * right. This means that it is more robust to split the lines * based on whitespace once we have skipped over the date field. Since we * specify using {@link PIDStatCollector#setEnvironment(Map)} that we want * an ISO date format, we know that the date field is 11 characters. The * data lines are broken up by whitespace after that. *

* Note: Since we split on whitespace, the resulting strings are already * trimmed. * * @return The fields. */ static public String[] splitDataLine(final String data) { // split into fields final String[] fields = data.trim().split("\\s+"); if(log.isDebugEnabled()) { log.debug("fields="+Arrays.toString(fields)); } return fields; } /** * Takes header and data lines and generates a Map from them * * * @return a Map where keys are fields names and values are fields values. */ static public Map getDataMap(final String header, final String data) { Map fields = new HashMap<>(); final String[] header_fields = SysstatUtil.splitDataLine(header); final String[] data_fields = SysstatUtil.splitDataLine(data); if ( header_fields.length != data_fields.length ) { throw new IllegalArgumentException("Different fields count in header and data"); } for (int i = 0; i < header_fields.length; i++) { fields.put(header_fields[i], data_fields[i]); } return fields; } /** * Used to parse the timestamp associated with each row of sysstat output. *

* Note: This assumes that you have controlled the date format using the * sysstat ISO date option. *

* Note: This is not thread-safe - use a distinct instance for each * {@link PIDStatCollector} or {@link SarCpuUtilizationCollector}. * * @deprecated sysstat only reports the TIME OF DAY. In order to get the UTC * time it has to be corrected by the UTC time of the start of * the current day. Since very little latency is expected * between the report by sysstat of its performance counters and * the parsing of those performance counters by our code, it is * MUCH easier and more robust to simply use the current time as * reported by {@link System#currentTimeMillis()}. */ static public DateFormat newDateFormat() { return new SimpleDateFormat("hh:mm:ss aa"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy