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

Generated at Fri Sep 2 2011 16:24:46 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004