| # Gaudi Framework, version v22r4 |

Home |  | Generated: Fri Sep 2 2011

# 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     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   // the states table keeps an entry for each alphabet letter, for efficient
    00245   // indexing
    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 //  char buf[MAX_STRING_LEN];
    00351 //  char *pbuf = buf;
    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/*_r*/(line, " :");//, &pbuf);
    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 //  char buf[MAX_STRING_LEN];
    00384 //  char *pbuf = buf;
    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& /*err*/) {
    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/*_r*/(line, " :");//, &pbuf);
    00415
    00416     /* the loopback interface is not considered */
    00417     if (strcmp(tmp, "lo") == 0)
    00418       continue;
    00419
    00420     /* find the index of the interface in the vector */
    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     /* parse the rest of the line */
    00437     tok = strtok/*_r*/(NULL, " ");//, &pbuf);
    00438     bytesReceived = atof(tok); /* bytes received */
    00439     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* packets received */
    00440     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* input errors */
    00441     errs = atoi(tok);
    00442     /* some parameters that we are not monitoring */
    00443     for (i = 1; i <= 5; i++)
    00444       tok = strtok/*_r*/(NULL, " ");//, &pbuf);
    00445
    00446     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* bytes transmitted */
    00447     bytesSent = atof(tok);
    00448     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* packets transmitted */
    00449     tok = strtok/*_r*/(NULL, " ");//, &pbuf); /* output errors */
    00450     errs += atoi(tok);
    00451
    00452     //printf("### bytesReceived %lf lastRecv %lf\n", bytesReceived,
    00453     // apm.lastBytesReceived[ind]);
    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; /* netIn is measured in KBps */
    00473       netOut[ind] = (bytesSent - apm.lastBytesSent[ind]) / (crtTime -
    00474                                                      apm.lastSysInfoSend);
    00475       netOut[ind] /= 1024; /* netOut is measured in KBps */
    00476       /* for network errors give the total number */
    00477       netErrs[ind] = errs; // - apm.lastNetErrs[ind];
    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 //  char buf[MAX_STRING_LEN];
    00519 //  char *pbuf = buf;
    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/*_r*/(line, ":");//, &pbuf);
    00543       /* take everything that's after the ":" */
    00544       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    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/*_r*/(line, ":");//, &pbuf);
    00553       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    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/*_r*/(line, ":");//, &pbuf);
    00562       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    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/*_r*/(line, ":");//, &pbuf);
    00571       /* take everything that's after the ":" */
    00572       tmp = strtok/*_r*/(NULL, ":");//, &pbuf);
    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   /* 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 (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     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       /* go to the "State" field */
    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 }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines