modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
| 55 ++++--
modules/plugins/jmx/pom.xml
| 7
modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
| 51 +++++
modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
| 6
modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
| 86 ++++------
5 files changed, 133 insertions(+), 72 deletions(-)
New commits:
commit 60861793babe07efc23f457e432f73fbb0f7ea52
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed May 29 10:46:05 2013 -0400
Use new JMX plugin metric "VM Memory System:Heap usage Percentage" to
provide
a factory installed alert template for an RHQ storage node. The actual
numbers probably need tweeking, currently its HUP > 75% with 10 of 15 dampening.
TODO: lower the collection interval to 1 minute for the relevant metric.
diff --git
a/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
b/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
index ce14f17..8704203 100644
---
a/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
+++
b/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
@@ -27,8 +27,8 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
-import org.rhq.core.domain.alert.AlertConditionOperator;
import org.rhq.core.domain.alert.AlertDampening;
+import org.rhq.core.domain.alert.AlertDampening.TimeUnits;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.alert.AlertPriority;
import org.rhq.core.domain.alert.BooleanExpression;
@@ -38,8 +38,10 @@ import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.criteria.AlertDefinitionCriteria;
import org.rhq.core.domain.criteria.ResourceTypeCriteria;
+import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
+import org.rhq.enterprise.server.alert.AlertTemplateManagerLocal;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
@@ -58,17 +60,17 @@ public class AlertDefinitionServerPluginComponent implements
ServerPluginCompone
private final Log log =
LogFactory.getLog(AlertDefinitionServerPluginComponent.class);
static private final List<InjectedTemplate> injectedTemplates;
- static private final InjectedTemplate testTemplate;
+ static private final InjectedTemplate storageNodeHighHeapTemplate;
static {
- testTemplate = new InjectedTemplate( //
- "RHQAgent", //
- "RHQ Agent", //
- "TestTemplate", //
- "A test template injection");
+ storageNodeHighHeapTemplate = new InjectedTemplate(
+ "RHQStorage", //
+ "VM Memory System", //
+ "StorageNodeHighHeapTemplate", //
+ "An alert template to notify users of excessive heap use by an RHQ
Storage Node. When fired please see documentation for the proper corrective
action.");
injectedTemplates = new ArrayList<InjectedTemplate>();
- injectedTemplates.add(testTemplate);
+ injectedTemplates.add(storageNodeHighHeapTemplate);
}
private ServerPluginContext context;
@@ -177,6 +179,7 @@ public class AlertDefinitionServerPluginComponent implements
ServerPluginCompone
ResourceTypeCriteria rtc = new ResourceTypeCriteria();
rtc.addFilterPluginName(injectedAlertDef.getPluginName());
rtc.addFilterName(injectedAlertDef.getResourceTypeName());
+ rtc.fetchMetricDefinitions(true);
List<ResourceType> resourceTypes =
typeManager.findResourceTypesByCriteria(subjectManager.getOverlord(), rtc);
if (resourceTypes.isEmpty()) {
@@ -206,8 +209,8 @@ public class AlertDefinitionServerPluginComponent implements
ServerPluginCompone
int newAlertDefId = 0;
- if (testTemplate.equals(injectedAlertDef)) {
- newAlertDefId = injectTestTemplate(resourceType);
+ if (storageNodeHighHeapTemplate.equals(injectedAlertDef)) {
+ newAlertDefId = injectStorageNodeHighHeapTemplate(resourceType);
}
adc.addFilterId(newAlertDefId);
@@ -218,27 +221,41 @@ public class AlertDefinitionServerPluginComponent implements
ServerPluginCompone
return result;
}
- private int injectTestTemplate(ResourceType resourceType) {
- AlertDefinitionManagerLocal alertDefManager =
LookupUtil.getAlertDefinitionManager();
+ private int injectStorageNodeHighHeapTemplate(ResourceType resourceType) {
+ AlertTemplateManagerLocal alertTemplateManager =
LookupUtil.getAlertTemplateManager();
SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
AlertDefinition newTemplate = new AlertDefinition();
- newTemplate.setName(testTemplate.getName());
+ newTemplate.setName(storageNodeHighHeapTemplate.getName());
newTemplate.setResourceType(resourceType);
newTemplate.setPriority(AlertPriority.MEDIUM);
- newTemplate.setAlertDampening(new AlertDampening(AlertDampening.Category.NONE));
newTemplate.setConditionExpression(BooleanExpression.ANY);
newTemplate.setRecoveryId(0);
newTemplate.setEnabled(true);
AlertCondition ac = new AlertCondition();
- ac.setCategory(AlertConditionCategory.AVAILABILITY);
- ac.setName(AlertConditionOperator.AVAIL_GOES_DOWN.name());
-
+ ac.setCategory(AlertConditionCategory.THRESHOLD);
+ ac.setComparator(">");
+ ac.setThreshold(0.75D);
+ for (MeasurementDefinition d : resourceType.getMetricDefinitions()) {
+ if ("Calculated.HeapUsagePercentage".equals(d.getName())) {
+ ac.setMeasurementDefinition(d);
+ ac.setName(d.getDisplayName());
+ break;
+ }
+ }
+ assert null != ac.getMeasurementDefinition() : "Did not find expected
measurement definition [Calculated.HeapUsagePercentage] for "
+ + resourceType;
newTemplate.addCondition(ac);
- int newTemplateId =
alertDefManager.createAlertDefinitionInNewTransaction(subjectManager.getOverlord(),
- newTemplate, null, true);
+ AlertDampening dampener = new
AlertDampening(AlertDampening.Category.PARTIAL_COUNT);
+ dampener.setPeriod(15);
+ dampener.setPeriodUnits(TimeUnits.MINUTES);
+ dampener.setValue(10);
+ newTemplate.setAlertDampening(dampener);
+
+ int newTemplateId =
alertTemplateManager.createAlertTemplate(subjectManager.getOverlord(), newTemplate,
+ resourceType.getId());
return newTemplateId;
}
commit 756d7ee25ba8526e1b70a874fdaa24340be6e8f5
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed May 29 10:42:47 2013 -0400
Add new JMX metric for "VM Memory System:Heap Usage Percentage". This
provides a way to monitor/alert actual memory consumption as it is calculated
as HeapUsage/HeapCommitted.
Re-enable JMXPluginTest, as it seems to be working (at least on
my box, hopefully on jenkins as well). Also, add test of new metric.
diff --git a/modules/plugins/jmx/pom.xml b/modules/plugins/jmx/pom.xml
index 1e17e7c..864f675 100644
--- a/modules/plugins/jmx/pom.xml
+++ b/modules/plugins/jmx/pom.xml
@@ -120,13 +120,6 @@
</goals>
<configuration>
<skip>${maven.test.skip}</skip>
- <excludes>
- <!--
- Disabled to due a NPE that the test hits in
vmUtility.attachToVirtualMachine on line 107 which
- may be due to this Sigar bug,
https://jira.hyperic.com/browse/SIGAR-231.
- -->
- <exclude>**/JMXPluginTest.java</exclude>
- </excludes>
<excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
<useSystemClassLoader>true</useSystemClassLoader>
<argLine>${jacoco.integration-test.args}
-Dorg.hyperic.sigar.path=${basedir}/target/itest/lib</argLine>
diff --git
a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
index 5637c2d..c0be3d4 100644
--- a/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
+++ b/modules/plugins/jmx/src/main/java/org/rhq/plugins/jmx/MBeanResourceComponent.java
@@ -89,6 +89,8 @@ public class MBeanResourceComponent<T extends
JMXComponent<?>> implements Measur
private static final Pattern PROPERTY_PATTERN =
Pattern.compile("^\\{(?:\\{([^\\}]*)\\})?([^\\}]*)\\}$");
private static final Pattern TEMPLATE_PATTERN =
Pattern.compile("%([^%]+)%");
+ private static final String CALCULATED_METRIC_HEAP_USAGE_PERCENTAGE =
"Calculated.HeapUsagePercentage";
+
// these two should be private - subclasses need to override the getter/setter/load
methods to affect these
/**
* @deprecated do not use this - use {@link #getEmsBean()} instead
@@ -262,10 +264,13 @@ public class MBeanResourceComponent<T extends
JMXComponent<?>> implements Measur
* @param bean the EmsBean on which to collect the metrics
*/
protected void getValues(MeasurementReport report,
Set<MeasurementScheduleRequest> requests, EmsBean bean) {
- // First we split the requests into their respective beans
+ // First we split the requests into their respective beans, and handle calculated
values
Set<MeasurementScheduleRequest> defaultBeanRequests = new
HashSet<MeasurementScheduleRequest>();
Map<String, Set<MeasurementScheduleRequest>> beansMap = new
HashMap<String, Set<MeasurementScheduleRequest>>();
for (MeasurementScheduleRequest request : requests) {
+ if (getCalculatedProperty(report, request, bean)) {
+ continue;
+ }
Matcher m = PROPERTY_PATTERN.matcher(request.getName());
if (m.matches() && (m.group(1) != null)) {
// Custom bean
@@ -295,6 +300,50 @@ public class MBeanResourceComponent<T extends
JMXComponent<?>> implements Measur
}
}
+ private boolean getCalculatedProperty(MeasurementReport report,
MeasurementScheduleRequest request, EmsBean bean) {
+ boolean result = false;
+ String metricName = request.getName();
+
+ if (CALCULATED_METRIC_HEAP_USAGE_PERCENTAGE.equals(request.getName())) {
+ result = true;
+
+ MeasurementReport calculationPropsReport = new MeasurementReport();
+ Set<MeasurementScheduleRequest> calculationPropsSchedules = new
HashSet(2);
+
+ MeasurementScheduleRequest heapUsedRequest = new
MeasurementScheduleRequest(0, "{HeapMemoryUsage.used}",
+ 0L, true, DataType.MEASUREMENT);
+ MeasurementScheduleRequest heapComittedRequest = new
MeasurementScheduleRequest(0,
+ "{HeapMemoryUsage.committed}", 0L, true,
DataType.MEASUREMENT);
+ calculationPropsSchedules.add(heapUsedRequest);
+ calculationPropsSchedules.add(heapComittedRequest);
+
+ getBeanProperties(calculationPropsReport, bean, calculationPropsSchedules);
+ Set<MeasurementDataNumeric> values =
calculationPropsReport.getNumericData();
+ Double heapUsed = Double.NaN;
+ Double heapCommitted = Double.NaN;
+ if (null != values && values.size() == 2) {
+ for (MeasurementDataNumeric v : values) {
+ if (v.getName().equals("{HeapMemoryUsage.used}")) {
+ heapUsed = v.getValue();
+ } else {
+ heapCommitted = v.getValue();
+ }
+ }
+ }
+
+ Double value = Double.NaN;
+ try {
+ value = heapUsed / heapCommitted;
+ } catch (Throwable t) {
+ // leave as NaN
+ }
+
+ report.addData(new MeasurementDataNumeric(request, value));
+ }
+
+ return result;
+ }
+
protected String transformBeanName(String beanTemplate) {
Matcher m = TEMPLATE_PATTERN.matcher(beanTemplate);
diff --git a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
index 76572a3..9bf9e1c 100644
--- a/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jmx/src/main/resources/META-INF/rhq-plugin.xml
@@ -250,6 +250,12 @@
property="{HeapMemoryUsage.used}"
description="Current heap memory usage"
units="bytes"/>
+ <!-- Heap Usage Percentage is calculated and is not an mbean property -->
+ <metric displayName="Heap Usage Percentage"
+ property="Calculated.HeapUsagePercentage"
+ displayType="summary"
+ description="Current heap memory usage as percentage of committed
heap"
+ units="percentage"/>
<metric displayName="Heap Committed"
property="{HeapMemoryUsage.committed}"
displayType="summary"
diff --git a/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
b/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
index 6fb39d6..151f99e 100644
--- a/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
+++ b/modules/plugins/jmx/src/test/java/org/rhq/plugins/jmx/test/JMXPluginTest.java
@@ -83,7 +83,7 @@ public class JMXPluginTest {
private static final String EXPLICIT_RESOURCE_KEY2 = "foo2";
private List<Process> testServerJvms = new ArrayList<Process>();
-
+
private InventoryManager inventoryManager;
@BeforeSuite
@@ -98,8 +98,8 @@ public class JMXPluginTest {
// + EXPLICIT_RESOURCE_KEY1));
this.testServerJvms.add(startTestServerJvm("-Dcom.sun.management.jmxremote.port="
+ JMX_REMOTING_PORT2,
- "-Dcom.sun.management.jmxremote.ssl=false",
"-Dcom.sun.management.jmxremote.authenticate=false",
- "-D" + JMXDiscoveryComponent.SYSPROP_RHQ_RESOURCE_KEY +
"=" + EXPLICIT_RESOURCE_KEY2));
+ "-Dcom.sun.management.jmxremote.ssl=false",
"-Dcom.sun.management.jmxremote.authenticate=false", "-D"
+ + JMXDiscoveryComponent.SYSPROP_RHQ_RESOURCE_KEY + "=" +
EXPLICIT_RESOURCE_KEY2));
// Give them time to fully start.
Thread.sleep(3000);
@@ -113,7 +113,8 @@ public class JMXPluginTest {
PluginContainer.getInstance().setConfiguration(pcConfig);
PluginContainer.getInstance().initialize();
- Set<String> pluginNames =
PluginContainer.getInstance().getPluginManager().getMetadataManager().getPluginNames();
+ Set<String> pluginNames =
PluginContainer.getInstance().getPluginManager().getMetadataManager()
+ .getPluginNames();
System.out.println("PC started with plugins " + pluginNames +
".");
this.inventoryManager = PluginContainer.getInstance().getInventoryManager();
@@ -135,8 +136,8 @@ public class JMXPluginTest {
args.add("target/test-classes");
args.addAll(Arrays.asList(jvmArgs));
args.add(TestProgram.class.getName());
-
- ProcessBuilder processBuilder = new ProcessBuilder(args);
+
+ ProcessBuilder processBuilder = new ProcessBuilder(args);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
@@ -144,17 +145,17 @@ public class JMXPluginTest {
Thread outputReaderThread = new Thread(outputReader);
outputReaderThread.setDaemon(true);
outputReaderThread.start();
-
+
return process;
}
@AfterSuite
- public void stop() {
+ public void stop() {
PluginContainer.getInstance().shutdown();
-
+
for (Process process : this.testServerJvms) {
process.destroy();
- }
+ }
}
@Test
@@ -184,24 +185,24 @@ public class JMXPluginTest {
System.out.println(" * " + jmxServer);
JvmResourceKey key = JvmResourceKey.valueOf(jmxServer.getResourceKey());
switch (key.getType()) {
- case Explicit:
- if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY1)) {
- assert
key.getMainClassName().equals(TestProgram.class.getName());
- foundExplicitKey1Server = true;
- } else if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY2)) {
- assert
key.getMainClassName().equals(TestProgram.class.getName());
- foundExplicitKey2Server = true;
- }
- break;
- case JmxRemotingPort:
- if (key.getMainClassName().equals(TestProgram.class.getName())
&&
- key.getJmxRemotingPort().equals(JMX_REMOTING_PORT1)) {
- assert
key.getMainClassName().equals(TestProgram.class.getName());
- foundJmxRemotingServer = true;
- }
- break;
- default:
- throw new IllegalStateException("Unsupported key type: " +
key.getType());
+ case Explicit:
+ if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY1)) {
+ assert key.getMainClassName().equals(TestProgram.class.getName());
+ foundExplicitKey1Server = true;
+ } else if (key.getExplicitValue().equals(EXPLICIT_RESOURCE_KEY2)) {
+ assert key.getMainClassName().equals(TestProgram.class.getName());
+ foundExplicitKey2Server = true;
+ }
+ break;
+ case JmxRemotingPort:
+ if (key.getMainClassName().equals(TestProgram.class.getName())
+ && key.getJmxRemotingPort().equals(JMX_REMOTING_PORT1)) {
+ assert key.getMainClassName().equals(TestProgram.class.getName());
+ foundJmxRemotingServer = true;
+ }
+ break;
+ default:
+ throw new IllegalStateException("Unsupported key type: " +
key.getType());
}
}
assert foundJmxRemotingServer : "JMX Remoting server not found.";
@@ -210,16 +211,7 @@ public class JMXPluginTest {
assert foundExplicitKey2Server : "JMX Remoting + explicit key server not
found.";
}
- /**
- * This test is currently disabled because we hit a NPE in
- * JvmUtility.attachToVirtualMachine on line 107 where,
- *
- * process.getCredentialsName().getUser();
- *
- * is called. Looks like the NPE is coming from the call to getUser() at the end
and
- * it might be due to this Sigar bug,
https://jira.hyperic.com/browse/SIGAR-231.
- */
- @Test(dependsOnMethods = "testServerDiscovery", enabled = false)
+ @Test(dependsOnMethods = "testServerDiscovery")
public void testServiceDiscovery() throws Exception {
InventoryReport report =
PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately();
assert report != null;
@@ -228,7 +220,7 @@ public class JMXPluginTest {
assert platform != null;
Set<Resource> jmxServers = getChildResourcesOfType(platform, new
ResourceType(SERVER_TYPE_NAME, PLUGIN_NAME,
- ResourceCategory.SERVER, null));
+ ResourceCategory.SERVER, null));
for (Resource jmxServer : jmxServers) {
Set<Resource> childResources = jmxServer.getChildResources();
@@ -255,12 +247,16 @@ public class JMXPluginTest {
Set<MeasurementScheduleRequest> metricList = new
HashSet<MeasurementScheduleRequest>();
metricList.add(new MeasurementScheduleRequest(1,
"FreePhysicalMemorySize", 1000, true,
DataType.MEASUREMENT));
+ if ("VM Memory
System".equals(service.getResourceType().getName())) {
+ metricList.add(new MeasurementScheduleRequest(2,
"Calculated.HeapUsagePercentage", 1000, true,
+ DataType.MEASUREMENT));
+ }
MeasurementReport report = new MeasurementReport();
if (serviceComponent.getAvailability().equals(AvailabilityType.UP))
{
((MeasurementFacet) serviceComponent).getValues(report,
metricList);
for (MeasurementData value : report.getNumericData()) {
- System.out.println(value.getValue() + ":" +
service.getName());
+ System.out.println(value.getValue() + ":" +
value.getName());
}
}
}
@@ -280,7 +276,7 @@ public class JMXPluginTest {
.getResourceComponent(service);
Object result = ((OperationFacet)
serviceComponent).invokeOperation("findMonitorDeadlockedThreads",
- new Configuration());
+ new Configuration());
System.out.println("Result of operation test was: " +
result);
}
}
@@ -328,8 +324,8 @@ public class JMXPluginTest {
Set<Resource> results = new HashSet<Resource>();
for (Resource resource : childResources) {
ResourceType childResourceType = resource.getResourceType();
- if (childResourceType.getPlugin().equals(resourceType.getPlugin())
&&
- childResourceType.getName().equals(resourceType.getName())) {
+ if (childResourceType.getPlugin().equals(resourceType.getPlugin())
+ && childResourceType.getName().equals(resourceType.getName())) {
results.add(resource);
}
}
@@ -360,7 +356,7 @@ public class JMXPluginTest {
public static class TestProgram implements Runnable {
long started = System.currentTimeMillis();
- public static void main(String[] args) {
+ public static void main(String[] args) {
final ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(0);
@@ -372,7 +368,7 @@ public class JMXPluginTest {
String jvmName = runtimeMXBean.getName();
int atIndex = jvmName.indexOf('@');
String pid = (atIndex != -1) ? jvmName.substring(0, atIndex) :
"?";
-
+
System.out.println("Test server JVM with pid [" + pid + "]
listening on port ["
+ serverSocket.getLocalPort() + "]...");
Runnable runnable = new Runnable() {