#include "check_memfree.h" using namespace std; char *servicename = (char*)"MEMORY"; int getNum(string cmd) { char buffer[128]; stringstream sstr; FILE* pipe = popen(cmd.c_str(), "r"); while (!feof(pipe)) { if (fgets(buffer, 128, pipe) != NULL) { sstr.str(sstr.str()+buffer); } } pclose(pipe); int num; sstr >> num; return num; } void printVersion() { cout << "check_memfree v" << VERSION << endl << endl; } void printHelp(bool longVersion) { if(longVersion) { printVersion(); cout << "Check free memory space on local machine." << endl << endl; printHelp(false); cout << "Options:" << endl; cout << " -h" << endl; cout << " Print detailed help screen" << endl; cout << " -V" << endl; cout << " Print version information" << endl; cout << " -w INTEGER" << endl; cout << " Exit with WARNING status if less than INTEGER bytes of memory space are free" << endl; cout << " -w PERCENT%" << endl; cout << " Exit with WARNING status if less than PERCENT of memory space is free" << endl; cout << " -c INTEGER" << endl; cout << " Exit with CRITICAL status if less than INTEGER bytes of memory space are free" << endl; cout << " -c PERCENT%" << endl; cout << " Exit with CRITCAL status if less than PERCENT of memory space is free" << endl << endl; return; } cout << "Usage: " << endl << "check_memfree [-hV] -w % -c %" << endl << "check_memfree [-hV] -w -c " << endl << endl; } int main(int argc, char **argv) { struct itimerval timer; timer.it_value.tv_sec = 10; timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; setitimer (ITIMER_VIRTUAL, &timer, 0); struct sigaction sa; memset (&sa, 0, sizeof (sa)); sa.sa_handler = &timer_handler; sigaction (SIGVTALRM, &sa, 0); char *warningFlag = NULL; char *criticalFlag = NULL; int c; while ((c = getopt (argc, argv, "w:c:Vh")) != -1) { switch(c) { case 'w': warningFlag = optarg; break; case 'c': criticalFlag = optarg; break; case 'V': printVersion(); return 0; case 'h': printHelp(true); return 0; case '?': printHelp(false); return 3; } } if(warningFlag == NULL) { cout << "Warning limit (-w) wasn't set. Exiting." << endl; return 3; } if(criticalFlag == NULL) { cout << "Critical limit (-w) wasn't set. Exiting." << endl; return 3; } double freeMem = 0; double totalMem = 0; double pageSize = 0; totalMem = getNum("sysctl hw.physmem | cut -d' ' -f 2") / 1024; pageSize = getNum("sysctl hw.pagesize | cut -d' ' -f 2"); freeMem += getNum("sysctl vm.stats.vm.v_inactive_count | cut -d' ' -f 2") * pageSize; freeMem += getNum("sysctl vm.stats.vm.v_cache_count | cut -d' ' -f 2") * pageSize; freeMem += getNum("sysctl vm.stats.vm.v_free_count | cut -d' ' -f 2") * pageSize; freeMem /= 1024; int freeMemMB = freeMem / 1024; int totalMemMB = totalMem / 1024; int percFree = ((double)freeMemMB/(double)totalMemMB)*100; range warningLimit, criticalLimit; try { warningLimit = parseRange(warningFlag,totalMemMB); criticalLimit = parseRange(criticalFlag,totalMemMB); } catch(rangeException e) { cout << e.what() << endl; exit(3); } int returnCode; cout << servicename; if((freeMemMB > criticalLimit.min) && (freeMemMB < criticalLimit.max)) { cout << " CRITICAL"; returnCode = 2; } else if((freeMemMB > warningLimit.min) && (freeMemMB < warningLimit.max)) { cout << " WARNING"; returnCode = 1; } else { cout << " OK"; returnCode = 0; } cout << " - " << percFree << "% free (" << freeMemMB << " MB out of " << totalMemMB << " MB) |memory=" << freeMemMB << "MB;" << warningLimit.max << ";" << criticalLimit.max << ";" << "0;" << totalMemMB << endl; return returnCode; }