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
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
00044 url_ =
00045 getApplicationDescriptor()->getContextDescriptor()->getURL()+"/"+
00046 getApplicationDescriptor()->getURN();
00047 class_ =getApplicationDescriptor()->getClassName();
00048 instance_=getApplicationDescriptor()->getInstance();
00049 hostname_=getApplicationDescriptor()->getContextDescriptor()->getURL();
00050
00051
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
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
00068
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
00124 try {
00125
00126
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
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
00263
00264
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
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
00335
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
00353
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
00409
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
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
00454
00455
00456
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
00505
00506 XDAQ_INSTANTIATOR_IMPL(iDie)