changeset 22:6fec95209844

Bug 1522: Add Java heap alert. reviewed-by: shintak
author Yasumasa Suenaga <suenaga.yasumasa@lab.ntt.co.jp>
date Mon, 19 Aug 2013 10:40:21 +0900
parents 8a3de8e3526c
children 978d76002cb5
files agent/ChangeLog agent/heapstats.conf.in agent/mib/HeapStatsMibs.txt agent/src/classContainer.cpp agent/src/classContainer.hpp agent/src/libmain.cpp agent/src/trapSender.hpp agent/src/util.cpp agent/src/util.hpp
diffstat 9 files changed, 206 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/agent/ChangeLog	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/ChangeLog	Mon Aug 19 10:40:21 2013 +0900
@@ -1,3 +1,7 @@
+2013-08-19  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
+
+	* Bug 1522: Add Java heap alert.
+
 2013-08-15  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
 
 	* Bug 1496: SNMP MIB definitions are missing except HeapAlert trap.
--- a/agent/heapstats.conf.in	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/heapstats.conf.in	Mon Aug 19 10:40:21 2013 +0900
@@ -24,6 +24,9 @@
 // Alert setting
 alert_percentage=50
 
+// Alert threshold for java heap usage.
+javaheap_alert_percentage=95
+
 // Timer setting
 snapshot_interval=0
 log_interval=300
--- a/agent/mib/HeapStatsMibs.txt	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/mib/HeapStatsMibs.txt	Mon Aug 19 10:40:21 2013 +0900
@@ -5,7 +5,7 @@
      FROM SNMPv2-SMI;
  
  heapStats MODULE-IDENTITY
-   LAST-UPDATED "201307121621Z"
+   LAST-UPDATED "201308151310Z"
    ORGANIZATION "Heapstats MIB"
    CONTACT-INFO
        "Email: oss-java-support@lab.ntt.co.jp"
@@ -14,6 +14,9 @@
    REVISION "201307121621Z"
    DESCRIPTION
        "Append resourceExhaustedAlert, collectLogAlert, deadLockAlert ."
+   REVISION "201308151310Z"
+   DESCRIPTION
+       "Append Append javaHeapAlert."
    -- REVISION "revision date"
    -- DESCRIPTION
    --     "about Revision"
@@ -150,4 +153,38 @@
    DESCRIPTION	"It's used to notify that raised dead-lock in JVM."
  ::= { deadLockAlert 0 }
  
+ -- javaHeapAlert Define ===================================================
+
+ javaHeapAlert OBJECT IDENTIFIER ::= { heapStats 5 }
+
+ alertDateTime OBJECT-TYPE
+   --
+   SYNTAX      Counter64
+   MAX-ACCESS  read-only
+   STATUS      mandatory
+   DESCRIPTION "alertDateTime is timestamp was generated alert by JVM agent
+                is milli-second from A.D. 01/01/1970 00:00:00."
+ ::= { javaHeapAlert 1 }
+
+ usage OBJECT-TYPE
+   --
+   SYNTAX      Counter64
+   MAX-ACCESS  read-only
+   STATUS      mandatory
+   DESCRIPTION "usage is Java heap usage when alert is generated."
+ ::= { javaHeapAlert 2 }
+
+ maxCapacity OBJECT-TYPE
+   --
+   SYNTAX      Counter64
+   MAX-ACCESS  read-only
+   STATUS      mandatory
+   DESCRIPTION "maxCapacity is max capacity of java heap."
+ ::= { javaHeapAlert 3 }
+
+ heapRegionAlertTrap NOTIFICATION-TYPE
+   STATUS      current
+   DESCRIPTION "It's used to notify that java heap infomation."
+ ::= { javaHeapAlert 0 }
+
 END
--- a/agent/src/classContainer.cpp	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/src/classContainer.cpp	Mon Aug 19 10:40:21 2013 +0900
@@ -33,6 +33,7 @@
 #include "oopUtil.hpp"
 #include "trapSender.hpp"
 #include "sorter.hpp"
+#include "libmain.hpp"
 
 /*!
  * \brief SNMP variable Identifier of raise heap-alert date.
@@ -56,6 +57,19 @@
 static oid OID_ALERT_CLS_COUNT[] = {SNMP_OID_HEAPALERT, 5};
 
 /*!
+ * \brief SNMP variable Identifier of raise Java heap alert date.
+ */
+static oid OID_JAVAHEAPALERT_DATE[]         = {SNMP_OID_JAVAHEAPALERT, 1};
+/*!
+ * \brief SNMP variable Identifier of Java heap usage.
+ */
+static oid OID_JAVAHEAPALERT_USAGE[]        = {SNMP_OID_JAVAHEAPALERT, 2};
+/*!
+ * \brief SNMP variable Identifier of Java heap max capacity.
+ */
+static oid OID_JAVAHEAPALERT_MAX_CAPACITY[] = {SNMP_OID_JAVAHEAPALERT, 3};
+
+/*!
  * \brief Format string for jlong.
  */
 const char JLONG_FORMAT_STR[5] = "%lld";
@@ -319,6 +333,78 @@
 }
 
 /*!
+ * \brief Send memory usage information by SNMP trap.
+ * \param pSender       [in] SNMP trap sender.
+ * \param type          [in] This alert type.
+ * \param occurred_time [in] Datetime of this alert is occurred.
+ * \param usage         [in] Java heap usage.
+ * \param maxCapacity   [in] Max capacity of Java heap.
+ * \return Process result.
+ */
+inline bool sendMemoryUsageAlertTrap(TTrapSender *pSender,
+                         TMemoryUsageAlertType type, jlong occurred_time,
+                                                jlong usage, jlong maxCapacity){
+  /* Setting trap information. */
+  char paramStr[256];
+  const char *trapOID;
+  oid *alert_date;
+  oid *alert_usage;
+  oid *alert_capacity;
+  int oid_len = 0;
+
+  switch(type){
+
+    case ALERT_JAVA_HEAP:
+      trapOID        = OID_JAVAHEAPALERT;
+      alert_date     = OID_JAVAHEAPALERT_DATE;
+      alert_usage    = OID_JAVAHEAPALERT_USAGE;
+      alert_capacity = OID_JAVAHEAPALERT_MAX_CAPACITY;
+      oid_len = OID_LENGTH(OID_JAVAHEAPALERT_DATE);
+      break;
+
+    default:
+      PRINT_CRIT_MSG("Unknown alert type!");
+      return false;
+
+  }
+
+  bool result = true;
+
+  try{
+    /* Setting sysUpTime */
+    pSender->setSysUpTime();
+
+    /* Setting trapOID. */
+    pSender->setTrapOID(trapOID);
+
+    /* Set time of occurring this alert. */
+    sprintf(paramStr, JLONG_FORMAT_STR, occurred_time);
+    pSender->addValue(alert_date, oid_len, paramStr, SNMP_VAR_TYPE_COUNTER64);
+
+    /* Set java heap usage. */
+    sprintf(paramStr, JLONG_FORMAT_STR, usage);
+    pSender->addValue(alert_usage, oid_len, paramStr, SNMP_VAR_TYPE_COUNTER64);
+
+    /* Set max capacity of java heap. */
+    sprintf(paramStr, JLONG_FORMAT_STR, maxCapacity);
+    pSender->addValue(alert_capacity, oid_len, paramStr, SNMP_VAR_TYPE_COUNTER64);
+
+    /* Send trap. */
+    if(unlikely(pSender->sendTrap() != SNMP_PROC_SUCCESS)){
+      /* Clean up. */
+      pSender->clearValues();
+      throw 1;
+    }
+
+  }
+  catch(...){
+    result = false;
+  }
+
+  return result;
+}
+
+/*!
  * \brief Output all-class information to file.
  * \param snapshot [in] Snapshot instance.
  * \return Sorted-class size information.
@@ -334,6 +420,28 @@
   /* Copy header. */
   TSnapShotFileHeader hdr;
   memcpy(&hdr, (const void *)snapshot->getHeader(), sizeof(TSnapShotFileHeader));
+
+  /* If java heap usage alert is enable. */
+  if(arg.HeapAlertThreshold > 0){
+    jlong usage = hdr.newAreaSize + hdr.oldAreaSize;
+
+    if(usage > arg.HeapAlertThreshold){
+      /* Raise alert. */
+      PRINT_WARN_MSG_HEADER
+                << "ALERT: Java heap usage exceeded the threshold ("
+                              << usage / 1024 / 1024 << " MB)" << NEWLINE;
+
+      /* If need send trap. */
+      if(arg.snmpSend){
+        if(unlikely(!sendMemoryUsageAlertTrap(pSender, ALERT_JAVA_HEAP,
+                            hdr.snapShotTime, usage, jvmInfo->getMaxMemory()))){
+          PRINT_WARN_MSG("SNMP trap send failed!");
+        }
+      }
+
+    }
+
+  }
   
   /* Allocate return array. */
   jlong rankCnt = this->classMap->size();
--- a/agent/src/classContainer.hpp	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/src/classContainer.hpp	Mon Aug 19 10:40:21 2013 +0900
@@ -58,6 +58,13 @@
 typedef std::deque<TClassContainer*> TLocalClassContainer;
 
 /*!
+ * \brief Memory usage alert types.
+ */
+typedef enum{
+  ALERT_JAVA_HEAP
+} TMemoryUsageAlertType;
+
+/*!
  * \brief This class is stored class information.<br>
  *        e.g. class-name, class instance count, size, etc...
  */
--- a/agent/src/libmain.cpp	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/src/libmain.cpp	Mon Aug 19 10:40:21 2013 +0900
@@ -203,8 +203,14 @@
     
     /* Calculate alert limit. */
     jlong MaxMemory = jvmInfo->getMaxMemory();
-    arg.AlertThreshold = (MaxMemory == -1)
-                                ? -1 : MaxMemory * arg.AlertPercentage / 100;
+    if(MaxMemory == -1){
+      arg.AlertThreshold = -1;
+      arg.HeapAlertThreshold = -1;
+    }
+    else{
+      arg.AlertThreshold = MaxMemory * arg.AlertPercentage / 100;
+      arg.HeapAlertThreshold = MaxMemory * arg.HeapAlertPercentage / 100;
+    }
     
     /* Inherited configuration setting. */
     inheritedSetting(&arg, &oldArg);
@@ -304,8 +310,14 @@
   
   /* Calculate alert limit. */
   jlong MaxMemory = jvmInfo->getMaxMemory();
-  arg.AlertThreshold = (MaxMemory == -1)
-                             ? -1 : MaxMemory * arg.AlertPercentage / 100;
+  if(MaxMemory == -1){
+    arg.AlertThreshold = -1;
+    arg.HeapAlertThreshold = -1;
+  }
+  else{
+    arg.AlertThreshold = MaxMemory * arg.AlertPercentage / 100;
+    arg.HeapAlertThreshold = MaxMemory * arg.HeapAlertPercentage / 100;
+  }
   
   /* Invoke JVM initialize event of snapshot function. */
   onVMInitForSnapShot(jvmti, env);
--- a/agent/src/trapSender.hpp	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/src/trapSender.hpp	Mon Aug 19 10:40:21 2013 +0900
@@ -112,6 +112,10 @@
  * \brief OID of deadlock alert trap.
  */
 #define SNMP_OID_DEADLOCKALERT SNMP_OID_PEN, 4
+/*!
+ * \brief OID of java heap usage alert trap.
+ */
+#define SNMP_OID_JAVAHEAPALERT SNMP_OID_PEN, 5
 
 /*!
  * \brief OID string of enterprice.
@@ -134,6 +138,10 @@
  * \brief OID string of deadlock alert trap.
  */
 #define OID_DEADLOCKALERT OID_PEN ".4.0"
+/*!
+ * \brief OID string of java heap usage alert trap.
+ */
+#define OID_JAVAHEAPALERT OID_PEN ".5.0"
 
 /*!
  * \brief This class is send trap to SNMP Manager. 
@@ -246,7 +254,7 @@
      * \brief Add trapOID to send information by trap.
      * \param trapOID[] [in] Identifier of trap.
      */
-    void setTrapOID(char *trapOID) {
+    void setTrapOID(const char *trapOID) {
       /* Setting trapOID. */
       oid OID_TRAPOID[] = {SNMP_OID_TRAPOID, 0};
       
@@ -266,7 +274,7 @@
      * \param type   [in] Kind of a variable.
      * \return Return process result code.
      */
-    int addValue(oid id[], int len, char *pValue, char type) {
+    int addValue(oid id[], int len, const char *pValue, char type) {
       
       /* Check param. */
       if (id == NULL || len <= 0 || pValue == NULL || type < 'A'
--- a/agent/src/util.cpp	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/src/util.cpp	Mon Aug 19 10:40:21 2013 +0900
@@ -154,6 +154,8 @@
   arg.order              = DELTA;
   arg.AlertPercentage    = 50;
   arg.AlertThreshold     = 0; /* Alert disabled. */
+  arg.HeapAlertPercentage= 95;
+  arg.HeapAlertThreshold = 0; /* Alert disabled. */
   arg.TimerInterval      = 0; /* Timer disabled. */
   arg.LogInterval        = 300000; /* 5min. */
   arg.firstCollect       = true;
@@ -514,6 +516,10 @@
           arg.AlertPercentage = ReadLongValue(key, value,
                                              arg.AlertPercentage, INT_MAX);
         }
+        else if (strcmp(key, "javaheap_alert_percentage") == 0) {
+          arg.HeapAlertPercentage = ReadLongValue(key, value,
+                                             arg.HeapAlertPercentage, INT_MAX);
+        }
         else if(strcmp(key, "snapshot_interval") == 0){
           arg.TimerInterval = ReadLongValue(key, value,
                                   arg.TimerInterval, LONG_MAX / 1000) * 1000;
@@ -721,6 +727,18 @@
       << "AlertPercentage = " << arg.AlertPercentage
       << " ( " << arg.AlertThreshold << " bytes )" << NEWLINE;
   }
+
+  /* Output about heap alert. */
+
+  if (arg.HeapAlertThreshold <= 0) {
+    PRINT_INFO_MSG_HEADER_NOIF << "Java heap usage alert is DISABLED." << NEWLINE;
+  }
+  else{
+    PRINT_INFO_MSG_HEADER_NOIF
+            << "Java heap usage alert percentage = " << arg.HeapAlertPercentage
+            << " ( " << arg.HeapAlertThreshold / 1024 / 1024 << " MB )"
+            << NEWLINE;
+  }
   
   /* Output about interval snapshot. */
   
--- a/agent/src/util.hpp	Thu Aug 15 11:47:19 2013 +0900
+++ b/agent/src/util.hpp	Mon Aug 19 10:40:21 2013 +0900
@@ -259,6 +259,8 @@
   TRankOrder order;        /*!< Order of ranking.                           */
   int AlertPercentage;     /*!< Percentage of trigger alert in heap.        */
   jlong AlertThreshold;    /*!< Size of trigger alert in heap.              */
+  int HeapAlertPercentage; /*!< Alert percentage of javaHeapAlert.          */
+  jlong HeapAlertThreshold;/*!< Trigger usage for javaHeapAlert.            */
   jlong TimerInterval;     /*!< Interval of periodic snapshot.              */
   jlong LogInterval;       /*!< Interval of periodic logging.               */
   bool firstCollect;       /*!< Logging on JVM error only first time.       */