# HG changeset patch # User Yasumasa Suenaga # Date 1376876421 -32400 # Node ID 6fec952098441451a2fa81c2c2d65c30c6cac6b7 # Parent 8a3de8e3526cafc7d5bdc6b7d160bb4e3cfdfd7c Bug 1522: Add Java heap alert. reviewed-by: shintak diff -r 8a3de8e3526c -r 6fec95209844 agent/ChangeLog --- 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 + + * Bug 1522: Add Java heap alert. + 2013-08-15 Yasumasa Suenaga * Bug 1496: SNMP MIB definitions are missing except HeapAlert trap. diff -r 8a3de8e3526c -r 6fec95209844 agent/heapstats.conf.in --- 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 diff -r 8a3de8e3526c -r 6fec95209844 agent/mib/HeapStatsMibs.txt --- 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 diff -r 8a3de8e3526c -r 6fec95209844 agent/src/classContainer.cpp --- 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(); diff -r 8a3de8e3526c -r 6fec95209844 agent/src/classContainer.hpp --- 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 TLocalClassContainer; /*! + * \brief Memory usage alert types. + */ +typedef enum{ + ALERT_JAVA_HEAP +} TMemoryUsageAlertType; + +/*! * \brief This class is stored class information.
* e.g. class-name, class instance count, size, etc... */ diff -r 8a3de8e3526c -r 6fec95209844 agent/src/libmain.cpp --- 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); diff -r 8a3de8e3526c -r 6fec95209844 agent/src/trapSender.hpp --- 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' diff -r 8a3de8e3526c -r 6fec95209844 agent/src/util.cpp --- 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. */ diff -r 8a3de8e3526c -r 6fec95209844 agent/src/util.hpp --- 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. */