Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 89734200B66 for ; Thu, 18 Aug 2016 18:30:55 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 87F0A160AAE; Thu, 18 Aug 2016 16:30:55 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 09782160ABF for ; Thu, 18 Aug 2016 18:30:52 +0200 (CEST) Received: (qmail 39620 invoked by uid 500); 18 Aug 2016 16:30:52 -0000 Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.incubator.apache.org Delivered-To: mailing list commits@geode.incubator.apache.org Received: (qmail 39611 invoked by uid 99); 18 Aug 2016 16:30:52 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Aug 2016 16:30:52 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 97EDE1A13B6 for ; Thu, 18 Aug 2016 16:30:51 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.646 X-Spam-Level: X-Spam-Status: No, score=-4.646 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx2-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id cdRpcBTvEMEx for ; Thu, 18 Aug 2016 16:30:42 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx2-lw-eu.apache.org (ASF Mail Server at mx2-lw-eu.apache.org) with SMTP id 1307C60DED for ; Thu, 18 Aug 2016 16:30:36 +0000 (UTC) Received: (qmail 38476 invoked by uid 99); 18 Aug 2016 16:30:36 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Aug 2016 16:30:36 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 16E7BE08E8; Thu, 18 Aug 2016 16:30:36 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: klund@apache.org To: commits@geode.incubator.apache.org Date: Thu, 18 Aug 2016 16:30:44 -0000 Message-Id: In-Reply-To: <1713cc67935c40e5beffaccd9066166a@git.apache.org> References: <1713cc67935c40e5beffaccd9066166a@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [10/24] incubator-geode git commit: GEODE-1781: refactor internal statistics classes archived-at: Thu, 18 Aug 2016 16:30:55 -0000 http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeImpl.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeImpl.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeImpl.java new file mode 100644 index 0000000..a338dfb --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeImpl.java @@ -0,0 +1,258 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import com.gemstone.gemfire.*; +import com.gemstone.gemfire.internal.i18n.LocalizedStrings; + +import java.io.*; +import java.util.*; + +/** + * Gathers together a number of {@link StatisticDescriptor statistics} + * into one logical type. + * + * @see Statistics + * + * + * @since GemFire 3.0 + */ +public class StatisticsTypeImpl implements StatisticsType { + + /** The name of this statistics type */ + private final String name; + + /** The description of this statistics type */ + private final String description; + + /** The descriptions of the statistics in id order */ + private final StatisticDescriptor[] stats; + + /** Maps a stat name to its StatisticDescriptor */ + private final HashMap statsMap; + + /** Contains the number of 32-bit statistics in this type. */ + private final int intStatCount; + + /** Contains the number of long statistics in this type. */ + private final int longStatCount; + + /** Contains the number of double statistics in this type. */ + private final int doubleStatCount; + + ///////////////////// Static Methods ///////////////////// + + /** + * @see StatisticsTypeXml#read(Reader, StatisticsTypeFactory) + */ + public static StatisticsType[] fromXml(Reader reader, + StatisticsTypeFactory factory) + throws IOException { + return (new StatisticsTypeXml()).read(reader, factory); + } + + ////////////////////// Constructors ////////////////////// + + /** + * Creates a new StatisticsType with the given name, + * description, and statistics. + * + * @param name + * The name of this statistics type (for example, + * "DatabaseStatistics") + * @param description + * A description of this statistics type (for example, + * "Information about the application's use of the + * database"). + * @param stats + * Descriptions of the individual statistics grouped together + * in this statistics type. + * + * @throws NullPointerException + * If either name or stats is + * null. + */ + public StatisticsTypeImpl(String name, String description, + StatisticDescriptor[] stats) { + this(name, description, stats, false); + } + + /** + * Creates a new StatisticsType with the given name, + * description, and statistics. + * + * @param name + * The name of this statistics type (for example, + * "DatabaseStatistics") + * @param description + * A description of this statistics type (for example, + * "Information about the application's use of the + * database"). + * @param stats + * Descriptions of the individual statistics grouped together + * in this statistics type. + * @param wrapsSharedClass + * True if this type is a wrapper around a SharedClass??. + * False if its a dynamic type created at run time. + * + * @throws NullPointerException + * If either name or stats is + * null. + */ + public StatisticsTypeImpl(String name, String description, + StatisticDescriptor[] stats, boolean wrapsSharedClass) { + if (name == null) { + throw new NullPointerException(LocalizedStrings.StatisticsTypeImpl_CANNOT_HAVE_A_NULL_STATISTICS_TYPE_NAME.toLocalizedString()); + } + + if (stats == null) { + throw new NullPointerException(LocalizedStrings.StatisticsTypeImpl_CANNOT_HAVE_A_NULL_STATISTIC_DESCRIPTORS.toLocalizedString()); + } + if (stats.length > StatisticsTypeFactory.MAX_DESCRIPTORS_PER_TYPE) { + throw new IllegalArgumentException(LocalizedStrings.StatisticsTypeImpl_THE_REQUESTED_DESCRIPTOR_COUNT_0_EXCEEDS_THE_MAXIMUM_WHICH_IS_1.toLocalizedString(new Object[] {Integer.valueOf(stats.length), Integer.valueOf(StatisticsTypeFactory.MAX_DESCRIPTORS_PER_TYPE)})); + } + + this.name = name; + this.description = description; + this.stats = stats; + this.statsMap = new HashMap(stats.length*2); + int intCount = 0; + int longCount = 0; + int doubleCount = 0; + for (int i=0; i < stats.length; i++) { + StatisticDescriptorImpl sd = (StatisticDescriptorImpl)stats[i]; + if (sd.getTypeCode() == StatisticDescriptorImpl.INT) { + if (!wrapsSharedClass) { + sd.setId(intCount); + } + intCount++; + } else if (sd.getTypeCode() == StatisticDescriptorImpl.LONG) { + if (!wrapsSharedClass) { + sd.setId(longCount); + } + longCount++; + } else if (sd.getTypeCode() == StatisticDescriptorImpl.DOUBLE) { + if (!wrapsSharedClass) { + sd.setId(doubleCount); + } + doubleCount++; + } + Object previousValue = statsMap.put(stats[i].getName(), sd); + if (previousValue != null) { + throw new IllegalArgumentException(LocalizedStrings.StatisticsTypeImpl_DUPLICATE_STATISTICDESCRIPTOR_NAMED_0.toLocalizedString(stats[i].getName())); + } + } + this.intStatCount = intCount; + this.longStatCount = longCount; + this.doubleStatCount = doubleCount; + } + + ////////////////////// StatisticsType Methods ////////////////////// + + public final String getName() { + return this.name; + } + + public final String getDescription() { + return this.description; + } + + public final StatisticDescriptor[] getStatistics() { + return this.stats; + } + + public final int nameToId(String name) { + return nameToDescriptor(name).getId(); + } + + public final StatisticDescriptor nameToDescriptor(String name) { + StatisticDescriptorImpl stat = (StatisticDescriptorImpl)statsMap.get(name); + if (stat == null) { + throw new IllegalArgumentException(LocalizedStrings.StatisticsTypeImpl_THERE_IS_NO_STATISTIC_NAMED_0.toLocalizedString(name)); + } + return stat; + } + + ////////////////////// Instance Methods ////////////////////// + + /** + * Gets the number of statistics in this type that are ints. + */ + public int getIntStatCount() { + return this.intStatCount; + } + /** + * Gets the number of statistics in this type that are longs. + */ + public int getLongStatCount() { + return this.longStatCount; + } + /** + * Gets the number of statistics that are doubles. + */ + public int getDoubleStatCount() { + return this.doubleStatCount; + } + +// @Override +// public String toString() { +// return "StatisticType with " + this.stats.length + " stats"; +// } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(getClass().getName()); + sb.append("@").append(System.identityHashCode(this)).append("{"); + sb.append("name=").append(this.name); + sb.append(", description=").append(this.description); + sb.append(", stats.length=").append(this.stats.length); + sb.append("}"); + return sb.toString(); + } + + @Override + public int hashCode() { + return getName().hashCode(); + } + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!(o instanceof StatisticsType)) { + return false; + } + StatisticsType other = (StatisticsType)o; + if (!getName().equals(other.getName())) { + return false; + } + if (!getDescription().equals(other.getDescription())) { + return false; + } + StatisticDescriptor[] myStats = getStatistics(); + StatisticDescriptor[] yourStats = other.getStatistics(); + if (myStats.length != yourStats.length) { + return false; + } + for (int i=0; i < myStats.length; i++) { + if (!myStats[i].equals(yourStats[i])) { + return false; + } + } + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeXml.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeXml.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeXml.java new file mode 100644 index 0000000..3fa1796 --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/StatisticsTypeXml.java @@ -0,0 +1,282 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import com.gemstone.gemfire.*; +import com.gemstone.gemfire.internal.Assert; +import com.gemstone.gemfire.internal.ClassPathLoader; +import com.gemstone.gemfire.internal.i18n.LocalizedStrings; + +import java.io.*; +import java.util.*; +import javax.xml.parsers.*; +//import javax.xml.transform.*; +//import javax.xml.transform.dom.*; +//import javax.xml.transform.stream.*; +import org.w3c.dom.*; +import org.xml.sax.*; + +// @todo davidw Use a SAX parser instead of DOM +/** + * This is an internal helper class for dealing with the + * SessionFactory XML configuration files. + */ +public class StatisticsTypeXml + implements EntityResolver, ErrorHandler { + + /** The name of the DTD file */ + static final String DTD = "statisticsType.dtd"; + + static final String systemId = "http://www.gemstone.com/dtd/" + DTD; + static final String publicId = + "-//GemStone Systems, Inc.//GemFire StatisticsType//EN"; + + ///////////////////// Interface methods /////////////////////// + + /** + * Given a publicId, attempts to resolve it to a DTD. Returns an + * InputSource for the DTD. + */ + public InputSource resolveEntity (String publicId, String systemId) + throws SAXException { + + // Figure out the location for the publicId. Be tolerant of other + // versions of the dtd + if(publicId.equals(StatisticsTypeXml.publicId) || + systemId.equals(StatisticsTypeXml.systemId) || + systemId.endsWith(DTD)) { + + // Public ID for system config DTD + String location = "/com/gemstone/gemfire/" + DTD; + InputStream stream = ClassPathLoader.getLatest().getResourceAsStream(getClass(), location); + if (stream != null) { + return new InputSource(stream); + + } else { + throw new SAXNotRecognizedException(LocalizedStrings.StatisticsTypeXml_DTD_NOT_FOUND_0.toLocalizedString(location)); + } + + } else { + throw new SAXNotRecognizedException(LocalizedStrings.StatisticsTypeXml_INVALID_PUBLIC_ID_0.toLocalizedString(publicId)); + } + } + + public void warning(SAXParseException exception) throws SAXException + { + // We don't want to thrown an exception. We want to log it!! + // FIXME +// String s = "SAX warning while working with XML"; + } + + public void error(SAXParseException exception) throws SAXException + { + throw new GemFireConfigException(LocalizedStrings.StatisticsTypeXml_SAX_ERROR_WHILE_WORKING_WITH_XML.toLocalizedString(), exception); + } + + public void fatalError(SAXParseException exception) throws SAXException + { + throw new GemFireConfigException(LocalizedStrings.StatisticsTypeXml_SAX_FATAL_ERROR_WHILE_WORKING_WITH_XML.toLocalizedString(), exception); + } + + ////////////////////// Parsing XML File //////////////////////// + + /** + * Parses the contents of XML data and from it creates one or more + * StatisticsType instances. + */ + public StatisticsType[] read( Reader reader, StatisticsTypeFactory statFactory) { + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); +// factory.setValidating(validate); + + DocumentBuilder parser = null; + try { + parser = factory.newDocumentBuilder(); + + } catch (ParserConfigurationException ex) { + throw new GemFireConfigException(LocalizedStrings.StatisticsTypeXml_FAILED_PARSING_XML.toLocalizedString(), ex); + } + + parser.setErrorHandler(this); + parser.setEntityResolver(this); + Document doc; + try { + doc = parser.parse(new InputSource(reader)); + } catch (SAXException se) { + throw new GemFireConfigException(LocalizedStrings.StatisticsTypeXml_FAILED_PARSING_XML.toLocalizedString(), se); + } catch (IOException io) { + throw new GemFireConfigException(LocalizedStrings.StatisticsTypeXml_FAILED_READING_XML_DATA.toLocalizedString(), io); + } + + if (doc == null) { + throw new GemFireConfigException(LocalizedStrings.StatisticsTypeXml_FAILED_READING_XML_DATA_NO_DOCUMENT.toLocalizedString()); + } + Element root = doc.getDocumentElement(); + if (root == null) { + throw new GemFireConfigException(LocalizedStrings.StatisticsTypeXml_FAILED_READING_XML_DATA_NO_ROOT_ELEMENT.toLocalizedString()); + } + return extractStatistics(root, statFactory); + } + + /* + * + */ + private StatisticsType[] extractStatistics(Element root, StatisticsTypeFactory statFactory) { + Assert.assertTrue(root.getTagName().equals("statistics")); + + ArrayList types = new ArrayList(); + NodeList typeNodes = root.getElementsByTagName("type"); + for (int i = 0; i < typeNodes.getLength(); i++) { + Element typeNode = (Element) typeNodes.item(i); + types.add(extractType(typeNode, statFactory)); + } + return (StatisticsType[])types.toArray(new StatisticsType[types.size()]); + } + /** + * + * + */ + private StatisticsType extractType(Element typeNode, StatisticsTypeFactory statFactory) { + Assert.assertTrue(typeNode.getTagName().equals("type")); + Assert.assertTrue(typeNode.hasAttribute("name")); + + final String typeName = typeNode.getAttribute("name"); + ArrayList stats = new ArrayList(); + NodeList statNodes = typeNode.getElementsByTagName("stat"); + for (int i = 0; i < statNodes.getLength(); i++) { + Element statNode = (Element) statNodes.item(i); + stats.add(extractStat(statNode, statFactory)); + } + StatisticDescriptor[] descriptors = + (StatisticDescriptor[])stats.toArray(new StatisticDescriptor[stats.size()]); + String description = ""; + { + NodeList descriptionNodes = typeNode.getElementsByTagName("description"); + if (descriptionNodes.getLength() > 0) { + // descriptionNodes will contain the both our description, if it exists, + // and any nested stat descriptions. Ours will always be first + Element descriptionNode = (Element) descriptionNodes.item(0); + // but make sure the first one belongs to our node + if (descriptionNode.getParentNode().getNodeName().equals(typeNode.getNodeName())) { + description = extractDescription(descriptionNode); + } + } + } + + return statFactory.createType(typeName, description, descriptors); + } + private final static int INT_STORAGE = 0; + private final static int LONG_STORAGE = 1; + private final static int DOUBLE_STORAGE = 2; + /** + * + * + */ + private StatisticDescriptor extractStat(Element statNode, StatisticsTypeFactory statFactory) { + Assert.assertTrue(statNode.getTagName().equals("stat")); + Assert.assertTrue(statNode.hasAttribute("name")); + + final String statName = statNode.getAttribute("name"); + String description = ""; + String unit = ""; + boolean isCounter = true; + boolean largerBetter; + int storage = INT_STORAGE; + + if ( statNode.hasAttribute("counter")) { + String value = statNode.getAttribute("counter"); + Assert.assertTrue(value.equalsIgnoreCase("true") || + value.equalsIgnoreCase("false")); + isCounter = Boolean.valueOf(value).booleanValue(); + } + largerBetter = isCounter; // default + if ( statNode.hasAttribute("largerBetter")) { + String value = statNode.getAttribute("largerBetter"); + Assert.assertTrue(value.equalsIgnoreCase("true") || + value.equalsIgnoreCase("false")); + largerBetter = Boolean.valueOf(value).booleanValue(); + } + if ( statNode.hasAttribute("storage")) { + String value = statNode.getAttribute("storage"); + if (value.equalsIgnoreCase("int")) { + storage = INT_STORAGE; + } else if (value.equalsIgnoreCase("long")) { + storage = LONG_STORAGE; + } else { + Assert.assertTrue(value.equalsIgnoreCase("double")); + storage = DOUBLE_STORAGE; + } + } + { + NodeList descriptionNodes = + statNode.getElementsByTagName("description"); + Assert.assertTrue(descriptionNodes.getLength() <= 1); + if (descriptionNodes.getLength() == 1) { + Element descriptionNode = (Element) descriptionNodes.item(0); + description = extractDescription(descriptionNode); + } + } + + { + NodeList unitNodes = + statNode.getElementsByTagName("unit"); + Assert.assertTrue(unitNodes.getLength() <= 1); + if (unitNodes.getLength() == 1) { + Element unitNode = (Element) unitNodes.item(0); + unit = extractUnit(unitNode); + } + } + if (isCounter) { + switch (storage) { + case INT_STORAGE: return statFactory.createIntCounter(statName, description, unit, largerBetter); + case LONG_STORAGE: return statFactory.createLongCounter(statName, description, unit, largerBetter); + case DOUBLE_STORAGE: return statFactory.createDoubleCounter(statName, description, unit, largerBetter); + default: throw new RuntimeException(LocalizedStrings.StatisticsTypeXml_UNEXPECTED_STORAGE_TYPE_0.toLocalizedString(Integer.valueOf(storage))); + } + } else { + switch (storage) { + case INT_STORAGE: return statFactory.createIntGauge(statName, description, unit, largerBetter); + case LONG_STORAGE: return statFactory.createLongGauge(statName, description, unit, largerBetter); + case DOUBLE_STORAGE: return statFactory.createDoubleGauge(statName, description, unit, largerBetter); + default: throw new RuntimeException(LocalizedStrings.StatisticsTypeXml_UNEXPECTED_STORAGE_TYPE_0.toLocalizedString(Integer.valueOf(storage))); + } + } + } + /** + * + */ + private String extractDescription(Element descriptionNode) { + Assert.assertTrue(descriptionNode.getTagName().equals("description")); + return extractText(descriptionNode); + } + /** + * + */ + private String extractUnit(Element unitNode) { + Assert.assertTrue(unitNode.getTagName().equals("unit")); + return extractText(unitNode); + } + private String extractText(Element element) { + Text text = (Text) element.getFirstChild(); + return((text == null ? "" : text.getData())); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStats.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStats.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStats.java new file mode 100644 index 0000000..8f441f5 --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStats.java @@ -0,0 +1,87 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import com.gemstone.gemfire.*; + +/** + * Statistics related to a Java VM. Currently they all come from + * {@link java.lang.Runtime}. + */ +public class VMStats implements VMStatsContract { + private final static StatisticsType vmType; + private final static int cpusId; + private final static int freeMemoryId; + private final static int totalMemoryId; + private final static int maxMemoryId; + static { + StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton(); + vmType = f.createType("VMStats", + "Stats available on any java virtual machine.", + new StatisticDescriptor[] { + f.createIntGauge("cpus", + "Number of cpus available to the java VM on its machine.", + "cpus", true), + f.createLongGauge("freeMemory", + "An approximation fo the total amount of memory currently available for future allocated objects, measured in bytes.", + "bytes", true), + f.createLongGauge("totalMemory", + "The total amount of memory currently available for current and future objects, measured in bytes.", + "bytes"), + f.createLongGauge("maxMemory", + "The maximum amount of memory that the VM will attempt to use, measured in bytes.", + "bytes", true) + }); + cpusId = vmType.nameToId("cpus"); + freeMemoryId = vmType.nameToId("freeMemory"); + totalMemoryId = vmType.nameToId("totalMemory"); + maxMemoryId = vmType.nameToId("maxMemory"); + } + + private final Statistics vmStats; + + + public VMStats(StatisticsFactory f, long id) { + this.vmStats = f.createStatistics(vmType, "vmStats", id); + } + + public void refresh() { + Runtime rt = Runtime.getRuntime(); + this.vmStats.setInt(cpusId, rt.availableProcessors()); + this.vmStats.setLong(freeMemoryId, rt.freeMemory()); + this.vmStats.setLong(totalMemoryId, rt.totalMemory()); + this.vmStats.setLong(maxMemoryId, rt.maxMemory()); + + } + public void close() { + this.vmStats.close(); + } + + /* (non-Javadoc) + * @see com.gemstone.gemfire.internal.statistics.VMStatsContract#getFdsOpen() + */ + public long getFdsOpen() { + return -1; + } + + /* (non-Javadoc) + * @see com.gemstone.gemfire.internal.statistics.VMStatsContract#getFdLimit() + */ + public long getFdLimit() { + return 0; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContract.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContract.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContract.java new file mode 100644 index 0000000..1870f27 --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContract.java @@ -0,0 +1,36 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +/** + * Describes the contract a VMStats implementation must implement. + *

I named this VMStatsContract because an implementation named + * VMStats already exists and I didn't want to rename it because + * of the svn merge issues. + * @see VMStatsContractFactory + */ +public interface VMStatsContract { + /** + * Called by sampler when it wants the VMStats statistics values to be + * refetched from the system. + */ + public void refresh(); + /** + * Called by sampler when it wants the VMStats to go away. + */ + public void close(); +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContractFactory.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContractFactory.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContractFactory.java new file mode 100644 index 0000000..4555683 --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/VMStatsContractFactory.java @@ -0,0 +1,60 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics; + +import com.gemstone.gemfire.*; +import com.gemstone.gemfire.internal.stats50.VMStats50; + +/** + * Factory used to produce an instance of VMStatsContract. + */ +public class VMStatsContractFactory { + /** + * Create and return a VMStatsContract. + */ + public static VMStatsContract create(StatisticsFactory f, long id) { + VMStatsContract result; + try { + result = new VMStats50(f, id); + } + catch (VirtualMachineError err) { + SystemFailure.initiateFailure(err); + // If this ever returns, rethrow the error. We're poisoned + // now, so don't let this thread continue. + throw err; + } + catch (Throwable ignore) { + // Now that we no longer support 1.4 I'm not sure why we would get here. + // But just in case other vm vendors don't support mxbeans I've left + // this logic in that will create a simple VMStats instance. + // Whenever you catch Error or Throwable, you must also + // catch VirtualMachineError (see above). However, there is + // _still_ a possibility that you are dealing with a cascading + // error condition, so you also need to check to see if the JVM + // is still usable: + SystemFailure.checkFailure(); + //log.warning("Could not create 5.0 VMStats", ignore); + // couldn't create the 1.5 version so create the old 1.4 version + result = new VMStats(f, id); + } + return result; + } + + private VMStatsContractFactory() { + // private so no instances allowed. static methods only + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/ValueMonitor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/ValueMonitor.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/ValueMonitor.java index 211719f..725abb2 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/ValueMonitor.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/ValueMonitor.java @@ -23,7 +23,6 @@ import java.util.Map; import com.gemstone.gemfire.StatisticDescriptor; import com.gemstone.gemfire.Statistics; import com.gemstone.gemfire.internal.CopyOnWriteHashSet; -import com.gemstone.gemfire.internal.StatisticDescriptorImpl; /** * Adds coarser-grained monitoring of entire Statistics instances. http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/package.html ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/package.html b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/package.html index 8875df2..4cb2d4f 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/package.html +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/package.html @@ -23,8 +23,8 @@ enhancements including the ability to monitor statistics. In addition, this package is temporarily home for new external API classes that may eventually be included in com.gemstone.gemfire.statistics. The original specification is the - -7.0 Statistics API Specification. + +Statistics API.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcFsStatistics.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcFsStatistics.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcFsStatistics.java new file mode 100644 index 0000000..1ce57a7 --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcFsStatistics.java @@ -0,0 +1,783 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics.platform; + +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import org.apache.logging.log4j.Logger; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class LinuxProcFsStatistics { + private enum CPU { + USER, NICE, SYSTEM, IDLE, IOWAIT, IRQ, SOFTIRQ, + /** stands for aggregation of all columns not present in the enum list*/ + OTHER + } + + private static final int DEFAULT_PAGESIZE = 4 * 1024; + private static final int OneMeg = 1024 * 1024; + private static final String pageSizeProperty = DistributionConfig.GEMFIRE_PREFIX + "statistics.linux.pageSize"; + private static CpuStat cpuStatSingleton; + private static int pageSize; + private static int sys_cpus; + private static boolean hasProcVmStat; + private static boolean hasDiskStats; + static SpaceTokenizer st; + + /** The number of non-process files in /proc */ + private static int nonPidFilesInProc; + + /** /proc/stat tokens */ + private static final String CPU_TOKEN = "cpu "; + private static final String PAGE = "page "; + private static final String SWAP = "swap "; + private static final String CTXT = "ctxt "; + private static final String PROCESSES = "processes "; + + /** /proc/vmstat tokens */ + private static final String PGPGIN = "pgpgin "; + private static final String PGPGOUT = "pgpgout "; + private static final String PSWPIN = "pswpin "; + private static final String PSWPOUT = "pswpout "; + + //Do not create instances of this class + private LinuxProcFsStatistics() { + } + + public static int init() { // TODO: was package-protected + nonPidFilesInProc = getNumberOfNonProcessProcFiles(); + sys_cpus = Runtime.getRuntime().availableProcessors(); + pageSize = Integer.getInteger(pageSizeProperty, DEFAULT_PAGESIZE); + cpuStatSingleton = new CpuStat(); + hasProcVmStat = new File("/proc/vmstat").exists(); + hasDiskStats = new File("/proc/diskstats").exists(); + st = new SpaceTokenizer(); + return 0; + } + + public static void close() { // TODO: was package-protected + cpuStatSingleton = null; + st = null; + } + + public static void readyRefresh() { // TODO: was package-protected + } + + /* get the statistics for the specified process. + * ( pid_rssSize, pid_imageSize ) + * vsize is assumed to be in units of kbytes + * System property gemfire.statistics.pagesSize can be used to configure + * pageSize. This is the mem_unit member of the struct returned by sysinfo() + * + */ + public static void refreshProcess(int pid, int[] ints, long[] longs, double[] doubles) { // TODO: was package-protected + //Just incase a pid is not available + if(pid == 0) return; + InputStreamReader isr = null; + BufferedReader br = null; + try { + File file = new File( "/proc/" + pid + "/stat" ); + isr = new InputStreamReader( new FileInputStream( file )); + br = new BufferedReader(isr, 2048); + String line = br.readLine(); + if ( line == null ) { + return; + } + st.setString(line); + st.skipTokens(22); + ints[LinuxProcessStats.imageSizeINT] = (int) (st.nextTokenAsLong() / OneMeg); + ints[LinuxProcessStats.rssSizeINT] = (int) ((st.nextTokenAsLong()*pageSize)/OneMeg); + } catch ( NoSuchElementException nsee ) { + // It might just be a case of the process going away while we + // where trying to get its stats. + // So for now lets just ignore the failure and leave the stats + // as they are. + } catch ( IOException ioe ) { + // It might just be a case of the process going away while we + // where trying to get its stats. + // So for now lets just ignore the failure and leave the stats + // as they are. + } finally { + st.releaseResources(); + if(br != null) try { br.close(); } catch(IOException ignore) {} + } + } + + public static void refreshSystem(int[] ints, long[] longs, double[] doubles) { // TODO: was package-protected + ints[LinuxSystemStats.processesINT] = getProcessCount(); + ints[LinuxSystemStats.cpusINT] = sys_cpus; + InputStreamReader isr = null; + BufferedReader br = null; + try { + isr = new InputStreamReader( new FileInputStream( "/proc/stat" )); + br = new BufferedReader(isr); + String line = null; + while ( ( line = br.readLine() ) != null ) { + try { + if (line.startsWith(CPU_TOKEN)) { + int[] cpuData = cpuStatSingleton.calculateStats(line); + ints[LinuxSystemStats.cpuIdleINT] = cpuData[CPU.IDLE.ordinal()]; + ints[LinuxSystemStats.cpuNiceINT] = cpuData[CPU.NICE.ordinal()]; + ints[LinuxSystemStats.cpuSystemINT] = cpuData[CPU.SYSTEM.ordinal()]; + ints[LinuxSystemStats.cpuUserINT] = cpuData[CPU.USER.ordinal()]; + ints[LinuxSystemStats.iowaitINT] = cpuData[CPU.IOWAIT.ordinal()]; + ints[LinuxSystemStats.irqINT] = cpuData[CPU.IRQ.ordinal()]; + ints[LinuxSystemStats.softirqINT] = cpuData[CPU.SOFTIRQ.ordinal()]; + ints[LinuxSystemStats.cpuActiveINT] = 100 - cpuData[CPU.IDLE.ordinal()]; + ints[LinuxSystemStats.cpuNonUserINT] = cpuData[CPU.OTHER.ordinal()] + + cpuData[CPU.SYSTEM.ordinal()] + + cpuData[CPU.IOWAIT.ordinal()] + + cpuData[CPU.IRQ.ordinal()] + + cpuData[CPU.SOFTIRQ.ordinal()]; + } else if ( !hasProcVmStat && line.startsWith(PAGE)) { + int secondIndex = line.indexOf(" ", PAGE.length()); + longs[LinuxSystemStats.pagesPagedInLONG] = SpaceTokenizer.parseAsLong(line.substring(PAGE.length(), secondIndex)); + longs[LinuxSystemStats.pagesPagedOutLONG] = SpaceTokenizer.parseAsLong(line.substring(secondIndex+1)); + } else if ( !hasProcVmStat && line.startsWith(SWAP)) { + int secondIndex = line.indexOf(" ", SWAP.length()); + longs[LinuxSystemStats.pagesSwappedInLONG] = SpaceTokenizer.parseAsLong(line.substring(SWAP.length(), secondIndex)); + longs[LinuxSystemStats.pagesSwappedOutLONG] = SpaceTokenizer.parseAsLong(line.substring(secondIndex+1)); + } else if ( line.startsWith(CTXT)) { + longs[LinuxSystemStats.contextSwitchesLONG] = SpaceTokenizer.parseAsLong(line.substring(CTXT.length())); + } else if ( line.startsWith(PROCESSES)) { + longs[LinuxSystemStats.processCreatesLONG] = SpaceTokenizer.parseAsInt(line.substring(PROCESSES.length())); + } + } catch ( NoSuchElementException nsee ) { + //this is the result of reading a partially formed file + //just do not update what ever entry had the problem + } + } + } catch ( IOException ioe ) { + } finally { + if(br != null) try { br.close(); } catch(IOException ignore) {} + } + getLoadAvg(doubles); + getMemInfo(ints); + getDiskStats(longs); + getNetStats(longs); + if(hasProcVmStat) { + getVmStats(longs); + } + st.releaseResources(); + } + + // Example of /proc/loadavg + // 0.00 0.00 0.07 1/218 7907 + private static void getLoadAvg(double[] doubles) { + InputStreamReader isr = null; + BufferedReader br = null; + try { + isr = new InputStreamReader( new FileInputStream( "/proc/loadavg" )); + br = new BufferedReader(isr, 512); + String line = br.readLine(); + if ( line == null ) { + return; + } + st.setString(line); + doubles[LinuxSystemStats.loadAverage1DOUBLE] = st.nextTokenAsDouble(); + doubles[LinuxSystemStats.loadAverage5DOUBLE] = st.nextTokenAsDouble(); + doubles[LinuxSystemStats.loadAverage15DOUBLE] = st.nextTokenAsDouble(); + } catch ( NoSuchElementException nsee ) { + } catch (IOException ioe) { + } finally { + st.releaseResources(); + if(br != null) try { br.close(); } catch(IOException ignore) {} + } + } + + /** + * Returns the available system memory (free + cached). + * @param logger the logger + * @return the available memory in bytes + */ + public static long getAvailableMemory(Logger logger) { + try { + BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/meminfo"))); + try { + long free = 0; + Pattern p = Pattern.compile("(.*)?:\\s+(\\d+)( kB)?"); + + String line; + while ((line = br.readLine()) != null) { + Matcher m = p.matcher(line); + if (m.matches() && ("MemFree".equals(m.group(1)) || "Cached".equals(m.group(1)))) { + free += Long.parseLong(m.group(2)); + } + } + + // convert to bytes + return 1024 * free; + + } finally { + br.close(); + } + } catch (IOException e) { + logger.warn("Error determining free memory", e); + return Long.MAX_VALUE; + } + } + + // Example of /proc/meminfo + // total: used: free: shared: buffers: cached: + //Mem: 4118380544 3816050688 302329856 0 109404160 3060326400 + //Swap: 4194881536 127942656 4066938880 + private static void getMemInfo(int[] ints) { + InputStreamReader isr = null; + BufferedReader br = null; + try { + isr = new InputStreamReader( new FileInputStream( "/proc/meminfo" )); + br = new BufferedReader(isr); + //Assume all values read in are in kB, convert to MB + String line = null; + while ( (line = br.readLine()) != null) { + try { + if ( line.startsWith("MemTotal: ")) { + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.physicalMemoryINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("MemFree: ")) { + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.freeMemoryINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("SharedMem: ")) { + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.sharedMemoryINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("Buffers: ")) { + st.setString(line); + st.nextToken(); //Burn initial token + ints[LinuxSystemStats.bufferMemoryINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("SwapTotal: ")) { + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.allocatedSwapINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("SwapFree: ")) { + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.unallocatedSwapINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("Cached: ")) { + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.cachedMemoryINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("Dirty: ")) { + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.dirtyMemoryINT] = (int) (st.nextTokenAsLong() / 1024); + } else if ( line.startsWith("Inact_dirty: ")) { // 2.4 kernels + st.setString(line); + st.skipToken(); //Burn initial token + ints[LinuxSystemStats.dirtyMemoryINT] = (int) (st.nextTokenAsLong() / 1024); + } + } catch(NoSuchElementException nsee) { + //ignore and let that stat not to be updated this time + } + } + } catch ( IOException ioe ) { + } finally { + st.releaseResources(); + if(br != null) try { br.close(); } catch(IOException ignore) {} + } + } + + /* +Inter-| Receive | Transmit + face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed + lo:1908275823 326949246 0 0 0 0 0 0 1908275823 326949246 0 0 0 0 0 0 +*/ + + private static void getNetStats(long[] longs) { + InputStreamReader isr = null; + BufferedReader br = null; + try { + isr = new InputStreamReader( new FileInputStream( "/proc/net/dev" )); + br = new BufferedReader(isr); + br.readLine(); // Discard header info + br.readLine(); // Discard header info + long lo_recv_packets = 0, lo_recv_bytes = 0; + long other_recv_packets = 0, other_recv_bytes = 0; + long other_recv_errs = 0, other_recv_drop = 0; + long other_xmit_packets = 0, other_xmit_bytes = 0; + long other_xmit_errs = 0, other_xmit_drop = 0, other_xmit_colls = 0; + String line = null; + while ( (line = br.readLine()) != null) { + int index = line.indexOf(":"); + boolean isloopback = (line.indexOf("lo:") != -1); + st.setString(line.substring(index+1).trim()); + long recv_bytes = st.nextTokenAsLong(); + long recv_packets = st.nextTokenAsLong(); + long recv_errs = st.nextTokenAsLong(); + long recv_drop = st.nextTokenAsLong(); + st.skipTokens(4); //fifo, frame, compressed, multicast + long xmit_bytes = st.nextTokenAsLong(); + long xmit_packets = st.nextTokenAsLong(); + long xmit_errs = st.nextTokenAsLong(); + long xmit_drop = st.nextTokenAsLong(); + st.skipToken(); //fifo + long xmit_colls = st.nextTokenAsLong(); + + if (isloopback) { + lo_recv_packets = recv_packets; + lo_recv_bytes = recv_bytes; + } + else { + other_recv_packets += recv_packets; + other_recv_bytes += recv_bytes; + } + other_recv_errs += recv_errs; + other_recv_drop += recv_drop; + + if (isloopback) { + /* loopback_xmit_packets = xmit_packets; */ + } else { + other_xmit_packets += xmit_packets; + other_xmit_bytes += xmit_bytes; + } + other_xmit_errs += xmit_errs; + other_xmit_drop += xmit_drop; + other_xmit_colls += xmit_colls; + } + // fix for bug 43860 + longs[LinuxSystemStats.loopbackPacketsLONG] = lo_recv_packets; + longs[LinuxSystemStats.loopbackBytesLONG] = lo_recv_bytes; + longs[LinuxSystemStats.recvPacketsLONG] = other_recv_packets; + longs[LinuxSystemStats.recvBytesLONG] = other_recv_bytes; + longs[LinuxSystemStats.recvErrorsLONG] = other_recv_errs; + longs[LinuxSystemStats.recvDropsLONG] = other_recv_drop; + longs[LinuxSystemStats.xmitPacketsLONG] = other_xmit_packets; + longs[LinuxSystemStats.xmitBytesLONG] = other_xmit_bytes; + longs[LinuxSystemStats.xmitErrorsLONG] = other_xmit_errs; + longs[LinuxSystemStats.xmitDropsLONG] = other_xmit_drop; + longs[LinuxSystemStats.xmitCollisionsLONG] = other_xmit_colls; + } catch (NoSuchElementException nsee) { + } catch (IOException ioe) { + } finally { + st.releaseResources(); + if(br != null) try { br.close(); } catch(IOException ignore) {} + } + } + + // example of /proc/diskstats +// 1 0 ram0 0 0 0 0 0 0 0 0 0 0 0 +// 1 1 ram1 0 0 0 0 0 0 0 0 0 0 0 +// 1 2 ram2 0 0 0 0 0 0 0 0 0 0 0 +// 1 3 ram3 0 0 0 0 0 0 0 0 0 0 0 +// 1 4 ram4 0 0 0 0 0 0 0 0 0 0 0 +// 1 5 ram5 0 0 0 0 0 0 0 0 0 0 0 +// 1 6 ram6 0 0 0 0 0 0 0 0 0 0 0 +// 1 7 ram7 0 0 0 0 0 0 0 0 0 0 0 +// 1 8 ram8 0 0 0 0 0 0 0 0 0 0 0 +// 1 9 ram9 0 0 0 0 0 0 0 0 0 0 0 +// 1 10 ram10 0 0 0 0 0 0 0 0 0 0 0 +// 1 11 ram11 0 0 0 0 0 0 0 0 0 0 0 +// 1 12 ram12 0 0 0 0 0 0 0 0 0 0 0 +// 1 13 ram13 0 0 0 0 0 0 0 0 0 0 0 +// 1 14 ram14 0 0 0 0 0 0 0 0 0 0 0 +// 1 15 ram15 0 0 0 0 0 0 0 0 0 0 0 +// 8 0 sda 1628761 56603 37715982 5690640 6073889 34091137 330349716 279787924 0 25235208 285650572 +// 8 1 sda1 151 638 45 360 +// 8 2 sda2 674840 11202608 8591346 68716852 +// 8 3 sda3 1010409 26512312 31733575 253868616 +// 8 16 sdb 12550386 47814 213085738 60429448 5529812 210792345 1731459040 1962038752 0 33797176 2024138028 +// 8 17 sdb1 12601113 213085114 216407197 1731257800 +// 3 0 hda 0 0 0 0 0 0 0 0 0 0 0 + private static void getDiskStats(long[] longs) { + InputStreamReader isr = null; + BufferedReader br = null; + String line = null; + try { + if (hasDiskStats) { + // 2.6 kernel + isr = new InputStreamReader( new FileInputStream( "/proc/diskstats" )); + } else { + // 2.4 kernel + isr = new InputStreamReader( new FileInputStream( "/proc/partitions" )); + } + br = new BufferedReader(isr); + long readsCompleted = 0, readsMerged = 0; + long sectorsRead = 0, timeReading = 0; + long writesCompleted = 0, writesMerged = 0; + long sectorsWritten = 0, timeWriting = 0; + long iosInProgress = 0; + long timeIosInProgress = 0; + long ioTime = 0; + if (!hasDiskStats) { + br.readLine(); // Discard header info + br.readLine(); // Discard header info + } + while ( (line = br.readLine()) != null) { + st.setString(line); + { + // " 8 1 sdb" on 2.6 + // " 8 1 452145145 sdb" on 2.4 + String tok = st.nextToken(); + if (tok.length() == 0 || Character.isWhitespace(tok.charAt(0))) { + // skip over first token since it is whitespace + tok = st.nextToken(); + } + // skip first token it is some number + tok = st.nextToken(); + // skip second token it is some number + tok = st.nextToken(); + if (!hasDiskStats) { + // skip third token it is some number + tok = st.nextToken(); + } + // Now tok should be the device name. + if (Character.isDigit(tok.charAt(tok.length()-1))) { + // If the last char is a digit + // skip this line since it is a partition of a device; not a device. + continue; + } + } + long tmp_readsCompleted = st.nextTokenAsLong(); + long tmp_readsMerged = st.nextTokenAsLong(); + long tmp_sectorsRead = st.nextTokenAsLong(); + long tmp_timeReading = st.nextTokenAsLong(); + if (st.hasMoreTokens()) { + // If we are on 2.6 then we might only have 4 longs; if so ignore this line + // Otherwise we should have 11 long tokens. + long tmp_writesCompleted = st.nextTokenAsLong(); + long tmp_writesMerged = st.nextTokenAsLong(); + long tmp_sectorsWritten = st.nextTokenAsLong(); + long tmp_timeWriting = st.nextTokenAsLong(); + long tmp_iosInProgress = st.nextTokenAsLong(); + long tmp_timeIosInProgress = st.nextTokenAsLong(); + long tmp_ioTime = st.nextTokenAsLong(); + readsCompleted += tmp_readsCompleted; + readsMerged += tmp_readsMerged; + sectorsRead += tmp_sectorsRead; + timeReading += tmp_timeReading; + writesCompleted += tmp_writesCompleted; + writesMerged += tmp_writesMerged; + sectorsWritten += tmp_sectorsWritten; + timeWriting += tmp_timeWriting; + iosInProgress += tmp_iosInProgress; + timeIosInProgress += tmp_timeIosInProgress; + ioTime += tmp_ioTime; + } + } // while + final int SECTOR_SIZE = 512; + longs[LinuxSystemStats.readsCompletedLONG] = readsCompleted; + longs[LinuxSystemStats.readsMergedLONG] = readsMerged; + longs[LinuxSystemStats.bytesReadLONG] = sectorsRead * SECTOR_SIZE; + longs[LinuxSystemStats.timeReadingLONG] = timeReading; + longs[LinuxSystemStats.writesCompletedLONG] = writesCompleted; + longs[LinuxSystemStats.writesMergedLONG] = writesMerged; + longs[LinuxSystemStats.bytesWrittenLONG] = sectorsWritten * SECTOR_SIZE; + longs[LinuxSystemStats.timeWritingLONG] = timeWriting; + longs[LinuxSystemStats.iosInProgressLONG] = iosInProgress; + longs[LinuxSystemStats.timeIosInProgressLONG] = timeIosInProgress; + longs[LinuxSystemStats.ioTimeLONG] = ioTime; + } catch (NoSuchElementException nsee) { +// com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.getAnyInstance().getLoggerI18n().fine("unexpected NoSuchElementException line=" + line, nsee); + } catch (IOException ioe) { + } finally { + st.releaseResources(); + if(br != null) try { br.close(); } catch(IOException ignore) {} + } + } + + //Example of /proc/vmstat + //... + //pgpgin 294333738 + //pgpgout 1057420300 + //pswpin 19422 + //pswpout 14495 + private static void getVmStats(long[] longs) { + assert hasProcVmStat != false : "getVmStats called when hasVmStat was false"; + InputStreamReader isr = null; + BufferedReader br = null; + try { + isr = new InputStreamReader( new FileInputStream( "/proc/vmstat" )); + br = new BufferedReader(isr); + String line = null; + while((line = br.readLine()) != null) { + if(line.startsWith(PGPGIN)) { + longs[LinuxSystemStats.pagesPagedInLONG] + = SpaceTokenizer.parseAsLong(line.substring(PGPGIN.length())); + } else if(line.startsWith(PGPGOUT)) { + longs[LinuxSystemStats.pagesPagedOutLONG] + = SpaceTokenizer.parseAsLong(line.substring(PGPGOUT.length())); + } else if(line.startsWith(PSWPIN)) { + longs[LinuxSystemStats.pagesSwappedInLONG] + = SpaceTokenizer.parseAsLong(line.substring(PSWPIN.length())); + } else if(line.startsWith(PSWPOUT)) { + longs[LinuxSystemStats.pagesSwappedOutLONG] + = SpaceTokenizer.parseAsLong(line.substring(PSWPOUT.length())); + } + } + } catch (NoSuchElementException nsee) { + } catch (IOException ioe) { + } finally { + if(br != null) try { br.close(); } catch(IOException ignore) {} + } + } + + /** + * Count the number of files in /proc that do not represent processes. + * This value is cached to make counting the number of running process a + * cheap operation. The assumption is that the contents of /proc will not + * change on a running system. + * @return the files in /proc that do NOT match /proc/[0-9]* + */ + private static int getNumberOfNonProcessProcFiles() { + File proc = new File("/proc"); + String[] procFiles = proc.list(); + int count = 0; + if(procFiles != null) { + for(String filename : procFiles) { + char c = filename.charAt(0); + if(! Character.isDigit(c)) { + if (c == '.') { + // see if the next char is a digit + if (filename.length() > 1) { + char c2 = filename.charAt(1); + if (Character.isDigit(c2)) { + // for bug 42091 do not count files that begin with a '.' followed by digits + continue; + } + } + } + count++; + } + } + } + return count; + } + + /** + * @return the number of running processes on the system + */ + private static int getProcessCount() { + File proc = new File("/proc"); + String[] procFiles = proc.list(); + if(procFiles == null) { + //unknown error, continue without this stat + return 0; + } + return procFiles.length - nonPidFilesInProc; + } + + //The array indices must be ordered as they appear in /proc/stats + // (user) (nice) (system) (idle) (iowait) (irq) (softirq) + // cpu 42813766 10844 8889075 1450764512 49963779 808244 3084872 + // + private static class CpuStat { + private static boolean lastCpuStatsInvalid; + private static List lastCpuStats; + + public CpuStat() { + lastCpuStatsInvalid = true; + } + + public int[] calculateStats( String newStatLine ) { + st.setString(newStatLine); + st.skipToken(); //cpu name + final int MAX_CPU_STATS = CPU.values().length; + /* newer kernels now have 8 columns for cpu in + * /proc/stat (up from 7). This number may increase + * even further, hence we now use List in place of long[]. + * We add up entries from all columns after 7 into CPU.OTHER + */ + List newStats = new ArrayList(8); + List diffs = new ArrayList(8); + long total_change = 0; + int actualCpuStats = 0; + long unaccountedCpuUtilization = 0; + + while (st.hasMoreTokens()) { + newStats.add(st.nextTokenAsLong()); + actualCpuStats++; + } + + if ( lastCpuStatsInvalid ) { + lastCpuStats = newStats; + lastCpuStatsInvalid = false; + for (int i=0; i 0 && skipToken()); + } + + protected static long parseAsLong(String number) { + long l = 0L; + try { + l = Long.parseLong(number); + } catch(NumberFormatException nfe) {} + return l; + } + + protected static int parseAsInt(String number) { + int i = 0; + try { + i = Integer.parseInt(number); + } catch(NumberFormatException nfe) {} + return i; + } + + protected int nextTokenAsInt() { + int i = 0; + try { + i = Integer.parseInt(nextToken()); + } catch(NumberFormatException nfe) {} + return i; + } + + protected long nextTokenAsLong() { + long l = 0L; + try { + l = Long.parseLong(nextToken()); + } catch(NumberFormatException nfe) {} + return l; + } + + protected double nextTokenAsDouble() { + double d = 0; + try { + d = Double.parseDouble(nextToken()); + } catch(NumberFormatException nfe) {} + return d; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcessStats.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcessStats.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcessStats.java new file mode 100644 index 0000000..ab4b78d --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxProcessStats.java @@ -0,0 +1,84 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics.platform; + +import com.gemstone.gemfire.*; +import com.gemstone.gemfire.internal.Assert; +import com.gemstone.gemfire.internal.statistics.HostStatHelper; +import com.gemstone.gemfire.internal.statistics.LocalStatisticsImpl; +import com.gemstone.gemfire.internal.statistics.StatisticsTypeFactoryImpl; +import com.gemstone.gemfire.internal.statistics.platform.ProcessStats; + +/** + *

This class provides the interface for statistics about a + * Linux operating system process that is using a GemFire system. + */ +public class LinuxProcessStats +{ + final static int imageSizeINT = 0; + final static int rssSizeINT = 1; + + private final static StatisticsType myType; + + private static void checkOffset(String name, int offset) { + int id = myType.nameToId(name); + Assert.assertTrue(offset == id, "Expected the offset for " + name + " to be " + offset + " but it was " + id); + } + + static { + StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton(); + myType = f.createType("LinuxProcessStats", + "Statistics on a Linux process.", + new StatisticDescriptor[] { + f.createIntGauge("imageSize", + "The size of the process's image in megabytes.", + "megabytes"), + f.createIntGauge("rssSize", + "The size of the process's resident set size in megabytes. (assumes PAGESIZE=4096, specify -Dgemfire.statistics.linux.pageSize= to adjust)", + "megabytes"), + }); + checkOffset("imageSize", imageSizeINT); + checkOffset("rssSize", rssSizeINT); + } + + private LinuxProcessStats() { + // no instances allowed + } + public static StatisticsType getType() { + return myType; + } + + /** + * Returns a ProcessStats that wraps Linux process + * Statistics. + * + * @since GemFire 3.5 + */ + public static ProcessStats createProcessStats(final Statistics stats) { // TODO: was package-protected + if (stats instanceof LocalStatisticsImpl) { + HostStatHelper.refresh((LocalStatisticsImpl) stats); + } // otherwise its a Dummy implementation so do nothing + return new ProcessStats(stats) { + @Override + public long getProcessSize() { + return stats.getInt(rssSizeINT); + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxSystemStats.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxSystemStats.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxSystemStats.java new file mode 100644 index 0000000..f50204e --- /dev/null +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/statistics/platform/LinuxSystemStats.java @@ -0,0 +1,313 @@ +/* + * 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 com.gemstone.gemfire.internal.statistics.platform; + +import com.gemstone.gemfire.*; +import com.gemstone.gemfire.internal.Assert; +import com.gemstone.gemfire.internal.statistics.StatisticsTypeFactoryImpl; + +/** + *

This class provides the interface for statistics about the + * Linux machine a GemFire system is running on. + */ +public class LinuxSystemStats +{ + + // shared fields + final static int allocatedSwapINT = 0; + final static int bufferMemoryINT = 1; + final static int sharedMemoryINT = 2; + final static int cpuActiveINT = 3; + final static int cpuIdleINT = 4; + final static int cpuNiceINT = 5; + final static int cpuSystemINT = 6; + final static int cpuUserINT = 7; + final static int iowaitINT = 8; + final static int irqINT = 9; + final static int softirqINT = 10; + final static int cpusINT = 11; + final static int freeMemoryINT = 12; + final static int physicalMemoryINT = 13; + final static int processesINT = 14; + final static int unallocatedSwapINT = 15; + final static int cachedMemoryINT = 16; + final static int dirtyMemoryINT = 17; + final static int cpuNonUserINT = 18; + + final static int loopbackPacketsLONG = 0; + final static int loopbackBytesLONG = 1; + final static int recvPacketsLONG = 2; + final static int recvBytesLONG = 3; + final static int recvErrorsLONG = 4; + final static int recvDropsLONG = 5; + final static int xmitPacketsLONG = 6; + final static int xmitBytesLONG = 7; + final static int xmitErrorsLONG = 8; + final static int xmitDropsLONG = 9; + final static int xmitCollisionsLONG = 10; + final static int contextSwitchesLONG = 11; + final static int processCreatesLONG = 12; + final static int pagesPagedInLONG = 13; + final static int pagesPagedOutLONG = 14; + final static int pagesSwappedInLONG = 15; + final static int pagesSwappedOutLONG = 16; + final static int readsCompletedLONG = 17; + final static int readsMergedLONG = 18; + final static int bytesReadLONG = 19; + final static int timeReadingLONG = 20; + final static int writesCompletedLONG = 21; + final static int writesMergedLONG = 22; + final static int bytesWrittenLONG = 23; + final static int timeWritingLONG = 24; + final static int iosInProgressLONG = 25; + final static int timeIosInProgressLONG = 26; + final static int ioTimeLONG = 27; + + final static int loadAverage1DOUBLE = 0; + final static int loadAverage15DOUBLE = 1; + final static int loadAverage5DOUBLE = 2; + + private final static StatisticsType myType; + + private static void checkOffset(String name, int offset) { + int id = myType.nameToId(name); + Assert.assertTrue(offset == id, "Expected the offset for " + name + " to be " + offset + " but it was " + id); + } + + static { + StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton(); + myType = f.createType("LinuxSystemStats", + "Statistics on a Linux machine.", + new StatisticDescriptor[] { + f.createIntGauge("allocatedSwap", + "The number of megabytes of swap space have actually been written to. Swap space must be reserved before it can be allocated.", + "megabytes"), + f.createIntGauge("bufferMemory", + "The number of megabytes of memory allocated to buffers.", + "megabytes"), + f.createIntGauge("sharedMemory", + "The number of megabytes of shared memory on the machine.", + "megabytes", true), + f.createIntGauge("cpuActive", + "The percentage of the total available time that has been used in a non-idle state.", + "%"), + f.createIntGauge("cpuIdle", + "The percentage of the total available time that has been spent sleeping.", + "%", true), + f.createIntGauge("cpuNice", + "The percentage of the total available time that has been used to execute user code in processes with low priority.", + "%"), + f.createIntGauge("cpuSystem", + "The percentage of the total available time that has been used to execute system (i.e. kernel) code.", + "%"), + f.createIntGauge("cpuUser", + "The percentage of the total available time that has been used to execute user code.", + "%"), + f.createIntGauge("iowait", + "The percentage of the total available time that has been used to wait for I/O to complete.", + "%"), + f.createIntGauge("irq", + "The percentage of the total available time that has been used servicing interrupts.", + "%"), + f.createIntGauge("softirq", + "The percentage of the total available time that has been used servicing softirqs.", + "%"), + f.createIntGauge("cpus", + "The number of online cpus on the local machine.", + "items"), + f.createIntGauge("freeMemory", + "The number of megabytes of unused memory on the machine.", + "megabytes", true), + f.createIntGauge("physicalMemory", + "The actual amount of total physical memory on the machine.", + "megabytes", true), + f.createIntGauge("processes", + "The number of processes in the computer at the time of data collection. Notice that this is an instantaneous count, not an average over the time interval. Each process represents the running of a program.", + "processes"), + f.createIntGauge("unallocatedSwap", + "The number of megabytes of swap space that have not been allocated.", + "megabytes", true), + f.createIntGauge("cachedMemory", + "The number of megabytes of memory used for the file system cache.", + "megabytes", true), + f.createIntGauge("dirtyMemory", + "The number of megabytes of memory in the file system cache that need to be written.", + "megabytes", true), + f.createIntGauge("cpuNonUser", + "The percentage of total available time that has been used to execute non-user code.(includes system, iowait, irq, softirq etc.)", + "%"), + + + f.createLongCounter("loopbackPackets", + "The number of network packets sent (or received) on the loopback interface", + "packets", false), + f.createLongCounter("loopbackBytes", + "The number of network bytes sent (or received) on the loopback interface", + "bytes", false), + f.createLongCounter("recvPackets", + "The total number of network packets received (excluding loopback)", + "packets", false), + f.createLongCounter("recvBytes", + "The total number of network bytes received (excluding loopback)", + "bytes", false), + f.createLongCounter("recvErrors", + "The total number of network receive errors", + "errors", false), + f.createLongCounter("recvDrops", + "The total number network receives dropped", + "packets", false), + f.createLongCounter("xmitPackets", + "The total number of network packets transmitted (excluding loopback)", + "packets", false), + f.createLongCounter("xmitBytes", + "The total number of network bytes transmitted (excluding loopback)", + "bytes", false), + f.createLongCounter("xmitErrors", + "The total number of network transmit errors", + "errors", false), + f.createLongCounter("xmitDrops", + "The total number of network transmits dropped", + "packets", false), + f.createLongCounter("xmitCollisions", + "The total number of network transmit collisions", + "collisions", false), + f.createLongCounter("contextSwitches", + "The total number of context switches from one thread to another on the computer. Thread switches can occur either inside of a single process or across processes. A thread switch may be caused either by one thread asking another for information, or by a thread being preempted by another, higher priority thread becoming ready to run.", + "operations", false), + f.createLongCounter("processCreates", + "The total number of times a process has been created.", + "operations", false), + f.createLongCounter("pagesPagedIn", + "The total number of pages that have been brought into memory from disk by the operating system's memory manager.", + "pages", false), + f.createLongCounter("pagesPagedOut", + "The total number of pages that have been flushed from memory to disk by the operating system's memory manager.", + "pages", false), + f.createLongCounter("pagesSwappedIn", + "The total number of swap pages that have been read in from disk by the operating system's memory manager.", + "pages", false), + f.createLongCounter("pagesSwappedOut", + "The total number of swap pages that have been written out to disk by the operating system's memory manager.", + "pages", false), + f.createLongCounter("diskReadsCompleted", + "The total number disk read operations completed successfully", + "ops"), + f.createLongCounter("diskReadsMerged", + "The total number disk read operations that were able to be merge with adjacent reads for efficiency", + "ops"), + f.createLongCounter("diskBytesRead", + "The total number bytes read from disk successfully", + "bytes"), + f.createLongCounter("diskTimeReading", + "The total number of milliseconds spent reading from disk", + "milliseconds"), + f.createLongCounter("diskWritesCompleted", + "The total number disk write operations completed successfully", + "ops"), + f.createLongCounter("diskWritesMerged", + "The total number disk write operations that were able to be merge with adjacent reads for efficiency", + "ops"), + f.createLongCounter("diskBytesWritten", + "The total number bytes written to disk successfully", + "bytes"), + f.createLongCounter("diskTimeWriting", + "The total number of milliseconds spent writing to disk", + "milliseconds"), + f.createLongGauge("diskOpsInProgress", + "The current number of disk operations in progress", + "ops"), + f.createLongCounter("diskTimeInProgress", + "The total number of milliseconds spent with disk ops in progress", + "milliseconds"), + f.createLongCounter("diskTime", + "The total number of milliseconds that measures both completed disk operations and any accumulating backlog of in progress ops.", + "milliseconds"), + + + f.createDoubleGauge("loadAverage1", + "The average number of threads in the run queue or waiting for disk I/O over the last minute.", + "threads"), + f.createDoubleGauge("loadAverage15", + "The average number of threads in the run queue or waiting for disk I/O over the last fifteen minutes.", + "threads"), + f.createDoubleGauge("loadAverage5", + "The average number of threads in the run queue or waiting for disk I/O over the last five minutes.", + "threads"), + }); + + checkOffset("allocatedSwap", allocatedSwapINT); + checkOffset("bufferMemory", bufferMemoryINT); + checkOffset("sharedMemory", sharedMemoryINT); + checkOffset("cpuActive", cpuActiveINT); + checkOffset("cpuIdle", cpuIdleINT); + checkOffset("cpuNice", cpuNiceINT); + checkOffset("cpuSystem", cpuSystemINT); + checkOffset("cpuUser", cpuUserINT); + checkOffset("iowait", iowaitINT); + checkOffset("irq", irqINT); + checkOffset("softirq", softirqINT); + checkOffset("cpus", cpusINT); + checkOffset("freeMemory", freeMemoryINT); + checkOffset("physicalMemory", physicalMemoryINT); + checkOffset("processes", processesINT); + checkOffset("unallocatedSwap", unallocatedSwapINT); + checkOffset("cachedMemory", cachedMemoryINT); + checkOffset("dirtyMemory", dirtyMemoryINT); + checkOffset("cpuNonUser", cpuNonUserINT); + + checkOffset("loopbackPackets", loopbackPacketsLONG); + checkOffset("loopbackBytes", loopbackBytesLONG); + checkOffset("recvPackets", recvPacketsLONG); + checkOffset("recvBytes", recvBytesLONG); + checkOffset("recvErrors", recvErrorsLONG); + checkOffset("recvDrops", recvDropsLONG); + checkOffset("xmitPackets", xmitPacketsLONG); + checkOffset("xmitBytes", xmitBytesLONG); + checkOffset("xmitErrors", xmitErrorsLONG); + checkOffset("xmitDrops", xmitDropsLONG); + checkOffset("xmitCollisions", xmitCollisionsLONG); + checkOffset("contextSwitches", contextSwitchesLONG); + checkOffset("processCreates", processCreatesLONG); + checkOffset("pagesPagedIn", pagesPagedInLONG); + checkOffset("pagesPagedOut", pagesPagedOutLONG); + checkOffset("pagesSwappedIn", pagesSwappedInLONG); + checkOffset("pagesSwappedOut", pagesSwappedOutLONG); + checkOffset("diskReadsCompleted", readsCompletedLONG); + checkOffset("diskReadsMerged", readsMergedLONG); + checkOffset("diskBytesRead", bytesReadLONG); + checkOffset("diskTimeReading", timeReadingLONG); + checkOffset("diskWritesCompleted", writesCompletedLONG); + checkOffset("diskWritesMerged", writesMergedLONG); + checkOffset("diskBytesWritten", bytesWrittenLONG); + checkOffset("diskTimeWriting", timeWritingLONG); + checkOffset("diskOpsInProgress", iosInProgressLONG); + checkOffset("diskTimeInProgress", timeIosInProgressLONG); + checkOffset("diskTime", ioTimeLONG); + + checkOffset("loadAverage1", loadAverage1DOUBLE); + checkOffset("loadAverage15", loadAverage15DOUBLE); + checkOffset("loadAverage5", loadAverage5DOUBLE); + } + + private LinuxSystemStats() { + // no instances allowed + } + public static StatisticsType getType() { + return myType; + } +}