00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "mon_constants.h"
00040 #include "utils.h"
00041 #include "ApMon.h"
00042 #include "proc_utils.h"
00043
00044 #ifndef WIN32
00045 #include <dirent.h>
00046 #endif
00047
00048 using namespace apmon_utils;
00049
00050 void ProcUtils::getCPUUsage(ApMon& apm, double& cpuUsage,
00051 double& cpuUsr, double& cpuSys,
00052 double& cpuNice, double& cpuIdle, int numCPUs)
00053 throw (runtime_error, procutils_error) {
00054 #ifndef WIN32
00055 FILE *fp1;
00056 char line[MAX_STRING_LEN];
00057 char s1[20]; double usrTime, sysTime, niceTime, idleTime, totalTime;
00058 int indU, indS, indN, indI;
00059
00060 time_t crtTime = time(NULL);
00061 fp1 = fopen("/proc/stat", "r");
00062 if (fp1 == NULL)
00063 throw procutils_error((char*)"[ getCPUUsage() ] Could not open /proc/stat");
00064
00065 while (fgets(line, MAX_STRING_LEN, fp1)) {
00066 if (strstr(line, "cpu") == line)
00067 break;
00068 }
00069
00070 if (line == NULL) {
00071 fclose(fp1);
00072 throw procutils_error((char*)"[ getCPUUsage() ] Could not obtain CPU usage info from /proc/stat");
00073 }
00074 fclose(fp1);
00075
00076 sscanf(line, "%s %lf %lf %lf %lf", s1, &usrTime, &niceTime, &sysTime,
00077 &idleTime);
00078
00079 indU = getVectIndex( (char*)"cpu_usr", apm.sysMonitorParams, apm.nSysMonitorParams);
00080 indS = getVectIndex((char*)"cpu_sys", apm.sysMonitorParams, apm.nSysMonitorParams);
00081 indN = getVectIndex((char*)"cpu_nice", apm.sysMonitorParams, apm.nSysMonitorParams);
00082 indI = getVectIndex((char*)"cpu_idle", apm.sysMonitorParams, apm.nSysMonitorParams);
00083 if (idleTime < apm.lastSysVals[indI]) {
00084 apm.lastSysVals[indU] = usrTime;
00085 apm.lastSysVals[indS] = sysTime;
00086 apm.lastSysVals[indN] = niceTime;
00087 apm.lastSysVals[indI] = idleTime;
00088 throw runtime_error("[ getCPUUsage() ] CPU usage counter reset");
00089 }
00090
00091 if (numCPUs == 0)
00092 throw procutils_error((char*)"[ getCPUUsage() ] Number of CPUs was not initialized");
00093
00094
00095 if (crtTime <= apm.lastSysInfoSend)
00096 throw runtime_error("[ getCPUUsage() ] Current time <= time of the previous sysInfoSend");
00097
00098 totalTime = (usrTime - apm.lastSysVals[indU]) +
00099 (sysTime -apm.lastSysVals[indS]) +
00100 (niceTime - apm.lastSysVals[indN]) +
00101 (idleTime - apm.lastSysVals[indI]);
00102
00103 cpuUsr = 100 * (usrTime - apm.lastSysVals[indU]) / totalTime;
00104 cpuSys = 100 * (sysTime - apm.lastSysVals[indS]) / totalTime;
00105 cpuNice = 100 * (niceTime - apm.lastSysVals[indN]) / totalTime;
00106 cpuIdle = 100 * (idleTime - apm.lastSysVals[indI]) / totalTime;
00107 cpuUsage = 100 * (totalTime - (idleTime - apm.lastSysVals[indI])) / totalTime;
00108
00109 apm.lastSysVals[indU] = usrTime;
00110 apm.lastSysVals[indN] = niceTime;
00111 apm.lastSysVals[indI] = idleTime;
00112 apm.lastSysVals[indS] = sysTime;
00113 #endif
00114 }
00115
00116 void ProcUtils::getSwapPages(ApMon& apm, double& pagesIn,
00117 double& pagesOut, double& swapIn,
00118 double& swapOut)
00119 throw (runtime_error, procutils_error) {
00120 #ifndef WIN32
00121 FILE *fp1;
00122 char line[MAX_STRING_LEN];
00123 char s1[20];
00124 bool foundPages, foundSwap;
00125 double p_in, p_out, s_in, s_out;
00126 int ind1, ind2;
00127
00128 time_t crtTime = time(NULL);
00129 fp1 = fopen("/proc/stat", "r");
00130 if (fp1 == NULL)
00131 throw procutils_error((char*)"[ getSwapPages() ] Could not open /proc/stat");
00132 if (crtTime <= apm.lastSysInfoSend)
00133 throw runtime_error("[ getSwapPages() ] Current time <= time of the previous sysInfoSend");
00134
00135 foundPages = foundSwap = false;
00136 while (fgets(line, MAX_STRING_LEN, fp1)) {
00137 if (strstr(line, "page") == line) {
00138 foundPages = true;
00139 sscanf(line, "%s %lf %lf ", s1, &p_in, &p_out);
00140
00141 ind1 = getVectIndex((char*)"pages_in", apm.sysMonitorParams, apm.nSysMonitorParams);
00142 ind2 = getVectIndex((char*)"pages_out", apm.sysMonitorParams, apm.nSysMonitorParams);
00143 if (p_in < apm.lastSysVals[ind1] || p_out < apm.lastSysVals[ind2]) {
00144 apm.lastSysVals[ind1] = p_in;
00145 apm.lastSysVals[ind2] = p_out;
00146 throw runtime_error("[ getSwapPages() ] Pages in/out counter reset");
00147 }
00148 pagesIn = (p_in - apm.lastSysVals[ind1]) / (crtTime - apm.lastSysInfoSend);
00149 pagesOut = (p_out - apm.lastSysVals[ind2]) / (crtTime - apm.lastSysInfoSend);
00150 apm.lastSysVals[ind1] = p_in;
00151 apm.lastSysVals[ind2] = p_out;
00152
00153 }
00154
00155 if (strstr(line, "swap") == line) {
00156 foundSwap = true;
00157 sscanf(line, "%s %lf %lf ", s1, &s_in, &s_out);
00158
00159 ind1 = getVectIndex((char*)"swap_in", apm.sysMonitorParams, apm.nSysMonitorParams);
00160 ind2 = getVectIndex((char*)"swap_out", apm.sysMonitorParams, apm.nSysMonitorParams);
00161 if (s_in < apm.lastSysVals[ind1] || s_out < apm.lastSysVals[ind2]) {
00162 apm.lastSysVals[ind1] = s_in;
00163 apm.lastSysVals[ind2] = s_out;
00164 throw runtime_error("[ getSwapPages() ] Swap in/out counter reset");
00165 }
00166 swapIn = (s_in - apm.lastSysVals[ind1]) / (crtTime - apm.lastSysInfoSend);
00167 swapOut = (s_out - apm.lastSysVals[ind2]) / (crtTime - apm.lastSysInfoSend);
00168 apm.lastSysVals[ind1] = s_in;
00169 apm.lastSysVals[ind2] = s_out;
00170
00171 }
00172 }
00173
00174 fclose(fp1);
00175
00176 if (!foundPages || !foundSwap) {
00177 throw procutils_error((char*)"[ getSwapPages() ] Could not obtain swap/pages in/out from /proc/stat");
00178 }
00179 #endif
00180 }
00181
00182 void ProcUtils::getLoad(double &load1, double &load5,
00183 double &load15, double &processes)
00184 throw(procutils_error) {
00185 #ifndef WIN32
00186 double v1, v5, v15, activeProcs, totalProcs;
00187 FILE *fp1;
00188
00189 fp1 = fopen("/proc/loadavg", "r");
00190 if (fp1 == NULL)
00191 throw procutils_error((char*)"[ getLoad() ] Could not open /proc/loadavg");
00192
00193 fscanf(fp1, "%lf %lf %lf", &v1, &v5, &v15);
00194 load1 = v1;
00195 load5 = v5;
00196 load15 = v15;
00197
00198 fscanf(fp1, "%lf/%lf", &activeProcs, &totalProcs);
00199 processes = totalProcs;
00200 fclose(fp1);
00201 #endif
00202 }
00203
00204 void ProcUtils::getProcesses(double& processes, double states[])
00205 throw(runtime_error) {
00206 #ifndef WIN32
00207 char *argv[4];
00208 char psstat_f[40];
00209 pid_t mypid = getpid();
00210 pid_t cpid;
00211 int status;
00212 char ch, buf[100];
00213 FILE *pf;
00214
00215 sprintf(psstat_f, "/tmp/apmon_psstat%d", mypid);
00216
00217 switch (cpid = fork()) {
00218 case -1:
00219 throw runtime_error("[ getProcesses() ] Unable to fork()");
00220 case 0:
00221 argv[0] = (char *)"/bin/sh"; argv[1] = (char *)"-c";
00222 sprintf(buf, "ps -A -o state > %s",
00223 psstat_f);
00224 argv[2] = buf;
00225 argv[3] = 0;
00226 execv("/bin/sh", argv);
00227 exit(RET_ERROR);
00228 default:
00229 if (waitpid(cpid, &status, 0) == -1) {
00230 sprintf(buf, "[ getProcesses() ] The number of processes could not be determined");
00231 throw runtime_error(buf);
00232 }
00233 break ;
00234 }
00235
00236 pf = fopen(psstat_f, "rt");
00237 if (pf == NULL) {
00238 unlink(psstat_f);
00239 sprintf(buf, "[ getProcesses() ] The number of processes could not be determined");
00240 throw runtime_error(buf);
00241 }
00242
00243 processes = 0;
00244
00245
00246 for (int i = 0; i < NLETTERS; i++)
00247 states[i] = 0.0;
00248 while (fgets(buf, 10, pf) > 0) {
00249 ch = buf[0];
00250 states[ch - 65]++;
00251 processes++;
00252 }
00253
00254 fclose(pf);
00255 unlink(psstat_f);
00256 #endif
00257 }
00258
00259 void ProcUtils::getSysMem(double &totalMem, double &totalSwap)
00260 throw(procutils_error) {
00261 #ifndef WIN32
00262 char s1[20], line[MAX_STRING_LEN];
00263 bool memFound = false, swapFound = false;
00264 double valMem, valSwap;
00265 FILE *fp1;
00266
00267 fp1 = fopen("/proc/meminfo", "r");
00268 if (fp1 == NULL)
00269 throw procutils_error((char*)"[ getSysMem() ] Could not open /proc/meminfo");
00270
00271 while (fgets(line, MAX_STRING_LEN, fp1)) {
00272 if (strstr(line, "MemTotal:") == line) {
00273 sscanf(line, "%s %lf", s1, &valMem);
00274 memFound = true;
00275 continue;
00276 }
00277
00278 if (strstr(line, "SwapTotal:") == line) {
00279 sscanf(line, "%s %lf", s1, &valSwap);
00280 swapFound = true;
00281 continue;
00282 }
00283
00284 }
00285 fclose(fp1);
00286
00287 if (!memFound || !swapFound)
00288 throw procutils_error((char*)"[ getSysMem() ] Could not obtain memory info from /proc/meminfo");
00289 totalMem = valMem;
00290 totalSwap = valSwap;
00291 #endif
00292 }
00293
00294 void ProcUtils::getMemUsed(double &usedMem, double& freeMem,
00295 double &usedSwap, double& freeSwap)
00296 throw(procutils_error) {
00297 #ifndef WIN32
00298 double mFree = 0, mTotal = 0, sFree = 0, sTotal = 0;
00299 char s1[20], line[MAX_STRING_LEN];
00300 bool mFreeFound = false, mTotalFound = false;
00301 bool sFreeFound = false, sTotalFound = false;
00302 FILE *fp1;
00303
00304 fp1 = fopen("/proc/meminfo", "r");
00305 if (fp1 == NULL)
00306 throw procutils_error((char*)"[ getMemUsed() ] Could not open /proc/meminfo");
00307
00308 while (fgets(line, MAX_STRING_LEN, fp1)) {
00309 if (strstr(line, "MemTotal:") == line) {
00310 sscanf(line, "%s %lf", s1, &mTotal);
00311 mTotalFound = true;
00312 continue;
00313 }
00314
00315 if (strstr(line, "MemFree:") == line) {
00316 sscanf(line, "%s %lf", s1, &mFree);
00317 mFreeFound = true;
00318 continue;
00319 }
00320
00321 if (strstr(line, "SwapTotal:") == line) {
00322 sscanf(line, "%s %lf", s1, &sTotal);
00323 sTotalFound = true;
00324 continue;
00325 }
00326
00327 if (strstr(line, "SwapFree:") == line) {
00328 sscanf(line, "%s %lf", s1, &sFree);
00329 sFreeFound = true;
00330 continue;
00331 }
00332
00333 }
00334 fclose(fp1);
00335
00336 if (!mFreeFound || !mTotalFound || !sFreeFound || !sTotalFound)
00337 throw procutils_error((char*)"[ getMemUsed() ] Could not obtain memory info from /proc/meminfo");
00338
00339 usedMem = (mTotal - mFree) / 1024;
00340 freeMem = mFree / 1024;
00341 usedSwap = (sTotal - sFree) / 1024;
00342 freeSwap = sFree / 1024;
00343 #endif
00344 }
00345
00346 void ProcUtils::getNetworkInterfaces(int &nInterfaces,
00347 char names[][20]) throw(procutils_error) {
00348 #ifndef WIN32
00349 char line[MAX_STRING_LEN], *tmp;
00350
00351
00352 FILE *fp1;
00353
00354 nInterfaces = 0;
00355
00356 fp1 = fopen("/proc/net/dev", "r");
00357 if (fp1 == NULL)
00358 throw procutils_error((char*)"[ getMemUsed() ] Could not open /proc/net/dev");
00359 while (fgets(line, MAX_STRING_LEN, fp1)) {
00360 if (strchr(line, ':') == NULL)
00361 continue;
00362
00363 tmp = strtok(line, " :");
00364
00365 if (strcmp(tmp, "lo") == 0)
00366 continue;
00367
00368 strcpy(names[nInterfaces], tmp);
00369 nInterfaces++;
00370 }
00371
00372 fclose(fp1);
00373 #endif
00374 }
00375
00376 void ProcUtils::getNetInfo(ApMon& apm, double **vNetIn,
00377 double **vNetOut, double **vNetErrs)
00378 throw(runtime_error, procutils_error) {
00379 #ifndef WIN32
00380 double *netIn, *netOut, *netErrs, bytesReceived, bytesSent;
00381 int errs;
00382 char line[MAX_STRING_LEN], msg[MAX_STRING_LEN];
00383
00384
00385 char *tmp, *tok;
00386 long bootTime = 0;
00387 FILE *fp1;
00388 time_t crtTime = time(NULL);
00389 int ind, i;
00390
00391 if (apm.lastSysInfoSend == 0) {
00392 try {
00393 bootTime = getBootTime();
00394 } catch (procutils_error& ) {
00395 logger(WARNING, "[ getNetInfo() ] Error obtaining boot time. The first system monitoring datagram will contain incorrect data.");
00396 bootTime = 0;
00397 }
00398 }
00399
00400 if (crtTime <= apm.lastSysInfoSend)
00401 throw runtime_error("[ getNetInfo() ] Current time <= time of the previous sysInfoSend");
00402
00403 fp1 = fopen("/proc/net/dev", "r");
00404 if (fp1 == NULL)
00405 throw procutils_error((char*)"[ getNetInfo() ] Could not open /proc/net/dev");
00406
00407 netIn = (double *)malloc(apm.nInterfaces * sizeof(double));
00408 netOut = (double *)malloc(apm.nInterfaces * sizeof(double));
00409 netErrs = (double *)malloc(apm.nInterfaces * sizeof(double));
00410
00411 while (fgets(line, MAX_STRING_LEN, fp1)) {
00412 if (strchr(line, ':') == NULL)
00413 continue;
00414 tmp = strtok(line, " :");
00415
00416
00417 if (strcmp(tmp, "lo") == 0)
00418 continue;
00419
00420
00421 ind = -1;
00422 for (i = 0; i < apm.nInterfaces; i++)
00423 if (strcmp(apm.interfaceNames[i], tmp) == 0) {
00424 ind = i;
00425 break;
00426 }
00427
00428 if (ind < 0) {
00429 fclose(fp1);
00430 free(netIn); free(netOut); free(netErrs);
00431 sprintf(msg, "[ getNetInfo() ] Could not find interface %s in /proc/net/dev",
00432 tmp);
00433 throw runtime_error(msg);
00434 }
00435
00436
00437 tok = strtok(NULL, " ");
00438 bytesReceived = atof(tok);
00439 tok = strtok(NULL, " ");
00440 tok = strtok(NULL, " ");
00441 errs = atoi(tok);
00442
00443 for (i = 1; i <= 5; i++)
00444 tok = strtok(NULL, " ");
00445
00446 tok = strtok(NULL, " ");
00447 bytesSent = atof(tok);
00448 tok = strtok(NULL, " ");
00449 tok = strtok(NULL, " ");
00450 errs += atoi(tok);
00451
00452
00453
00454 if (bytesReceived < apm.lastBytesReceived[ind] || bytesSent <
00455 apm.lastBytesSent[ind] || errs < apm.lastNetErrs[ind]) {
00456 apm.lastBytesReceived[ind] = bytesReceived;
00457 apm.lastBytesSent[ind] = bytesSent;
00458 apm.lastNetErrs[ind] = errs;
00459 fclose(fp1);
00460 free(netIn); free(netOut); free(netErrs);
00461 throw runtime_error("[ getNetInfo() ] Network interface(s) restarted.");
00462 }
00463
00464 if (apm.lastSysInfoSend == 0) {
00465 netIn[ind] = bytesReceived/(crtTime - bootTime);
00466 netOut[ind] = bytesSent/(crtTime - bootTime);
00467 netErrs[ind] = errs;
00468 }
00469 else {
00470 netIn[ind] = (bytesReceived - apm.lastBytesReceived[ind]) / (crtTime -
00471 apm.lastSysInfoSend);
00472 netIn[ind] /= 1024;
00473 netOut[ind] = (bytesSent - apm.lastBytesSent[ind]) / (crtTime -
00474 apm.lastSysInfoSend);
00475 netOut[ind] /= 1024;
00476
00477 netErrs[ind] = errs;
00478 }
00479
00480 apm.lastBytesReceived[ind] = bytesReceived;
00481 apm.lastBytesSent[ind] = bytesSent;
00482 apm.lastNetErrs[ind] = errs;
00483 }
00484
00485 fclose(fp1);
00486 *vNetIn = netIn;
00487 *vNetOut = netOut;
00488 *vNetErrs = netErrs;
00489 #endif
00490 }
00491
00492 int ProcUtils::getNumCPUs() throw(procutils_error) {
00493 #ifdef WIN32
00494 return 0;
00495 #else
00496 int numCPUs = 0;
00497 char line[MAX_STRING_LEN];
00498
00499 FILE *fp = fopen("/proc/stat", "r");
00500
00501 if (fp == NULL)
00502 throw procutils_error((char*)"[ getNumCPUs() ] Could not open /proc/stat.");
00503
00504 while(fgets(line, MAX_STRING_LEN, fp)) {
00505 if (strstr(line, "cpu") == line && isdigit(line[3]))
00506 numCPUs++;
00507 }
00508
00509 fclose(fp);
00510 return numCPUs;
00511 #endif
00512 }
00513
00514 void ProcUtils::getCPUInfo(ApMon& apm) throw(procutils_error) {
00515 #ifndef WIN32
00516 double freq = 0;
00517 char line[MAX_STRING_LEN], s1[100], s2[100], s3[100];
00518
00519
00520 char *tmp, *tmp_trim;
00521 bool freqFound = false, bogomipsFound = false;
00522
00523 FILE *fp = fopen("/proc/cpuinfo", "r");
00524 if (fp == NULL)
00525 throw procutils_error((char*)"[ getCPUInfo() ] Could not open /proc/cpuinfo");
00526
00527 while (fgets(line, MAX_STRING_LEN, fp)) {
00528 if (strstr(line, "cpu MHz") == line) {
00529 sscanf(line, "%s %s %s %lf", s1, s2, s3, &freq);
00530 apm.currentGenVals[GEN_CPU_MHZ] = freq;
00531 freqFound = true;
00532 continue;
00533 }
00534
00535 if (strstr(line, "bogomips") == line) {
00536 sscanf(line, "%s %s %lf", s1, s2, &(apm.currentGenVals[GEN_BOGOMIPS]));
00537 bogomipsFound = true;
00538 continue;
00539 }
00540
00541 if (strstr(line, "vendor_id") == line) {
00542 tmp = strtok(line, ":");
00543
00544 tmp = strtok(NULL, ":");
00545 tmp_trim = trimString(tmp);
00546 strcpy(apm.cpuVendor, tmp_trim);
00547 free(tmp_trim);
00548 continue;
00549 }
00550
00551 if (strstr(line, "cpu family") == line) {
00552 tmp = strtok(line, ":");
00553 tmp = strtok(NULL, ":");
00554 tmp_trim = trimString(tmp);
00555 strcpy(apm.cpuFamily, tmp_trim);
00556 free(tmp_trim);
00557 continue;
00558 }
00559
00560 if (strstr(line, "model") == line && strstr(line, "model name") != line) {
00561 tmp = strtok(line, ":");
00562 tmp = strtok(NULL, ":");
00563 tmp_trim = trimString(tmp);
00564 strcpy(apm.cpuModel, tmp_trim);
00565 free(tmp_trim);
00566 continue;
00567 }
00568
00569 if (strstr(line, "model name") == line) {
00570 tmp = strtok(line, ":");
00571
00572 tmp = strtok(NULL, ":");
00573 tmp_trim = trimString(tmp);
00574 strcpy(apm.cpuModelName, tmp_trim);
00575 free(tmp_trim);
00576 continue;
00577 }
00578 }
00579
00580 fclose(fp);
00581 if (!freqFound || !bogomipsFound)
00582 throw procutils_error((char*)"[ getCPUInfo() ] Could not find frequency or bogomips in /proc/cpuinfo");
00583 #endif
00584 }
00585
00589 long ProcUtils::getBootTime() throw (procutils_error) {
00590 #ifdef WIN32
00591 return 0;
00592 #else
00593 char line[MAX_STRING_LEN], s[MAX_STRING_LEN];
00594 long btime = 0;
00595 FILE *fp = fopen("/proc/stat", "rt");
00596 if (fp == NULL)
00597 throw procutils_error((char*)"[ getBootTime() ] Could not open /proc/stat");
00598
00599 while (fgets(line, MAX_STRING_LEN, fp)) {
00600 if (strstr(line, "btime") == line) {
00601 sscanf(line, "%s %ld", s, &btime);
00602 break;
00603 }
00604 }
00605 fclose(fp);
00606 if (btime == 0)
00607 throw procutils_error((char*)"[ getBootTime() ] Could not find boot time in /proc/stat");
00608 return btime;
00609 #endif
00610 }
00611
00612
00613 double ProcUtils::getUpTime() throw(procutils_error) {
00614 #ifdef WIN32
00615 return 0;
00616 #else
00617 double uptime = 0;
00618 FILE *fp = fopen("/proc/uptime", "rt");
00619 if (fp == NULL) {
00620 throw procutils_error((char*)"[ getUpTime() ] Could not open /proc/uptime");
00621 }
00622
00623 fscanf(fp, "%lf", &uptime);
00624 fclose(fp);
00625
00626 if (uptime <= 0) {
00627 throw procutils_error((char*)"[ getUpTime() ] Could not find uptime in /proc/uptime");
00628 }
00629 return uptime / (24 * 3600);
00630 #endif
00631 }
00632
00633 int ProcUtils::countOpenFiles(long pid) throw(procutils_error) {
00634 #ifdef WIN32
00635 return 0;
00636 #else
00637 char dirname[50];
00638 char msg[MAX_STRING_LEN];
00639 DIR *dir;
00640 int cnt = 0;
00641
00642
00643 sprintf(dirname, "/proc/%ld/fd", pid);
00644 dir = opendir(dirname);
00645 if (dir == NULL) {
00646 sprintf(msg, "[ countOpenFiles() ] Could not open %s", dirname);
00647 throw procutils_error(msg);
00648 }
00649
00650
00651 while (readdir(dir) != NULL) {
00652 cnt++;
00653 }
00654
00655 closedir(dir);
00656
00657
00658 cnt -= 2;
00659 if (cnt < 0) {
00660 sprintf(msg, "[ countOpenFiles() ] Directory %s has less than 2 entries",
00661 dirname);
00662 logger(FINE, msg);
00663 cnt = 0;
00664 }
00665
00666 return cnt;
00667 #endif
00668 }
00669
00670 void ProcUtils::getNetstatInfo(ApMon& apm, double nsockets[],
00671 double tcp_states[])
00672 throw(runtime_error) {
00673
00674
00675
00676 int i;
00677 for (i = 0; i < 4; i++)
00678 nsockets[i] = 0.0;
00679 for (i = 0; i < N_TCP_STATES; i++)
00680 tcp_states[i] = 0.0;
00681
00682 #ifndef WIN32
00683 char *argv[4];
00684 char netstat_f[40];
00685 pid_t mypid = getpid();
00686 pid_t cpid;
00687 int status, idx;
00688 char buf[100], msg[100];
00689 char *pbuf = buf, *tmp, *tmp2;
00690 FILE *pf;
00691
00692 sprintf(netstat_f, "/tmp/apmon_netstat%d", mypid);
00693
00694 switch (cpid = fork()) {
00695 case -1:
00696 throw runtime_error("[ getNetstatInfo() ] Unable to fork()");
00697 case 0:
00698 argv[0] = (char *)"/bin/sh"; argv[1] = (char *)"-c";
00699 sprintf(buf, "netstat -an > %s",
00700 netstat_f);
00701 argv[2] = buf;
00702 argv[3] = 0;
00703 execv("/bin/sh", argv);
00704 exit(RET_ERROR);
00705 default:
00706 if (waitpid(cpid, &status, 0) == -1) {
00707 sprintf(msg, "[ getNetstatInfo() ] The netstat information could not be collected");
00708 throw runtime_error(msg);
00709 }
00710 break ;
00711 }
00712
00713 pf = fopen(netstat_f, "rt");
00714 if (pf == NULL) {
00715 unlink(netstat_f);
00716 sprintf(msg, "[ getNetstatInfo() ] The netstat information could not be collected");
00717 throw runtime_error(msg);
00718 }
00719
00720 while (fgets(buf, 200, pf) > 0) {
00721 tmp = strtok_r(buf, " \t\n", &pbuf);
00722 if (strstr(tmp, "tcp") == tmp) {
00723 nsockets[SOCK_TCP]++;
00724
00725
00726 for (i = 1; i <= 5; i++)
00727 tmp2 = strtok_r(NULL, " \t\n", &pbuf);
00728
00729 idx = getVectIndex(tmp2, apm.socketStatesMapTCP, N_TCP_STATES);
00730 if (idx >= 0) {
00731 tcp_states[idx]++;
00732 } else {
00733 sprintf(msg, "[ getNestatInfo() ] Invalid socket state: %s q", tmp2);
00734 logger(WARNING, msg);
00735 }
00736 } else {
00737 if (strstr(tmp, "udp") == tmp) {
00738 nsockets[SOCK_UDP]++;
00739 } else {
00740 if (strstr(tmp, "unix") == tmp)
00741 nsockets[SOCK_UNIX]++;
00742 else if (strstr(tmp, "icm") == tmp)
00743 nsockets[SOCK_ICM]++;
00744 }
00745 }
00746 }
00747
00748 fclose(pf);
00749 unlink(netstat_f);
00750 #endif
00751 }