The architecture of the Resource Monitor defines five primary components:
// *************************************************************************** // CplusplusExample.cpp - description // This example shows a C++ style setup of a bidirectional threshold monitor // required compile options: -I/usr/include/ResourceMonitor // required link options: -lResourceMonitor -luuid // *************************************************************************** #include <ResourceMonitor.h> #include <RM_ProcessMonitor.h> ResourceMonitor::RMmonitor *CreateVirtualMemoryMonitor(rmValue threshold) { RMuid ssid = RMuid(RM_PROCESS_UUID_STRING); rmMonitorControl moncontrol; rmMonitorConfiguration monconfig; monconfig.statisticKey.SubsystemId = ssid.id; monconfig.statisticKey.ResourceId = getpid(); monconfig.statisticKey.StatisticId = STAT_vsize_ID; monconfig.monitorType = rmThresholding; monconfig.statisticTransform = rmNone; monconfig.RMThresholdType = rmThreshold; monconfig.RMThresholdValue.rmValue32 = threshold.rmValue32; monconfig.RMThresholdCondition = rmValueIsAtOrAbove; monconfig.RMThresholdPrecondition = rmNoPrecondition; monconfig.RMThresholdEventSeverity = LOG_WARNING; monconfig.RMThresholdCancelEventSeverity = LOG_NOTICE; moncontrol.monitorType = rmThresholding; clearMonitorUID(moncontrol); clearDataCapture(moncontrol); moncontrol.location = rmDaemon; moncontrol.monitorId = 0; // unused for daemon monitors moncontrol.monitoringInterval = 0; // monitor until stopped moncontrol.monitoringRate = 5; // check every 5 seconds moncontrol.microMonitoringRate = 0; // check every 5 seconds moncontrol.RMThresholdTolerance.rmValueU32 = 0; // qualifies what "At" or "equal to" is moncontrol.RMThresholdSamples = 2; // log event after 2 consecutive readings above the threshold moncontrol.RMThresholdLoggingRate = 60; // log events no more than once a minute try { ResourceMonitor::RMmonitor *mp = new ResourceMonitor::RMmonitor(monconfig, &moncontrol); mp->StartMonitor(); return mp; } catch(...) { cerr << "failed to create CreateVirtualMemoryMonitor" << endl; return 0; } }
// *************************************************************************** // Cexample.c - description // This example shows a C-style setup of a bidirectional threshold monitor // required compile options: -I/usr/include/ResourceMonitor // required link options: -lResourceMonitor -luuid // *************************************************************************** #include <ResourceMonitor.h> #include <RM_ProcessMonitor.h> #include <stdio.h> rmHandle CreateVirtualMemoryMonitor(rmValue threshold) { rmHandle handle; rmMonitorControl moncontrol; rmMonitorConfiguration monconfig; uuid_parse(RM_PROCESS_UUID_STRING, monconfig.statisticKey.SubsystemId); monconfig.statisticKey.ResourceId = getpid(); monconfig.statisticKey.StatisticId = STAT_vsize_ID; monconfig.monitorType = rmThresholding; monconfig.statisticTransform = rmNone; monconfig.RMThresholdType = rmThreshold; monconfig.RMThresholdValue.rmValue32 = threshold.rmValueU32; monconfig.RMThresholdCondition = rmValueIsAtOrAbove; monconfig.RMThresholdPrecondition = rmNoPrecondition; monconfig.RMThresholdEventSeverity = LOG_WARNING; monconfig.RMThresholdCancelEventSeverity = LOG_NOTICE; moncontrol.monitorType = rmThresholding; clearMonitorUID(moncontrol); clearDataCapture(moncontrol); moncontrol.location = rmDaemon; moncontrol.monitoringInterval = 0; // monitor until stopped moncontrol.monitoringRate = 5; // check every 5 seconds moncontrol.microMonitoringRate = 0; // check every 5 seconds moncontrol.RMThresholdTolerance.rmValue32 = 0; // qualifies what "At" or "NotAt" is moncontrol.RMThresholdSamples = 2; // log event after 2 consecutive readings above the threshold moncontrol.RMThresholdLoggingRate = 60; // log events no more than once a minute handle = rmCreateMonitor( &monconfig, &moncontrol); if( handle == 0 ) perror("rmCreateMonitor"); else rmStartMonitor(handle); return handle; }
// *************************************************************************** // EventingExample.c - description // required compile options: -I/usr/include/ResourceMonitor // required link options: -lResourceMonitor -luuid -levl -lnsl -lpthread // *************************************************************************** #include <ResourceMonitor.h> #include <RM_ProcessMonitor.h> #include <stdio.h> #include <stdlib.h> #define SMALLBUFSIZE 1024 #include <string.h> int eventReceived = 0; rmHandle CreateVirtualMemoryMonitor(rmValue threshold) { rmHandle handle; rmMonitorControl moncontrol; rmMonitorConfiguration monconfig; uuid_parse(RM_PROCESS_UUID_STRING, monconfig.statisticKey.SubsystemId); monconfig.statisticKey.ResourceId = getpid(); monconfig.statisticKey.StatisticId = STAT_vsize_ID; monconfig.monitorType = rmThresholding; monconfig.statisticTransform = rmNone; monconfig.RMThresholdType = rmThreshold; monconfig.RMThresholdValue.rmValueU32 = threshold.rmValueU32; monconfig.RMThresholdCondition = rmValueIsAtOrAbove; monconfig.RMThresholdPrecondition = rmNoPrecondition; monconfig.RMThresholdEventSeverity = LOG_WARNING; monconfig.RMThresholdCancelEventSeverity = LOG_NOTICE; moncontrol.monitorType = rmThresholding; clearMonitorUID(moncontrol); clearDataCapture(moncontrol); moncontrol.location = rmDaemon; moncontrol.monitoringInterval = 0; // monitor until stopped moncontrol.monitoringRate = 5; // check every 5 seconds moncontrol.microMonitoringRate = 0; // check every 5 seconds moncontrol.RMThresholdTolerance.rmValueU32 = 0; // qualifies what "At" or "NotAt" is moncontrol.RMThresholdSamples = 2; // log event after 2 consecutive readings above the threshold moncontrol.RMThresholdLoggingRate = 60; // log events no more than once a minute handle = rmCreateMonitor( &monconfig, &moncontrol); if( handle == 0 ) perror("rmCreateMonitor"); else rmStartMonitor(handle); return handle; } // // The call to posix_log_notify_add registered a query // string and this function as the callback. If the query // evaluates to true for any incoming event, then this // function will be called. Normal application execution // continues after this function returns. // void catchNotificationEvent(int signo, siginfo_t *info, void *ignored) { posix_log_recid_t recid; rmHandle handle = (rmHandle)info->si_int; rmMonitorState state; rmGetMonitorState( handle, &state); // Get the recid of the event that caused this function call. // IBM : we change our posix API - see update posix_log_siginfo_getrecid(info, ignored, &recid); printf(" signal=%d from event: handle=%d, Record ID=%d\n", info->si_signo, info->si_int, recid); rmStopMonitor(handle); rmDeleteMonitor(handle); eventReceived = 1; } int TestVirtualMemoryEvent() { char query_string[SMALLBUFSIZE], error_string[SMALLBUFSIZE]; int once = 0; posix_log_notify_t notifyThresholdHandle; // Remember the monitor's query_handle and its query posix_log_query_t thresholdQuery; // so we can stuff them into the Monitorset to use later. struct sigaction SigRTAction; // IBM's way of defining the signal handler... struct sigevent mynotification; char monitor_string[MAX_GUID_STRLEN]; rmHandle handle = CreateVirtualMemoryMonitor( (rmValue)(u_int32_t)1, 0); rmMonitorControl control; if( handle == 0 ) return 1; // Initialize thresholdNotification with the local function name which is to be the callback function // and set the desired POSIX signal value. If your application only needs one callback registration // then use SIGRTMIN+1. For each additional callback function, you should use different signal values // between SIGRTMIN to SIGRTMAX (a range of 32 values). mynotification.sigev_value.sival_int = (int)handle; // pass monitor handle to event handler mynotification.sigev_notify = SIGEV_SIGNAL; mynotification.sigev_signo = SIGRTMIN + 1; // needs to match the sigaction number below (void) memset(&SigRTAction, 0, sizeof(SigRTAction)); SigRTAction.sa_flags = SA_SIGINFO | SA_RESTART; SigRTAction.sa_handler = (void (*) (int)) catchNotificationEvent; // to use catchNotificationEvent() for this Monitor's events. if (sigaction( SIGRTMIN + 1, // signo_offset can typically default to 0, if &SigRTAction, NULL) < 0) { // you are only using a single listener. perror("sigaction failed for new SIGRTMIN."); return 1; } // Initialize m_notification with the local function name which is // to be the callback function and set the desired POSIX signal // value. If your application only needs one callback registration // then use SIGRTMIN+1. For each additional callback function, you // should use different signal values between SIGRTMIN to SIGRTMAX // (a range of 32 values). // A query string will typically consist of a monitor's RID // e.g. "data contains \"Monitor_ID=cc63f3bb-d74b-41a0-ab46-5d81579c9b11\"" rmGetMonitorControl(handle, &control); uuid_unparse(control.uid, monitor_string); snprintf(query_string,SMALLBUFSIZE,"data contains \"Monitor_ID=%s\" && severity=WARNING",monitor_string); // Register the query string and check it for basic syntax req. if(posix_log_query_create( query_string, POSIX_LOG_PRPS_NOTIFY, &thresholdQuery, error_string, SMALLBUFSIZE) != 0) { perror("could not create threshold query!"); return 1; } if(posix_log_notify_add(&thresholdQuery, &mynotification, once, ¬ifyThresholdHandle)!=0) { perror("Threshold posix_log_notify_add() failed"); posix_log_query_destroy(&thresholdQuery); return 1; } printf("Registered Threshold Notification with POSIX Event logger (handle=%d)\n", notifyThresholdHandle); while(eventReceived==0) { sleep(1); if( ++once > 10 ) return 1; } return 0; } int main(int argc, char *argv[]) { if( TestVirtualMemoryEvent() == 0 ) exit( EXIT_SUCCESS ); exit(1); }
kill -SIGNAL `cat /var/run/resourcemonitord.pid`