From e46c6d744ad40707335478e539edba1935f8c39a Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Wed, 19 Sep 2007 17:05:42 +0000
Subject: [PATCH] Add a new monitor provider that can be used to monitor memory usage within the JVM, including:
---
opends/resource/schema/02-config.ldif | 3
opends/src/admin/defn/org/opends/server/admin/std/MemoryUsageMonitorProviderConfiguration.xml | 61 +++++++
opends/src/server/org/opends/server/monitors/MemoryUsageMonitorProvider.java | 335 +++++++++++++++++++++++++++++++++++++++++
opends/resource/config/config.ldif | 24 ++-
4 files changed, 415 insertions(+), 8 deletions(-)
diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 240ee9e..ba10ec3 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -1155,6 +1155,22 @@
ds-cfg-monitor-provider-class: org.opends.server.monitors.ClientConnectionMonitorProvider
ds-cfg-monitor-provider-enabled: true
+dn: cn=Entry Cache,cn=Monitor Providers,cn=config
+objectClass: top
+objectClass: ds-cfg-monitor-provider
+objectClass: ds-cfg-entry-cache-monitor-provider
+cn: Entry Cache
+ds-cfg-monitor-provider-class: org.opends.server.monitors.EntryCacheMonitorProvider
+ds-cfg-monitor-provider-enabled: true
+
+dn: cn=JVM Memory Usage,cn=Monitor Providers,cn=config
+objectClass: top
+objectClass: ds-cfg-monitor-provider
+objectClass: ds-cfg-memory-usage-monitor-provider
+cn: JVM Memory Usage
+ds-cfg-monitor-provider-class: org.opends.server.monitors.MemoryUsageMonitorProvider
+ds-cfg-monitor-provider-enabled: true
+
dn: cn=JVM Stack Trace,cn=Monitor Providers,cn=config
objectClass: top
objectClass: ds-cfg-monitor-provider
@@ -1179,14 +1195,6 @@
ds-cfg-monitor-provider-class: org.opends.server.monitors.VersionMonitorProvider
ds-cfg-monitor-provider-enabled: true
-dn: cn=Entry Cache,cn=Monitor Providers,cn=config
-objectClass: top
-objectClass: ds-cfg-monitor-provider
-objectClass: ds-cfg-entry-cache-monitor-provider
-cn: Entry Cache
-ds-cfg-monitor-provider-class: org.opends.server.monitors.EntryCacheMonitorProvider
-ds-cfg-monitor-provider-enabled: true
-
dn: cn=Password Generators,cn=config
objectClass: top
objectClass: ds-cfg-branch
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index 5eafa48..816c4dc 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -2509,4 +2509,7 @@
objectClasses: ( 1.3.6.1.4.1.26027.1.2.173
NAME 'ds-cfg-entry-cache-monitor-provider' SUP ds-cfg-monitor-provider
STRUCTURAL X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.174
+ NAME 'ds-cfg-memory-usage-monitor-provider' SUP ds-cfg-monitor-provider
+ STRUCTURAL X-ORIGIN 'OpenDS Directory Server' )
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/MemoryUsageMonitorProviderConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/MemoryUsageMonitorProviderConfiguration.xml
new file mode 100644
index 0000000..f44ab07
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/MemoryUsageMonitorProviderConfiguration.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+! CDDL HEADER START
+!
+! The contents of this file are subject to the terms of the
+! Common Development and Distribution License, Version 1.0 only
+! (the "License"). You may not use this file except in compliance
+! with the License.
+!
+! You can obtain a copy of the license at
+! trunk/opends/resource/legal-notices/OpenDS.LICENSE
+! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+! See the License for the specific language governing permissions
+! and limitations under the License.
+!
+! When distributing Covered Code, include this CDDL HEADER in each
+! file and include the License file at
+! trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+! add the following below this CDDL HEADER, with the fields enclosed
+! by brackets "[]" replaced with your own identifying information:
+! Portions Copyright [yyyy] [name of copyright owner]
+!
+! CDDL HEADER END
+!
+!
+! Portions Copyright 2007 Sun Microsystems, Inc.
+! -->
+
+<adm:managed-object
+ name="memory-usage-monitor-provider"
+ plural-name="memory-usage-monitor-providers"
+ package="org.opends.server.admin.std"
+ extends="monitor-provider"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+
+ <adm:synopsis>
+ The <adm:user-friendly-name /> may be used to publish information about
+ memory consumption and garbage collection activity in the JVM.
+ </adm:synopsis>
+
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.174</ldap:oid>
+ <ldap:name>ds-cfg-memory-usage-monitor-provider</ldap:name>
+ <ldap:superior>ds-cfg-monitor-provider</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+
+ <adm:property-override name="monitor-class">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.monitors.MemoryUsageMonitorProvider
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+
+</adm:managed-object>
+
diff --git a/opends/src/server/org/opends/server/monitors/MemoryUsageMonitorProvider.java b/opends/src/server/org/opends/server/monitors/MemoryUsageMonitorProvider.java
new file mode 100644
index 0000000..1b4f419
--- /dev/null
+++ b/opends/src/server/org/opends/server/monitors/MemoryUsageMonitorProvider.java
@@ -0,0 +1,335 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.monitors;
+
+
+
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryUsage;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+
+import org.opends.server.admin.std.server.MemoryUsageMonitorProviderCfg;
+import org.opends.server.api.MonitorProvider;
+import org.opends.server.config.ConfigException;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.protocols.asn1.ASN1OctetString;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.InitializationException;
+
+
+
+/**
+ * This class defines a monitor provider that reports information about
+ * Directory Server memory usage.
+ */
+public class MemoryUsageMonitorProvider
+ extends MonitorProvider<MemoryUsageMonitorProviderCfg>
+{
+ // A map of the last GC counts seen by this monitor for calculating recent
+ // stats.
+ private HashMap<String,Long> lastGCCounts = new HashMap<String,Long>();
+
+ // A map of the last GC times seen by this monitor for calculating recent
+ // stats.
+ private HashMap<String,Long> lastGCTimes = new HashMap<String,Long>();
+
+ // A map of the most recent GC durations seen by this monitor.
+ private HashMap<String,Long> recentGCDurations = new HashMap<String,Long>();
+
+ // A map of the memory manager names to names that are safe for use in
+ // attribute names.
+ private HashMap<String,String> gcSafeNames = new HashMap<String,String>();
+
+
+
+ /**
+ * Initializes this monitor provider.
+ */
+ public MemoryUsageMonitorProvider()
+ {
+ super("JVM Memory Usage Monitor Provider");
+
+ // No initialization should be performed here.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void initializeMonitorProvider(
+ MemoryUsageMonitorProviderCfg configuration)
+ throws ConfigException, InitializationException
+ {
+ // No initialization is required.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public String getMonitorInstanceName()
+ {
+ return "JVM Memory Usage";
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public long getUpdateInterval()
+ {
+ // Update the information once every second.
+ return 1000;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public void updateMonitorData()
+ {
+ for (GarbageCollectorMXBean gc :
+ ManagementFactory.getGarbageCollectorMXBeans())
+ {
+ String gcName = gc.getName();
+ long gcCount = gc.getCollectionCount();
+ long gcTime = gc.getCollectionTime();
+
+ long lastGCCount = 0L;
+ long lastGCTime = 0L;
+ long recentGCDuration = 0L;
+ if (lastGCCounts.containsKey(gcName))
+ {
+ lastGCCount = lastGCCounts.get(gcName);
+ lastGCTime = lastGCTimes.get(gcName);
+ recentGCDuration = recentGCDurations.get(gcName);
+ }
+
+ if (gcCount > lastGCCount)
+ {
+ long recentGCCount = gcCount - lastGCCount;
+ long recentGCTime = gcTime - lastGCTime;
+ recentGCDuration = (recentGCTime / recentGCCount);
+ }
+
+ lastGCCounts.put(gcName, gcCount);
+ lastGCTimes.put(gcName, gcTime);
+ recentGCDurations.put(gcName, recentGCDuration);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override()
+ public ArrayList<Attribute> getMonitorData()
+ {
+ ArrayList<Attribute> attrs = new ArrayList<Attribute>();
+
+ for (GarbageCollectorMXBean gc :
+ ManagementFactory.getGarbageCollectorMXBeans())
+ {
+ String gcName = gc.getName();
+ long gcCount = gc.getCollectionCount();
+ long gcTime = gc.getCollectionTime();
+
+ long avgGCDuration = 0L;
+ if (gcCount > 0)
+ {
+ avgGCDuration = gcTime / gcCount;
+ }
+
+ long recentGCDuration = 0L;
+ if (recentGCDurations.containsKey(gcName))
+ {
+ recentGCDuration = recentGCDurations.get(gcName);
+ }
+
+ String safeName = gcSafeNames.get(gcName);
+ if (safeName == null)
+ {
+ safeName = generateSafeName(gcName);
+ gcSafeNames.put(gcName, safeName);
+ }
+
+ attrs.add(createAttribute(safeName + "-total-collection-count",
+ String.valueOf(gcCount)));
+ attrs.add(createAttribute(safeName + "-total-collection-duration",
+ String.valueOf(gcTime)));
+ attrs.add(createAttribute(safeName + "-average-collection-duration",
+ String.valueOf(avgGCDuration)));
+ attrs.add(createAttribute(safeName + "-recent-collection-duration",
+ String.valueOf(recentGCDuration)));
+ }
+
+ for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans())
+ {
+ String poolName = mp.getName();
+ MemoryUsage currentUsage = mp.getUsage();
+ MemoryUsage collectionUsage = mp.getCollectionUsage();
+
+ String safeName = gcSafeNames.get(poolName);
+ if (safeName == null)
+ {
+ safeName = generateSafeName(poolName);
+ gcSafeNames.put(poolName, safeName);
+ }
+
+ if (currentUsage == null)
+ {
+ attrs.add(createAttribute(safeName + "-current-bytes-used", "0"));
+ }
+ else
+ {
+ attrs.add(createAttribute(safeName + "-current-bytes-used",
+ String.valueOf(currentUsage.getUsed())));
+ }
+
+ if (collectionUsage == null)
+ {
+ attrs.add(createAttribute(safeName +
+ "-bytes-used-after-last-collection",
+ "0"));
+ }
+ else
+ {
+ attrs.add(createAttribute(safeName +
+ "-bytes-used-after-last-collection",
+ String.valueOf(collectionUsage.getUsed())));
+ }
+ }
+
+ return attrs;
+ }
+
+
+
+ /**
+ * Constructs an attribute using the provided information. It will have the
+ * default syntax.
+ *
+ * @param name The name to use for the attribute.
+ * @param value The value to use for the attribute.
+ *
+ * @return The attribute created from the provided information.
+ */
+ private Attribute createAttribute(String name, String value)
+ {
+ AttributeType attrType = DirectoryServer.getDefaultAttributeType(name);
+
+ ASN1OctetString encodedValue = new ASN1OctetString(value);
+ LinkedHashSet<AttributeValue> values = new LinkedHashSet<AttributeValue>(1);
+
+ try
+ {
+ values.add(new AttributeValue(encodedValue,
+ attrType.normalize(encodedValue)));
+ }
+ catch (Exception e)
+ {
+ values.add(new AttributeValue(encodedValue, encodedValue));
+ }
+
+ return new Attribute(attrType, name, values);
+ }
+
+
+
+ /**
+ * Creates a "safe" version of the provided name, which is acceptable for
+ * use as part of an attribute name.
+ *
+ * @param name The name for which to obtain the safe name.
+ *
+ * @return The calculated safe name.
+ */
+ private String generateSafeName(String name)
+ {
+ StringBuilder buffer = new StringBuilder();
+ boolean lastWasUppercase = false;
+ boolean lastWasDash = false;
+ for (int i=0; i < name.length(); i++)
+ {
+ char c = name.charAt(i);
+ if (Character.isLetter(c))
+ {
+ if (Character.isUpperCase(c))
+ {
+ char lowerCaseCharacter = Character.toLowerCase(c);
+ if ((buffer.length() > 0) && (! lastWasUppercase) && (! lastWasDash))
+ {
+ buffer.append('-');
+ }
+
+ buffer.append(lowerCaseCharacter);
+ lastWasUppercase = true;
+ lastWasDash = false;
+ }
+ else
+ {
+ buffer.append(c);
+ lastWasUppercase = false;
+ lastWasDash = false;
+ }
+ }
+ else if (Character.isDigit(c))
+ {
+ buffer.append(c);
+ lastWasUppercase = false;
+ lastWasDash = false;
+ }
+ else if ((c == ' ') || (c == '_') || (c == '-'))
+ {
+ if (! lastWasDash)
+ {
+ buffer.append('-');
+ }
+
+ lastWasUppercase = false;
+ lastWasDash = true;
+ }
+ }
+
+ return buffer.toString();
+ }
+}
+
--
Gitblit v1.10.0