CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/EventFilter/Goodies/src/iDie.cc

Go to the documentation of this file.
00001 #include "iDie.h"
00002 
00003 #include "xdaq/NamespaceURI.h"
00004 
00005 #include "xoap/SOAPEnvelope.h"
00006 #include "xoap/SOAPBody.h"
00007 #include "xoap/domutils.h"
00008 
00009 #include <boost/tokenizer.hpp>
00010 
00011 #include <netinet/in.h>
00012 #include <sstream>
00013 #include <errno.h>
00014 #include <iomanip>
00015 #include <algorithm>
00016 
00017 #include "cgicc/CgiDefs.h"
00018 #include "cgicc/Cgicc.h"
00019 #include "cgicc/FormEntry.h"
00020 #include "cgicc/FormFile.h"
00021 #include "cgicc/HTMLClasses.h"
00022 
00023 #include "EventFilter/Utilities/interface/DebugUtils.h"
00024 
00025 using namespace evf;
00026 
00027 
00029 // construction/destruction
00031 
00032 //______________________________________________________________________________
00033 iDie::iDie(xdaq::ApplicationStub *s) 
00034   : xdaq::Application(s)
00035   , log_(getApplicationLogger())
00036   , instance_(0)
00037   , runNumber_(0)
00038   , totalCores_(0)
00039   , nstates_(0)
00040   , cpustat_(std::vector<std::vector<int> >(0))
00041   , last_ls_(0)
00042 {
00043   // initialize application info
00044   url_     =
00045     getApplicationDescriptor()->getContextDescriptor()->getURL()+"/"+
00046     getApplicationDescriptor()->getURN();
00047   class_   =getApplicationDescriptor()->getClassName();
00048   instance_=getApplicationDescriptor()->getInstance();
00049   hostname_=getApplicationDescriptor()->getContextDescriptor()->getURL();
00050   
00051   //soap interface
00052   xoap::bind(this,&evf::iDie::fsmCallback,"Configure",XDAQ_NS_URI);
00053   xoap::bind(this,&evf::iDie::fsmCallback,"Enable",   XDAQ_NS_URI);
00054   xoap::bind(this,&evf::iDie::fsmCallback,"Stop",     XDAQ_NS_URI);
00055   xoap::bind(this,&evf::iDie::fsmCallback,"Halt",     XDAQ_NS_URI);
00056 
00057   // web interface
00058   xgi::bind(this,&evf::iDie::defaultWeb,  "Default");
00059   xgi::bind(this,&evf::iDie::summaryTable,"summary");
00060   xgi::bind(this,&evf::iDie::detailsTable,"details");
00061   xgi::bind(this,&evf::iDie::dumpTable,   "dump"   );
00062   xgi::bind(this,&evf::iDie::updater,     "updater");
00063   xgi::bind(this,&evf::iDie::iChoke,      "iChoke" );
00064 
00065   xgi::bind(this,&evf::iDie::postEntry,       "postEntry");
00066   xgi::bind(this,&evf::iDie::postEntryiChoke, "postChoke");
00067   //  gui_->setSmallAppIcon("/evf/images/Hilton.gif");
00068   //  gui_->setLargeAppIcon("/evf/images/Hilton.gif");
00069 
00070   xdata::InfoSpace *ispace = getApplicationInfoSpace();
00071   ispace->fireItemAvailable("parameterSet",         &configString_                );
00072   ispace->fireItemAvailable("runNumber",            &runNumber_                   );
00073   getApplicationInfoSpace()->addItemChangedListener("runNumber",              this);
00074 }
00075 
00076 
00077 //______________________________________________________________________________
00078 iDie::~iDie()
00079 {
00080 }
00081 
00082 //______________________________________________________________________________
00083 void iDie::actionPerformed(xdata::Event& e)
00084 {
00085   
00086   if (e.type()=="ItemChangedEvent" ) {
00087     std::string item = dynamic_cast<xdata::ItemChangedEvent&>(e).itemName();
00088     
00089     if ( item == "runNumber") {
00090       LOG4CPLUS_WARN(getApplicationLogger(),
00091                      "New Run was started - iDie will reset");
00092       reset();
00093     }
00094     
00095   }
00096 }
00097 
00098 //______________________________________________________________________________
00099 xoap::MessageReference iDie::fsmCallback(xoap::MessageReference msg)
00100   throw (xoap::exception::Exception)
00101 {
00102   
00103   xoap::SOAPPart     part    =msg->getSOAPPart();
00104   xoap::SOAPEnvelope env     =part.getEnvelope();
00105   xoap::SOAPBody     body    =env.getBody();
00106   DOMNode           *node    =body.getDOMNode();
00107   DOMNodeList       *bodyList=node->getChildNodes();
00108   DOMNode           *command =0;
00109   std::string             commandName;
00110   
00111   for (unsigned int i=0;i<bodyList->getLength();i++) {
00112     command = bodyList->item(i);
00113     if(command->getNodeType() == DOMNode::ELEMENT_NODE) {
00114       commandName = xoap::XMLCh2String(command->getLocalName());
00115       break;
00116     }
00117   }
00118   
00119   if (commandName.empty()) {
00120     XCEPT_RAISE(xoap::exception::Exception,"Command not found.");
00121   }
00122   
00123   // fire appropriate event and create according response message
00124   try {
00125 
00126     // response string
00127     xoap::MessageReference reply = xoap::createMessage();
00128     xoap::SOAPEnvelope envelope  = reply->getSOAPPart().getEnvelope();
00129     xoap::SOAPName responseName  = envelope.createName(commandName+"Response",
00130                                                        "xdaq",XDAQ_NS_URI);
00131     xoap::SOAPBodyElement responseElem =
00132       envelope.getBody().addBodyElement(responseName);
00133     
00134     std::string state;
00135     // generate correct return state string
00136     if(commandName == "Configure") state = "Ready";
00137     else if(commandName == "Enable") state = "Enabled";
00138     else if(commandName == "Stop") state = "Ready";
00139     else if(commandName == "Halt") state = "Halted";
00140     else state = "BOH";
00141 
00142     xoap::SOAPName    stateName     = envelope.createName("state",
00143                                                           "xdaq",XDAQ_NS_URI);
00144     xoap::SOAPElement stateElem     = responseElem.addChildElement(stateName);
00145     xoap::SOAPName    attributeName = envelope.createName("stateName",
00146                                                           "xdaq",XDAQ_NS_URI);
00147     stateElem.addAttribute(attributeName,state);
00148     
00149     return reply;
00150   }
00151   catch (toolbox::fsm::exception::Exception & e) {
00152     XCEPT_RETHROW(xoap::exception::Exception,"invalid command.",e);
00153   }     
00154   
00155 
00156 
00157 }
00158 
00159 //______________________________________________________________________________
00160 void iDie::defaultWeb(xgi::Input *in,xgi::Output *out)
00161   throw (xgi::exception::Exception)
00162 {
00163   cgicc::Cgicc cgi(in);
00164   std::string method = cgi.getEnvironment().getRequestMethod();
00165   if(method == "POST"){
00166     unsigned int run;
00167     std::vector<cgicc::FormEntry> el1 = cgi.getElements();
00168     cgi.getElement("run",el1);
00169     if(el1.size()!=0){
00170       run = el1[0].getIntegerValue();
00171       if(run > runNumber_.value_ || runNumber_.value_==0){
00172         if(runNumber_.value_!=0) reset();
00173         runNumber_.value_ = run;
00174       }
00175     }
00176     internal::fu fuinstance;
00177 
00178     fuinstance.ccount = 0;
00179     std::string hostname = cgi.getEnvironment().getRemoteHost();
00180     std::transform(hostname.begin(), hostname.end(),
00181                    hostname.begin(), ::toupper);
00182     fus_[hostname] = fuinstance;
00183   }
00184   else{
00185     *out << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">" 
00186          << "<html><head><title>" << getApplicationDescriptor()->getClassName()
00187          << getApplicationDescriptor()->getInstance() << "</title>"
00188          << "<meta http-equiv=\"REFRESH\" content=\"0;url=/evf/html/idiePage.html\">"
00189          << "</head></html>";
00190   }
00191 }
00192 
00193 //______________________________________________________________________________
00194 void iDie::updater(xgi::Input *in,xgi::Output *out)
00195   throw (xgi::exception::Exception)
00196 {
00197   *out << runNumber_.value_ << std::endl;
00198 }
00199 //______________________________________________________________________________
00200 void iDie::summaryTable(xgi::Input *in,xgi::Output *out)
00201   throw (xgi::exception::Exception)
00202 {
00203     *out << "<tr><td>"<<fus_.size()<<"</td><td>" << totalCores_ 
00204          << "</td><td></td></tr>" << std::endl;
00205 }
00206 
00207 //______________________________________________________________________________
00208 void iDie::detailsTable(xgi::Input *in,xgi::Output *out)
00209   throw (xgi::exception::Exception)
00210 {
00211   timeval tv;
00212   gettimeofday(&tv,0);
00213   time_t now = tv.tv_sec;
00214   for(ifmap i = fus_.begin(); i != fus_.end(); i++)
00215     if((*i).second.ccount != 0){
00216       *out << "<tr><td " 
00217            << (now-(*i).second.tstamp<300 ? "style=\"background-color:red\"" : "")
00218            << ">"<<(*i).first<<"</td><td>" 
00219            << (*i).second.ccount << "</td>"
00220            << "<td onClick=loaddump(\'" << url_.value_ << "/dump?name="
00221            << (*i).first << "\')>" << (*i).second.cpids.back()
00222            << "</td><td>" <<(*i).second.signals.back() 
00223            << "</td></tr>" << std::endl;
00224     }
00225 }
00226 
00227 //______________________________________________________________________________
00228 void iDie::dumpTable(xgi::Input *in,xgi::Output *out)
00229   throw (xgi::exception::Exception)
00230 {
00231   cgicc::Cgicc cgi(in); 
00232 
00233   std::vector<cgicc::FormEntry> el1;
00234   cgi.getElement("name",el1);
00235   if(el1.size()!=0){
00236     std::string hostname = el1[0].getValue();
00237     std::transform(hostname.begin(), hostname.end(),
00238                    hostname.begin(), ::toupper);
00239     ifmap fi = fus_.find(hostname);    
00240     if(fi!=fus_.end()){
00241       *out << (*fi).second.stacktraces.back() << std::endl;
00242     }
00243     else{ 
00244       for(fi=fus_.begin(); fi != fus_.end(); fi++) 
00245         std::cout << "known hosts: " << (*fi).first << std::endl;
00246     }
00247   }
00248 }
00249 
00250 //______________________________________________________________________________
00251 void iDie::iChokeMiniInterface(xgi::Input *in,xgi::Output *out)
00252   throw (xgi::exception::Exception)
00253 {
00254 }
00255 
00256 //______________________________________________________________________________
00257 void iDie::iChoke(xgi::Input *in,xgi::Output *out)
00258   throw (xgi::exception::Exception)
00259 {
00260   cgicc::Cgicc cgi(in);
00261   unsigned int i = 0;
00262 //   while(i<mapmod_.size()){
00263 //     *out << i << " " << mapmod_[i] << std::endl;
00264 //     ++i;
00265 //   }
00266   std::cout << "iChoke, last_ls= " << last_ls_ << std::endl;
00267   if(last_ls_==0) return;
00268   *out << "Last ls=" << last_ls_ << "Cpu statistics=" 
00269        << cpuentries_[last_ls_-1] << std::endl;
00270   *out << "================" << std::endl;
00271   sorted_indices tmp(cpustat_[last_ls_-1]);
00272   //  std::sort(tmp.begin(),tmp.end());// figure out how to remap indices of legenda
00273   while(i<nstates_){
00274     if(tmp[i]!=0) *out << mapmod_[tmp.ii(i)] << " " << float(tmp[i])/float(cpuentries_[last_ls_-1]) << std::endl;
00275     i++;
00276   }
00277   *out << "\n\n\n";
00278   unsigned int begin = last_ls_<10 ? 0 : last_ls_-10;
00279   for(i=begin; i < last_ls_; i++)
00280     *out << std::setw(9) << i +1 << " ";
00281   *out << std::endl;
00282   for(i=begin; i < last_ls_; i++)
00283     *out << "----------";
00284   *out << std::endl;
00285   for(i=begin; i < last_ls_; i++)
00286     *out << std::setw(8) << float(cpustat_[i][2])/float(cpuentries_[i]) << " ";
00287   *out << std::endl;
00288   *out << "\n\n\n";
00289   begin = last_ls_<10 ? 0 : last_ls_-10;
00290   for(i=begin; i < last_ls_; i++)
00291     *out << std::setw(9) << i +1 << " ";
00292   *out << std::endl;
00293   for(i=begin; i < last_ls_; i++)
00294     *out << "----------";
00295   *out << std::endl;
00296   for(i=begin; i < last_ls_; i++)
00297     *out << std::setw(8) << float(trp_[i].eventSummary.totalEventsPassed)/float(trp_[i].eventSummary.totalEvents) << " "; 
00298   *out << std::endl;
00299   for(i=begin; i < last_ls_; i++)
00300     *out << std::setw(8) << trp_[i].eventSummary.totalEvents << " "; 
00301   *out << std::endl;
00302 
00303   for(int j = 0; j < trp_[last_ls_-1].trigPathsInMenu; j++)
00304     {
00305       for(i=begin; i < last_ls_; i++)
00306         *out << std::setw(8) << trp_[i].trigPathSummaries[j].timesPassed << "("
00307              << trp_[i].trigPathSummaries[j].timesPassedL1 << ")("
00308              << trp_[i].trigPathSummaries[j].timesPassedPs << ") ";
00309       *out << mappath_[j];
00310       *out << std::endl;
00311     }
00312   for(int j = 0; j < trp_[last_ls_-1].endPathsInMenu; j++)
00313     {
00314       for(i=begin; i < last_ls_; i++)
00315         *out << std::setw(8) << trp_[i].endPathSummaries[j].timesPassed << " ";
00316       *out << mappath_[j+trp_[last_ls_-1].trigPathsInMenu];
00317       *out << std::endl;
00318     }
00319 
00320 
00321 }
00322 
00323 //______________________________________________________________________________
00324 void iDie::postEntry(xgi::Input*in,xgi::Output*out)
00325   throw (xgi::exception::Exception)
00326 {
00327   std::cout << "postEntry " << std::endl;
00328   timeval tv;
00329   gettimeofday(&tv,0);
00330   time_t now = tv.tv_sec;
00331   cgicc::Cgicc cgi(in); 
00332   unsigned int run = 0;
00333   pid_t cpid = 0;
00334   /*  cgicc::CgiEnvironment cgie(in);
00335   cout << "query = "  << cgie.getContentLength() << endl;
00336   */
00337   std::vector<cgicc::FormEntry> el1;
00338   el1 = cgi.getElements();
00339   for(unsigned int i = 0; i < el1.size(); i++)
00340     std::cout << "name="<<el1[i].getName() << std::endl;
00341   el1.clear();
00342   cgi.getElement("run",el1);
00343   if(el1.size()!=0)
00344     {
00345       run =  el1[0].getIntegerValue();
00346     }
00347   el1.clear();
00348   cgi.getElement("stacktrace",el1);
00349   if(el1.size()!=0)
00350     {
00351       cpid = run;
00352       //      std::cout << "=============== stacktrace =============" << std::endl;
00353       //      std::cout << el1[0].getValue() << std::endl;
00354       if(el1[0].getValue().find("Dead")==0){
00355 
00356         std::string host = cgi.getEnvironment().getRemoteHost();
00357         std::transform(host.begin(), host.end(),
00358                        host.begin(), ::toupper);
00359         ifmap fi = fus_.find(host);
00360         if(fi!=fus_.end()){
00361           fus_.erase(fi);
00362         }
00363       }
00364       else{
00365         totalCores_++;
00366         std::string st = el1[0].getValue();
00367         std::string sig; 
00368         size_t psig = st.find("signal");
00369         if(psig != std::string::npos)
00370           sig = st.substr(psig,9);
00371         std::string host = cgi.getEnvironment().getRemoteHost();
00372         std::transform(host.begin(), host.end(),
00373                        host.begin(), ::toupper);
00374         ifmap fi = fus_.find(host);
00375         if(fi!=fus_.end()){
00376           (*fi).second.tstamp = now;
00377           (*fi).second.ccount++;
00378           (*fi).second.cpids.push_back(cpid);
00379           (*fi).second.signals.push_back(sig);
00380           (*fi).second.stacktraces.push_back(st);
00381         }
00382       }
00383     }
00384   el1.clear();
00385   cgi.getElement("legenda",el1);
00386   if(el1.size()!=0)
00387     {
00388       parsePathLegenda(el1[0].getValue());
00389     }
00390   cgi.getElement("trp",el1);
00391   if(el1.size()!=0)
00392     {
00393       unsigned int lsid = run;
00394       parsePathHisto((unsigned char*)(el1[0].getValue().c_str()),lsid);
00395     }
00396   el1.clear();
00397 
00398 
00399 }
00400 
00401 //______________________________________________________________________________
00402 void iDie::postEntryiChoke(xgi::Input*in,xgi::Output*out)
00403   throw (xgi::exception::Exception)
00404 {
00405   std::cout << "postEntryiChoke " << std::endl;
00406   unsigned int lsid = 0;
00407   cgicc::Cgicc cgi(in); 
00408   /*  cgicc::CgiEnvironment cgie(in);
00409   cout << "query = "  << cgie.getContentLength() << endl;
00410   */
00411   std::vector<cgicc::FormEntry> el1;
00412   el1 = cgi.getElements();
00413   for(unsigned int i = 0; i < el1.size(); i++)
00414     std::cout << "name="<<el1[i].getName() << std::endl;
00415   el1.clear();
00416   cgi.getElement("run",el1);
00417   if(el1.size()!=0)
00418     {
00419       lsid =  el1[0].getIntegerValue();
00420     }
00421   el1.clear();
00422   cgi.getElement("legenda",el1);
00423   if(el1.size()!=0)
00424     {
00425       parseModuleLegenda(el1[0].getValue());
00426     }
00427   cgi.getElement("trp",el1);
00428   if(el1.size()!=0)
00429     {
00430       parseModuleHisto(el1[0].getStrippedValue().c_str(),lsid);
00431     }
00432   el1.clear();
00433 }
00434 
00435 
00436 void iDie::reset()
00437 {
00438   fus_.erase(fus_.begin(),fus_.end());
00439   totalCores_=0;
00440 }
00441 
00442 void iDie::parseModuleLegenda(std::string leg)
00443 {
00444   mapmod_.clear();
00445   //  if(cpustat_) delete cpustat_;
00446   boost::char_separator<char> sep(",");
00447   boost::tokenizer<boost::char_separator<char> > tokens(leg, sep);
00448   for (boost::tokenizer<boost::char_separator<char> >::iterator tok_iter = tokens.begin();
00449        tok_iter != tokens.end(); ++tok_iter){
00450     mapmod_.push_back((*tok_iter));
00451   }
00452   nstates_ = mapmod_.size();
00453   //  cpustat_ = new int[nstates_];
00454 //   for(int i = 0; i < nstates_; i++)
00455 //     cpustat_[i]=0;   
00456 //   cpuentries_ = 0;
00457 }
00458 
00459 void iDie::parseModuleHisto(const char *crp, unsigned int lsid)
00460 {
00461   std::cout << "parseModuleHisto ls=" << lsid << std::endl; 
00462   if(last_ls_ < lsid) last_ls_ = lsid; 
00463   int *trp = (int*)crp;
00464   if(lsid>=cpustat_.size()){
00465     cpustat_.resize(lsid,std::vector<int>(nstates_,0));
00466     cpuentries_.resize(lsid,0);
00467   }
00468   for(unsigned int i=0;i<nstates_; i++)
00469     {
00470       cpustat_[lsid-1][i] += trp[i];
00471       cpuentries_[lsid-1] += trp[i];
00472     }
00473 }
00474 
00475 
00476 void iDie::parsePathLegenda(std::string leg)
00477 {
00478   std::cout << "parsePathLegenda" << std::endl;
00479   std::cout << leg << std::endl;
00480   mappath_.clear();
00481   boost::char_separator<char> sep(",");
00482   boost::tokenizer<boost::char_separator<char> > tokens(leg, sep);
00483   for (boost::tokenizer<boost::char_separator<char> >::iterator tok_iter = tokens.begin();
00484        tok_iter != tokens.end(); ++tok_iter){
00485     mappath_.push_back((*tok_iter));
00486   }
00487 }
00488 
00489 void iDie::parsePathHisto(const unsigned char *crp, unsigned int lsid)
00490 {
00491   std::cout << "parsePathHisto ls=" << lsid << std::endl; 
00492   TriggerReportStatic *trp = (TriggerReportStatic*)crp;
00493   if(lsid>=trp_.size()){
00494     trp_.resize(lsid);
00495     funcs::reset(&trp_[lsid-1]);
00496     trpentries_.resize(lsid,0);
00497   }
00498   funcs::addToReport(&trp_[lsid-1],trp,lsid);
00499   trpentries_[lsid-1]++;
00500 }
00501 
00503 // xdaq instantiator implementation macro
00505 
00506 XDAQ_INSTANTIATOR_IMPL(iDie)