Gaudi Framework, version v20r2

Generated: 18 Jul 2008

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 }

Generated at Fri Jul 18 11:59:23 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004