--- projects/cms/source/host/c++/SysMon.cpp 2001/02/26 15:00:42 1.1 +++ projects/cms/source/host/c++/SysMon.cpp 2002/05/21 16:47:11 1.10 @@ -1,3 +1,23 @@ +/* + * i-scream central monitoring system + * http://www.i-scream.org.uk + * Copyright (C) 2000-2002 i-scream + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #include "SysMon.h" SysMon::SysMon( Config config, int printDebug){ @@ -11,12 +31,9 @@ SysMon::SysMon( Config config, int printDebug){ // setup some standard variables sequence = 0; // no packets sent yet - // get our values from config - - // setup our arrays titlepointer = 0; - for ( int i=0; i < 40; i++ ){ + for ( int i=0; i < max_titles; i++ ){ titles[i] = ""; values[i] = ""; } @@ -28,72 +45,62 @@ SysMon::SysMon( Config config, int printDebug){ int SysMon::collect(){ if ( debug == 1 ){ std::cout << "SysMon::collect()\n"; - } + } // if // say we have checked again checks++; // collect the system data and place it in an array of strings. // presume that the data is all formtted correctly. - char input[2048]; + if ( debug == 1 ){ std::cout << "SysMon::collect::ipipestream\n"; } - ipipestream p("statgrab.pl"); + + p = new SubPipe("./statgrab.pl"); // get the output into input from statgrab - while ( p.getline (input, 2048) ){ - // find the first non-whitespace char in input - string sinput = input; + string sinput; + while ( p->getLine(&sinput) == 0 ){ + + if ( titlepointer == max_titles ){ + std::cout << "WARNING: Max Titles reached, skipping remaining" << endl; + std::cout << "Try recompiling with a value greater than the current (" << max_titles << ")" << endl; + titlepointer--; + break; + } // if + // locate the first white space int found = sinput.find(" ",0); if ( found == string::npos ){ // error if ( debug == 1 ){ std::cout << "SysMon::collect::Parse error from statgrab.pl\n"; - } + } // if } else { int gotTitle = 0; // now use the array of titles and values - for ( int i = 0; i < 60; i++ ){ + for ( int i = 0; i < max_titles; i++ ){ // check against the array value if ( titles[i] == sinput.substr(0,found) ){ // is the one we are looking for. - if ( debug == 1 ){ + if ( debug == 2 ){ std::cout << "SysMon::collect::Found Value\n"; - gotTitle = 1; - } + } // if debug + + gotTitle = 1; // now modify the data in the arrays if they are numbers - int * end; - char *buffer; - // buffer = sinput.substr(found+1, sinput.length()); - double dbl = 0; // strtod((char *) sinput.substr(found+1, sinput.length()), &end); - if ( dbl == 0 ){ - // error? we aren't so sure. check the position - // of end. - if ( *end == sinput.length()-1 ){ - // was the end.. ok - - } // if - } else { - // must have worked! - double dbl2 = 0; //strtod(values[i], &end); - dbl2 += dbl; - char *buffer; - int precision = 5; - int decimal, sign; - buffer = ecvt (dbl2, precision, &decimal, &sign); - } // if - } // if + } // if (titles[i]) } // for + // did we find this title? if not add it if ( gotTitle == 0 ){ // didnt if ( debug == 1 ){ - std::cout << "SysMon::collect::Adding New Value\n"; - std::cout << "'" << sinput.substr(0,found) << "'\n"; - std::cout << "'" << sinput.substr(found+1, sinput.length()) << "'\n"; - } + std::cout << "SysMon::collect::Adding New Value\n"; + std::cout << "'" << sinput.substr(0,found) << "' : "; + std::cout << "'" << sinput.substr(found+1, sinput.length()) << "'\n"; + } // if titles[titlepointer] = sinput.substr(0,found); values[titlepointer] = sinput.substr(found+1, sinput.length()); titlepointer++; @@ -103,57 +110,333 @@ int SysMon::collect(){ } // while + // delete the pointer to free up memory + delete p; + if ( debug == 1 ){ std::cout << "SysMon::collect::Parse from StatGrab finished\n"; - } + } // if - // alert? - // return 1; - // return sucessful return 0; } // collect +void SysMon::clearData(){ + + titlepointer = 0; + for ( int i=0; i < max_titles; i++ ){ + titles[i] = ""; + values[i] = ""; + } // for + + return; + +} // clearData + + string SysMon::getData(){ if ( debug == 1 ){ std::cout << "SysMon::getData()\n"; - } + } // if // create an xml object XMLFormatter xml = XMLFormatter(); + + if ( debug == 1 ){ + std::cout << "SysMon::getData::Sorting " << titlepointer << " elements\n"; + } // if + + // firstly sort the data. + // simple bubble sort + int flag = 1; + while ( flag == 1 ){ + flag = 0; + for ( int i=1; i<=titlepointer; i++ ){ + if (titles[i-1].compare(titles[i]) > 0 ){ + // swap them + string temp; + temp = titles[i-1]; + titles[i-1] = titles[i]; + titles[i] = temp; + // now do the values + temp = values[i-1]; + values[i-1] = values[i]; + values[i] = temp; + // say we have changed something + flag = 1; + } // if + } // for + } // while + + /* used to check the array has sorted correctly + for ( int i=0; i < titlepointer; i++ ){ + std::cout << titles[i] << endl; + } + */ + + // work through each one of the titles in turn and + // work out their levels. - // spammage - // xml.addElement(titles[0],values[0]); // version - xml.addNest("os"); - xml.addElement("name",values[1]); // packet.os.name - xml.addElement("release",values[2]); // packet.os.release - xml.addElement("platform",values[3]); // packet.os.platform - xml.addElement("sysname",values[4]); // packet.os.sysname - xml.addElement("version",values[5]); // packet.os.version - xml.addElement("uptime",values[9]); // packet.os.uptime - xml.closeNest(); - xml.addNest("load"); - xml.addElement("load1",values[6]); // packet.load.load1 - xml.addElement("load5",values[7]); // packet.load.load5 - xml.addElement("load15",values[8]); // packet.load.load15 - xml.closeNest(); - xml.addNest("users"); - xml.addElement("count",values[10]); // packet.users.count - // xml.addElement("list",values[11]); // packet.users.list - // xml.addElement("list",values[11]); // packet.users.list - xml.closeNest(); - - + int count = 0; + string currentLevel = "packet"; + string currentLevels[10]; + int currentLevelint = 0; + int retryCount = 0; + string attributes = ""; + int isAttrib = 0; + string attributeLevel = ""; + // init that array quickly ;) + for ( int i=0; i< 10; i++ ){ + currentLevels[i] = ""; + } // for + if ( debug == 1 ){ + std::cout << "SysMon::getData::Starting while\n"; + } // if - // xml. - - - // } // for - + while ( count <= titlepointer ){ + + if ( debug == 1 ){ + std::cout << "Processing: " << titles[count] << endl; + } // if + + retryCount++; + + currentLevel = ""; + for ( int i=0; i 0 ){ + if ( levels[level-1] != "attributes" ){ + // say it isn't an attribute, but write out + // the attribute first if the last one was + if ( attributeLevel != "" ){ + xml.addElement(attributeLevel,attributes,""); + if ( debug == 1 ){ + std::cout << "Adding Element + attributes" << endl; + } // if + + } // if + isAttrib = 0; + attributeLevel = ""; + attributes = ""; + + for ( int i=0; i < level; i++ ){ + newLevelString += levels[i]; + if ( i != level-1 ){ + newLevelString += "."; + } // if + } // for + } // if levels[level] + + else + + { + // we need to add to the attributes + level -= 2; + for ( int i=0; i < level; i++ ){ + newLevelString += levels[i]; + if ( i != level-1 ){ + newLevelString += "."; + } // if + } // for + + isAttrib = 1; + if ( attributeLevel == "" ){ + // set this attribute to be the level + attributeLevel = levels[level]; + } else { + if ( levels[level] != attributeLevel ){ + // arrg! its a different level! + if ( attributeLevel != levels[level] ){ + xml.addElement(attributeLevel,attributes,""); + if ( debug == 1 ){ + std::cout << "Adding Element + attributes1" << endl; + } // if + attributeLevel = ""; + attributes = ""; + count++; + } // if + if ( count == titlepointer ){ + xml.addElement(attributeLevel,attributes,""); + if ( debug == 1 ){ + std::cout << "Adding Element + attributes2" << endl; + } // if + attributeLevel = ""; + attributes = ""; + count++; + } // if + } // if + } // if else + + } // else attributes + } // if level > 1 + else { + if ( count == titlepointer ){ + if ( attributeLevel != "" ){ + xml.addElement(attributeLevel,attributes,""); + if ( debug == 1 ){ + std::cout << "Adding Element + attributes3" << endl; + } // if + attributeLevel = ""; + attributes = ""; + count++; + } // if + } // if + + + for ( int i=0; i < level; i++ ){ + newLevelString += levels[i]; + if ( i != level-1 ){ + newLevelString += "."; + } // if + } // for + } // if level == 1 + + // check if it is the same + if ( newLevelString == currentLevel ){ + // it is the same level, just add this as another element + if ( isAttrib ){ + attributes += levels[level+2]; + attributes += "=\""; + attributes += values[count]; + attributes += "\" "; + + } else { + xml.addElement(levels[level], values[count]); + count++; + if ( debug == 1 ){ + std::cout << "Adding Element" << endl; + } // if + } // if + + } else { + // gotta change it + + while( newLevelString.find(currentLevel) == string::npos ){ + + if ( currentLevelint <= 0 ){ + break; + } // if + + // back up atleast one level... + xml.closeNest(); + if ( debug == 1 ){ + std::cout << "Closing Nest" << endl; + } // if + // remove the last item + currentLevelint--; + + currentLevel = ""; + for ( int i=0; i 10 ){ + count++; + if ( debug == 1 ){ + std::cout << "Tried too many times" << endl; + } // if + retryCount = 0; + } // if + + } // while + + if ( debug == 1 ){ + std::cout << "\n"; + } // if + // return the string return xml.returnXML();