Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.welen.jmole.collector.MBeanCollectorImpl Maven / Gradle / Ivy
package net.welen.jmole.collector;
import java.text.DecimalFormat;
/*
* #%L
* JMole, https://bitbucket.org/awelen/jmole
* %%
* Copyright (C) 2015 - 2020 Anders Welén, [email protected]
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.MBeanException;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.ReflectionException;
import javax.management.Attribute;
import javax.management.AttributeList;
import net.welen.jmole.Utils;
/**
* The impl, of a MBeanCollector
*/
public class MBeanCollectorImpl implements MBeanCollector {
private final static Logger LOG = Logger.getLogger(MBeanCollectorImpl.class.getName());
private MBeanServer server = Utils.getMBeanServer();
private String name = "%s";
private List nameAttributes = null;
private List nameParameters = null;
private List nameDomainNameParts = null;
private Map counterIntervals = new HashMap();
private Map lastFetchMap = new HashMap();
private List attributes = new ArrayList();
private Map attributeExtractors = new HashMap();
private Map attributeRecalculations = new HashMap();
private Map attributeFormatPatterns = new HashMap();
private static class LastFetch {
public LastFetch(long fetchTime, Double value, Double lastCalculatedValue) {
this.fetchTime = fetchTime;
this.value = value;
this.lastCalculatedValue = lastCalculatedValue;
}
long fetchTime;
Double value;
Double lastCalculatedValue;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setNameAttributes(List nameAttributes) {
this.nameAttributes = nameAttributes;
}
public void setNameParameters(List nameParameters) {
this.nameParameters = nameParameters;
}
public void setNameDomainNameParts(List nameDomainNameParts) {
this.nameDomainNameParts = nameDomainNameParts;
}
public Map getCounterIntervals() {
return counterIntervals;
}
public void setCounterIntervals(Map counterIntervals) {
this.counterIntervals = counterIntervals;
}
private String getNameSubstitution(ObjectName objectName)
throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException {
StringBuilder tmp = new StringBuilder();
if (nameDomainNameParts != null) {
String[] domainNameParts = objectName.getDomain().split("\\.");
for (Integer pos : nameDomainNameParts) {
if (tmp.length() > 0) {
tmp.append(" ");
}
tmp.append(domainNameParts[pos]);
}
}
if (nameAttributes != null) {
for (String part : nameAttributes) {
if (tmp.length() > 0) {
tmp.append(" ");
}
tmp.append(server.getAttribute(objectName, part).toString());
}
}
if (nameParameters != null) {
for (String part : nameParameters) {
if (tmp.length() > 0) {
tmp.append(" ");
}
tmp.append(objectName.getKeyProperty(part));
}
}
if (tmp.length() == 0) {
return null;
}
return tmp.toString();
}
public void setAttributes(List attributes) {
this.attributes = attributes;
}
public List getAttributes() {
return attributes;
}
public void setDataCollectorExtractors(Map attributeExtractors) {
this.attributeExtractors = attributeExtractors;
}
public void setAttributeRecalculations(Map attributeRecalculations) {
this.attributeRecalculations = attributeRecalculations;
}
public void setAttributeFormatPatterns(Map attributeFormatPatterns) {
this.attributeFormatPatterns = attributeFormatPatterns;
}
@Override
public String getConstructedName(ObjectName objectName)
throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException {
String substition = getNameSubstitution(objectName);
if (substition != null) {
return String.format(name, substition);
}
return name;
}
public Map getValues(ObjectName objectName)
throws InstanceNotFoundException, ReflectionException, AttributeNotFoundException, MBeanException {
LOG.log(Level.FINE, "Getting the values for ObjectName: " + objectName);
LOG.log(Level.FINE, "Attribute list: " + attributes);
AttributeList attributeList = null;
try {
// WildFly 14 seems not to handle attributes that is not found, even if the javadoc says it's ok
// so we remove all attributes that are handled by DataCollectorExtractors
List tmpAttributes = new ArrayList(attributes);
for (DataCollectorExtractor extractor : attributeExtractors.values()) {
if (tmpAttributes.contains(extractor.getAttribute())) {
tmpAttributes.remove(extractor.getAttribute());
}
}
attributeList = server.getAttributes(objectName, tmpAttributes.toArray(new String[0]));
} catch (RuntimeException e) {
LOG.log(Level.SEVERE, "Couldn't get the attributes: " + attributes + " for MBean: " + objectName, e);
throw e;
}
LOG.log(Level.FINE, "AttributeList: " + attributeList);
// Quick fix #1 for old JBoss MBeanServer impl. that return to many
// attributes/values from getAttributes()
if (attributeList.size() > attributes.size()) {
LOG.log(Level.FINE,
"Fixing JBoss MBean server bug. Got: " + attributeList + " expected only: " + attributes);
AttributeList fixed = new AttributeList();
for (Attribute value : attributeList.asList()) {
if (attributes.contains(value.getName())) {
fixed.add(value);
}
}
attributeList = fixed;
}
// Quick fix #2 for old JBoss MBeanServer impl. where getAttributes()
// doesn't seem to return super class attributes
if (attributeList.size() != attributes.size()) {
for (String attribute : attributes) {
if (!attributeList.contains(attribute)) {
try {
attributeList.add(new Attribute(attribute, server.getAttribute(objectName, attribute)));
LOG.log(Level.FINE, "Fixing JBoss MBean server bug for MBean: " + objectName
+ " and attribute: " + attribute);
} catch (InstanceNotFoundException e) {
// Do nothing, just continue
LOG.log(Level.FINE, e.getMessage(), e);
} catch (ReflectionException e) {
// Do nothing, just continue
LOG.log(Level.FINE, e.getMessage(), e);
} catch (AttributeNotFoundException e) {
// Do nothing, just continue
LOG.log(Level.FINE, e.getMessage(), e);
} catch (MBeanException e) {
// Do nothing, just continue }
LOG.log(Level.FINE, e.getMessage(), e);
}
}
}
}
Map answer = new HashMap();
// Collect all attribute values
for (Attribute attribute : attributeList.asList()) {
String attributeName = attribute.getName();
Object value;
try {
value = attribute.getValue();
} catch (Throwable t) {
LOG.log(Level.SEVERE, t.getMessage(), t);
continue;
}
// Ignore any DataCollectorExtractors based attributes
boolean extractorHandled = false;
for (DataCollectorExtractor extractor : attributeExtractors.values()) {
if (extractor.getAttribute().equals(attributeName)) {
extractorHandled = true;
break;
}
}
if (!extractorHandled) {
answer.put(attributeName, handleValue(objectName, attributeName, value));
}
}
// Collect any DataCollectorExtractors based attributes
LOG.log(Level.FINE, "DataCollectorExtractor attributes: " + attributeExtractors.keySet());
for (DataCollectorExtractor extractor : attributeExtractors.values()) {
LOG.log(Level.FINE,
"DataCollectorExtractor found ObjectName: " + objectName + " Attribute: "
+ extractor.getAttribute() + " Properties: " + extractor.getProperties());
Object value;
try {
value = extractor.extractData(objectName);
} catch (Throwable t) {
LOG.log(Level.SEVERE, t.getMessage(), t);
continue;
}
answer.put(extractor.getAttribute(), handleValue(objectName, extractor.getAttribute(), value));
}
LOG.log(Level.FINE, "Returning: " + answer);
return answer;
}
private Object handleValue(ObjectName objectName, String attributeName, Object value) {
LOG.log(Level.FINE, "Attribute : " + attributeName + " value = " + value);
// Check if we have a counter interval and calculate the value instead
if (counterIntervals.containsKey(attributeName)) {
value = calculateCounterValue(objectName + "->" + attributeName, Double.parseDouble(value.toString()),
counterIntervals.get(attributeName));
}
if (value == null) {
LOG.log(Level.FINE, "Attribute: " + attributeName + " is null for ObjectName: " + objectName);
return null;
}
// Any recalculation?
if (attributeRecalculations.containsKey(attributeName)) {
try {
Double doubleValue = Double.parseDouble(value.toString());
String reCalculation = attributeRecalculations.get(attributeName);
value = Double.parseDouble(Utils.rpnCalculate(doubleValue + "," + reCalculation));
} catch (NumberFormatException e) {
LOG.log(Level.SEVERE, "Can't do recalculation on non decimal value: " + objectName + " " + value, e);
}
}
// Any formatting?
if (attributeFormatPatterns.containsKey(attributeName)) {
try {
Double doubleValue = Double.parseDouble(value.toString());
String pattern = attributeFormatPatterns.get(attributeName);
DecimalFormat decimalFormat = new DecimalFormat(pattern);
value = decimalFormat.format(doubleValue);
} catch (NumberFormatException e) {
LOG.log(Level.SEVERE, "Can't do formatting on non decimal value: " + objectName + " " + value, e);
}
}
LOG.log(Level.FINE, "Attribute: " + attributeName + " is " + value + " for ObjectName: " + objectName);
return value;
}
private Double calculateCounterValue(String key, Double value, int counterInterval) {
LOG.log(Level.FINE, "Checking " + key);
long now = System.currentTimeMillis();
LastFetch lastFetch = lastFetchMap.get(key);
if (lastFetch == null) {
LOG.log(Level.FINE, "No earlier fetch available, skipping");
lastFetchMap.put(key, new LastFetch(now, value, null));
return null;
}
if (lastFetch.value > value) {
LOG.log(Level.FINE, "Skipping and reset due to that " + lastFetch.value + " > " + value);
lastFetchMap.put(key, new LastFetch(now, value, null));
return null;
}
if (lastFetch.fetchTime + counterInterval > now) {
LOG.log(Level.FINE, "Returning last know calculated value due to that the counter interval "
+ counterInterval + " ms is not reached: " + (lastFetch.fetchTime + counterInterval) + " > " + now);
return lastFetch.lastCalculatedValue;
}
// Calculate the value
Double calculatedValue = (value - lastFetch.value) / ((now - lastFetch.fetchTime) / (double) counterInterval);
// Save fetchTime and value
lastFetchMap.put(key, new LastFetch(now, value, calculatedValue));
LOG.log(Level.FINE, "Returning calculated value: " + calculatedValue);
return calculatedValue;
}
}