| # Gaudi Framework, version v20r4
Generated: 8 Jan 2009

# proc_utils.cpp

Go to the documentation of this file.

    00001
    00007 /*
    00008  * ApMon - Application Monitoring Tool
    00009  * Version: 2.2.0
    00010  *
    00011  * Copyright (C) 2006 California Institute of Technology
    00012  *
    00013  * Permission is hereby granted, free of charge, to use, copy and modify
    00014  * this software and its documentation (the "Software") for any
    00015  * purpose, provided that existing copyright notices are retained in
    00016  * all copies and that this notice is included verbatim in any distributions
    00017  * or substantial portions of the Software.
    00018  * This software is a part of the MonALISA framework (http://monalisa.cacr.caltech.edu).
    00019  * Users of the Software are asked to feed back problems, benefits,
    00020  * and/or suggestions about the software to the MonALISA Development Team
    00021  * (developers@monalisa.cern.ch). Support for this software - fixing of bugs,
    00022  * incorporation of new features - is done on a best effort basis. All bug
    00023  * fixes and enhancements will be made available under the same terms and
    00024  * conditions as the original software,
    00025
    00026  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
    00027  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
    00028  * OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
    00029  * EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00030
    00031  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
    00032  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
    00033  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS
    00034  * PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
    00035  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
    00036  * MODIFICATIONS.
    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   //printf("### crtTime %ld lastSysInfo %ld\n", crtTime, apm.lastSysInfoSend);
    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   }
    00234
    00235   pf = fopen(psstat_f, "rt");
    00236   if (pf == NULL) {
    00237     unlink(psstat_f);
    00238     sprintf(buf, "[ getProcesses() ] The number of processes could not be determined");
    00239     throw runtime_error(buf);
    00240   }
    00241
    00242   processes = 0;
    00243   // the states table keeps an entry for each alphabet letter, for efficient
    00244   // indexing
    00245   for (int i = 0; i < NLETTERS; i++)
    00246     states[i] = 0.0;
    00247   while (fgets(buf, 10, pf) > 0) {
    00248     ch = buf[0];
    00249     states[ch - 65]++;
    00250     processes++;
    00251   }
    00252
    00253   fclose(pf);
    00254   unlink(psstat_f);
    00255 #endif
    00256 }
    00257
    00258 void ProcUtils::getSysMem(double &totalMem, double &totalSwap)
    00259   throw(procutils_error) {
    00260 #ifndef WIN32
    00261   char s1[20], line[MAX_STRING_LEN];
    00262   bool memFound = false, swapFound = false;
    00263   double valMem, valSwap;
    00264   FILE *fp1;
    00265
    00266   fp1 = fopen("/proc/meminfo", "r");
    00267   if (fp1 == NULL)
    00268     throw procutils_error((char*)"[ getSysMem() ] Could not open /proc/meminfo");
    00269
    00270   while (fgets(line, MAX_STRING_LEN, fp1)) {
    00271     if (strstr(line, "MemTotal:") == line) {
    00272       sscanf(line, "%s %lf", s1, &valMem);
    00273       memFound = true;
    00274       continue;
    00275     }
    00276
    00277     if (strstr(line, "SwapTotal:") == line) {
    00278       sscanf(line, "%s %lf", s1, &valSwap);
    00279       swapFound = true;
    00280       continue;
    00281     }
    00282
    00283   }
    00284   fclose(fp1);
    00285
    00286   if (!memFound || !swapFound)
    00287     throw procutils_error((char*)"[ getSysMem() ] Could not obtain memory info from /proc/meminfo");
    00288   totalMem = valMem;
    00289   totalSwap = valSwap;
    00290 #endif
    00291 }
    00292
    00293 void ProcUtils::getMemUsed(double &usedMem, double& freeMem,
    00294                                   double &usedSwap, double& freeSwap)
    00295   throw(procutils_error) {
    00296 #ifndef WIN32
    00297   double mFree = 0, mTotal = 0, sFree = 0, sTotal = 0;
    00298   char s1[20], line[MAX_STRING_LEN];
    00299   bool mFreeFound = false, mTotalFound = false;
    00300   bool sFreeFound = false, sTotalFound = false;
    00301   FILE *fp1;
    00302
    00303   fp1 = fopen("/proc/meminfo", "r");
    00304   if (fp1 == NULL)
    00305     throw procutils_error((char*)"[ getMemUsed() ] Could not open /proc/meminfo");
    00306
    00307   while (fgets(line, MAX_STRING_LEN, fp1)) {
    00308     if (strstr(line, "MemTotal:") == line) {
    00309       sscanf(line, "%s %lf", s1, &mTotal);
    00310       mTotalFound = true;
    00311       continue;
    00312     }
    00313
    00314     if (strstr(line, "MemFree:") == line) {
    00315       sscanf(line, "%s %lf", s1, &mFree);
    00316       mFreeFound = true;
    00317       continue;
    00318     }
    00319
    00320     if (strstr(line, "SwapTotal:") == line) {
    00321       sscanf(line, "%s %lf", s1, &sTotal);
    00322       sTotalFound = true;
    00323       continue;
    00324     }
    00325
    00326     if (strstr(line, "SwapFree:") == line) {
    00327       sscanf(line, "%s %lf", s1, &sFree);
    00328       sFreeFound = true;
    00329       continue;
    00330     }
    00331
    00332   }
    00333   fclose(fp1);
    00334
    00335   if (!mFreeFound || !mTotalFound || !sFreeFound || !sTotalFound)
    00336     throw procutils_error((char*)"[ getMemUsed() ] Could not obtain memory info from /proc/meminfo");
    00337
    00338   usedMem = (mTotal - mFree) / 1024;
    00339   freeMem = mFree / 1024;
    00340   usedSwap = (sTotal - sFree) / 1024;
    00341   freeSwap = sFree / 1024;
    00342 #endif
    00343 }
    00344
    00345 void ProcUtils::getNetworkInterfaces(int &nInterfaces,
    00346                       char names[][20]) throw(procutils_error) {
    00347 #ifndef WIN32
    00348   char line[MAX_STRING_LEN], *tmp;
    00349 //  char buf[MAX_STRING_LEN];
    00350 //  char *pbuf = buf;
    00351   FILE *fp1;
    00352
    00353   nInterfaces = 0;
    00354
    00355   fp1 = fopen("/proc/net/dev", "r");
    00356   if (fp1 == NULL)
    00357     throw procutils_error((char*)"[ getMemUsed() ] Could not open /proc/net/dev");
    00358   while (fgets(line, MAX_STRING_LEN, fp1)) {
    00359     if (strchr(line, ':') == NULL)
    00360       continue;
    00361
    00362     tmp = strtok/*_r*/(line, " :");//, &pbuf);
    00363
    00364     if (strcmp(tmp, "lo") == 0)
    00365       continue;
    00366
    00367     strcpy(names[nInterfaces], tmp);
    00368     nInterfaces++;
    00369   }
    00370
    00371   fclose(fp1);
    00372 #endif
    00373 }
    00374
    00375 void ProcUtils::getNetInfo(ApMon& apm, double **vNetIn,
    00376                                   double **vNetOut, double **vNetErrs)
    00377   throw(runtime_error, procutils_error) {
    00378 #ifndef WIN32
    00379   double *netIn, *netOut, *netErrs, bytesReceived, bytesSent;
    00380   int errs;
    00381   char line[MAX_STRING_LEN], msg[MAX_STRING_LEN];
    00382 //  char buf[MAX_STRING_LEN];
    00383 //  char *pbuf = buf;
    00384   char *tmp, *tok;
    00385   double bootTime = 0;
    00386   FILE *fp1;
    00387   time_t crtTime = time(NULL);
    00388   int ind, i;
    00389
    00390   if (apm.lastSysInfoSend == 0) {
    00391     try {
    00392       bootTime = getBootTime();
    00393     } catch (procutils_error& err) {
    00394       logger(WARNING, "[ getNetInfo() ] Error obtaining boot time. The first system monitoring datagram will contain incorrect data.");
    00395       bootTime = 0;
    00396     }
    00397   }
    00398
    00399   if (crtTime <= apm.lastSysInfoSend)
    00400     throw runtime_error("[ getNetInfo() ] Current time <= time of the previous sysInfoSend");
    00401
    00402   fp1 = fopen("/proc/net/dev", "r");
    00403   if (fp1 == NULL)
    00404     throw procutils_error((char*)"[ getNetInfo() ] Could not open /proc/net/dev");
    00405
    00406   netIn = (double *)malloc(apm.nInterfaces * sizeof(double));
    00407   netOut = (double *)malloc(apm.nInterfaces * sizeof(double));
    00408   netErrs = (double *)malloc(apm.nInterfaces * sizeof(double));
    00409
    00410   while (fgets(line, MAX_STRING_LEN, fp1)) {
    00411     if (strchr(line, ':') == NULL)
    00412       continue;
    00413     tmp = strtok/*_r*/(line, " :");//, &pbuf);
    00414
    00415     /* the loopback interface is not considered */
    00416     if (strcmp(tmp, "lo") == 0)
    00417       continue;
    00418
    00419     /* find the index of the interface in the vector */
    00420     ind = -1;
    00421     for (i = 0; i < apm.nInterfaces; i++)
    00422       if (strcmp(apm.interfaceNames[i], tmp) == 0) {
    00423         ind = i;
    00424         break;
    00425       }
    00426
    00427     if (ind < 0) {
    00428       fclose(fp1);
    00429       free(netIn); free(netOut); free(netErrs);
    00430       sprintf(msg, "[ getNetInfo() ] Could not find interface %s in /proc/net/dev",
    00431               tmp);
    00432       throw runtime_error(msg);
    00433     }
    00434
    00435     /* parse the rest of the line */
    00436     tok = strtok/*_r*/(NULL, " ");//, &pbuf);
    00437     bytesReceived = atof(tok); /* bytes received */
    00438     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* packets received */
    00439     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* input errors */
    00440     errs = atoi(tok);
    00441     /* some parameters that we are not monitoring */
    00442     for (i = 1; i <= 5; i++)
    00443       tok = strtok/*_r*/(NULL, " ");//, &pbuf);
    00444
    00445     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* bytes transmitted */
    00446     bytesSent = atof(tok);
    00447     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* packets transmitted */
    00448     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* output errors */
    00449     errs += atoi(tok);
    00450
    00451     //printf("### bytesReceived %lf lastRecv %lf\n", bytesReceived,
    00452     // apm.lastBytesReceived[ind]);
    00453     if (bytesReceived < apm.lastBytesReceived[ind] || bytesSent <
    00454         apm.lastBytesSent[ind] || errs < apm.lastNetErrs[ind]) {
    00455       apm.lastBytesReceived[ind] = bytesReceived;
    00456       apm.lastBytesSent[ind] = bytesSent;
    00457       apm.lastNetErrs[ind] = errs;
    00458       fclose(fp1);
    00459       free(netIn); free(netOut); free(netErrs);
    00460       throw runtime_error("[ getNetInfo() ] Network interface(s) restarted.");
    00461     }
    00462
    00463     if (apm.lastSysInfoSend == 0) {
    00464       netIn[ind] = bytesReceived/(crtTime - bootTime);
    00465       netOut[ind] = bytesSent/(crtTime - bootTime);
    00466       netErrs[ind] = errs;
    00467     }
    00468     else {
    00469       netIn[ind] = (bytesReceived - apm.lastBytesReceived[ind]) / (crtTime -
    00470                                                      apm.lastSysInfoSend);
    00471       netIn[ind] /= 1024; /* netIn is measured in KBps */
    00472       netOut[ind] = (bytesSent - apm.lastBytesSent[ind]) / (crtTime -
    00473                                                      apm.lastSysInfoSend);
    00474       netOut[ind] /= 1024; /* netOut is measured in KBps */
    00475       /* for network errors give the total number */
    00476       netErrs[ind] = errs; // - apm.lastNetErrs[ind];
    00477     }
    00478
    00479     apm.lastBytesReceived[ind] = bytesReceived;
    00480     apm.lastBytesSent[ind] = bytesSent;
    00481     apm.lastNetErrs[ind] = errs;
    00482   }
    00483
    00484   fclose(fp1);
    00485   *vNetIn = netIn;
    00486   *vNetOut = netOut;
    00487   *vNetErrs = netErrs;
    00488 #endif
    00489  }
    00490
    00491 int ProcUtils::getNumCPUs() throw(procutils_error) {
    00492 #ifdef WIN32
    00493         return 0;
    00494 #else
    00495   int numCPUs = 0;
    00496   char line[MAX_STRING_LEN];
    00497
    00498   FILE *fp = fopen("/proc/stat", "r");
    00499
    00500   if (fp == NULL)
    00501     throw procutils_error((char*)"[ getNumCPUs() ] Could not open /proc/stat.");
    00502
    00503   while(fgets(line, MAX_STRING_LEN, fp)) {
    00504     if (strstr(line, "cpu") == line && isdigit(line[3]))
    00505       numCPUs++;
    00506   }
    00507
    00508   fclose(fp);
    00509   return numCPUs;
    00510 #endif
    00511 }
    00512
    00513 void ProcUtils::getCPUInfo(ApMon& apm) throw(procutils_error) {
    00514 #ifndef WIN32
    00515   double freq = 0;
    00516   char line[MAX_STRING_LEN], s1[100], s2[100], s3[100];
    00517 //  char buf[MAX_STRING_LEN];
    00518 //  char *pbuf = buf;
    00519   char *tmp, *tmp_trim;
    00520   bool freqFound = false, bogomipsFound = false;
    00521
    00522   FILE *fp = fopen("/proc/cpuinfo", "r");
    00523   if (fp == NULL)
    00524     throw procutils_error((char*)"[ getCPUInfo() ] Could not open /proc/cpuinfo");
    00525
    00526   while (fgets(line, MAX_STRING_LEN, fp)) {
    00527     if (strstr(line, "cpu MHz") == line) {
    00528       sscanf(line, "%s %s %s %lf", s1, s2, s3, &freq);
    00529       apm.currentGenVals[GEN_CPU_MHZ] = freq;
    00530       freqFound = true;
    00531       continue;
    00532     }
    00533
    00534     if (strstr(line, "bogomips") == line) {
    00535       sscanf(line, "%s %s %lf", s1, s2, &(apm.currentGenVals[GEN_BOGOMIPS]));
    00536       bogomipsFound = true;
    00537       continue;
    00538     }
    00539
    00540     if (strstr(line, "vendor_id") == line) {
    00541       tmp = strtok/*_r*/(line, ":");//, &pbuf);
    00542       /* take everything that's after the ":" */
    00543       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    00544       tmp_trim = trimString(tmp);
    00545       strcpy(apm.cpuVendor, tmp_trim);
    00546       free(tmp_trim);
    00547       continue;
    00548     }
    00549
    00550     if (strstr(line, "cpu family") == line) {
    00551       tmp = strtok/*_r*/(line, ":");//, &pbuf);
    00552       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    00553       tmp_trim = trimString(tmp);
    00554       strcpy(apm.cpuFamily, tmp_trim);
    00555       free(tmp_trim);
    00556       continue;
    00557     }
    00558
    00559     if (strstr(line, "model") == line && strstr(line, "model name") != line) {
    00560       tmp = strtok/*_r*/(line, ":");//, &pbuf);
    00561       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    00562       tmp_trim = trimString(tmp);
    00563       strcpy(apm.cpuModel, tmp_trim);
    00564       free(tmp_trim);
    00565       continue;
    00566     }
    00567
    00568     if (strstr(line, "model name") == line) {
    00569       tmp = strtok/*_r*/(line, ":");//, &pbuf);
    00570       /* take everything that's after the ":" */
    00571       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    00572       tmp_trim = trimString(tmp);
    00573       strcpy(apm.cpuModelName, tmp_trim);
    00574       free(tmp_trim);
    00575       continue;
    00576     }
    00577   }
    00578
    00579   fclose(fp);
    00580   if (!freqFound || !bogomipsFound)
    00581     throw procutils_error((char*)"[ getCPUInfo() ] Could not find frequency or bogomips in /proc/cpuinfo");
    00582 #endif
    00583 }
    00584
    00588 long ProcUtils::getBootTime() throw (procutils_error) {
    00589 #ifdef WIN32
    00590         return 0;
    00591 #else
    00592   char line[MAX_STRING_LEN], s[MAX_STRING_LEN];
    00593   long btime = 0;
    00594   FILE *fp = fopen("/proc/stat", "rt");
    00595   if (fp == NULL)
    00596     throw procutils_error((char*)"[ getBootTime() ] Could not open /proc/stat");
    00597
    00598   while (fgets(line, MAX_STRING_LEN, fp)) {
    00599     if (strstr(line, "btime") == line) {
    00600       sscanf(line, "%s %ld", s, &btime);
    00601       break;
    00602     }
    00603   }
    00604   fclose(fp);
    00605   if (btime == 0)
    00606     throw procutils_error((char*)"[ getBootTime() ] Could not find boot time in /proc/stat");
    00607   return btime;
    00608 #endif
    00609 }
    00610
    00611
    00612 double ProcUtils::getUpTime() throw(procutils_error) {
    00613 #ifdef WIN32
    00614         return 0;
    00615 #else
    00616   double uptime = 0;
    00617   FILE *fp = fopen("/proc/uptime", "rt");
    00618   if (fp == NULL) {
    00619     throw procutils_error((char*)"[ getUpTime() ] Could not open /proc/uptime");
    00620   }
    00621
    00622   fscanf(fp, "%lf", &uptime);
    00623   fclose(fp);
    00624
    00625   if (uptime <= 0) {
    00626     throw procutils_error((char*)"[ getUpTime() ] Could not find uptime in /proc/uptime");
    00627   }
    00628   return uptime / (24 * 3600);
    00629 #endif
    00630 }
    00631
    00632 int ProcUtils::countOpenFiles(long pid) throw(procutils_error) {
    00633 #ifdef WIN32
    00634         return 0;
    00635 #else
    00636   char dirname[50];
    00637   char msg[MAX_STRING_LEN];
    00638   DIR *dir;
    00639   struct dirent *dir_entry;
    00640   int cnt = 0;
    00641
    00642   /* in /proc/<pid>/fd/ there is an entry for each opened file descriptor */
    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   /* count the files from /proc/<pid>/fd/ */
    00651   while ((dir_entry = readdir(dir)) != NULL) {
    00652     cnt++;
    00653   }
    00654
    00655   closedir(dir);
    00656
    00657   /* don't take into account . and .. */
    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   // the states table keeps an entry for each alphabet letter, for efficient
    00675   // indexing
    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 /*ch,*/ 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   }
    00711
    00712   pf = fopen(netstat_f, "rt");
    00713   if (pf == NULL) {
    00714     unlink(netstat_f);
    00715     sprintf(msg, "[ getNetstatInfo() ] The netstat information could not be collected");
    00716     throw runtime_error(msg);
    00717   }
    00718
    00719   while (fgets(buf, 200, pf) > 0) {
    00720     tmp = strtok_r(buf, " \t\n", &pbuf);
    00721     if (strstr(tmp, "tcp") == tmp) {
    00722       nsockets[SOCK_TCP]++;
    00723
    00724       /* go to the "State" field */
    00725       for (i = 1; i <= 5; i++)
    00726         tmp2 = strtok_r(NULL, " \t\n", &pbuf);
    00727
    00728       idx = getVectIndex(tmp2, apm.socketStatesMapTCP, N_TCP_STATES);
    00729       if (idx >= 0) {
    00730         tcp_states[idx]++;
    00731       } else {
    00732         sprintf(msg, "[ getNestatInfo() ] Invalid socket state: %s q", tmp2);
    00733         logger(WARNING, msg);
    00734       }
    00735     } else {
    00736       if (strstr(tmp, "udp") == tmp) {
    00737         nsockets[SOCK_UDP]++;
    00738       } else {
    00739         if (strstr(tmp, "unix") == tmp)
    00740           nsockets[SOCK_UNIX]++;
    00741         else if (strstr(tmp, "icm") == tmp)
    00742           nsockets[SOCK_ICM]++;
    00743       }
    00744     }
    00745   }
    00746
    00747   fclose(pf);
    00748   unlink(netstat_f);
    00749 #endif
    00750 }