CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/EventFilter/SMProxyServer/src/SMPSWebPageHelper.cc

Go to the documentation of this file.
00001 // $Id: SMPSWebPageHelper.cc,v 1.1.4.2 2011/03/07 12:01:12 mommsen Exp $
00003 
00004 #include "EventFilter/SMProxyServer/interface/SMPSWebPageHelper.h"
00005 #include "EventFilter/StorageManager/interface/RegistrationCollection.h"
00006 #include "EventFilter/StorageManager/interface/Utils.h"
00007 #include "EventFilter/StorageManager/interface/XHTMLMonitor.h"
00008 #include "EventFilter/StorageManager/src/ConsumerWebPageHelper.icc"
00009 
00010 #include <boost/pointer_cast.hpp>
00011 
00012 
00013 namespace smproxy
00014 {
00015   SMPSWebPageHelper::SMPSWebPageHelper
00016   (
00017     xdaq::ApplicationDescriptor* appDesc,
00018     StateMachinePtr stateMachine
00019   ) :
00020   stor::WebPageHelper<SMPSWebPageHelper>(appDesc, "$Name: V02-01-00 $", this, &smproxy::SMPSWebPageHelper::addDOMforHyperLinks),
00021   stateMachine_(stateMachine),
00022   consumerWebPageHelper_(appDesc, "$Name: V02-01-00 $", this, &smproxy::SMPSWebPageHelper::addDOMforHyperLinks)
00023   { }
00024   
00025   
00026   void SMPSWebPageHelper::defaultWebPage(xgi::Output* out) const
00027   {
00028     stor::XHTMLMonitor theMonitor;
00029     stor::XHTMLMaker maker;
00030 
00031     stor::XHTMLMaker::Node* body = createWebPageBody(maker,
00032       "Main",
00033       stateMachine_->getExternallyVisibleStateName(),
00034       stateMachine_->getStateName(),
00035       stateMachine_->getReasonForFailed()
00036     );
00037 
00038     DataRetrieverMonitorCollection::SummaryStats summaryStats;
00039     stateMachine_->getStatisticsReporter()->
00040       getDataRetrieverMonitorCollection().getSummaryStats(summaryStats);
00041 
00042     addDOMforConnectionInfo(maker, body, summaryStats);
00043 
00044     maker.addNode("br", body);
00045 
00046     addDOMforThroughputPerEventType(maker, body, summaryStats);
00047     
00048     addDOMforHyperLinks(maker, body);
00049     
00050     // Dump the webpage to the output stream
00051     maker.out(*out);
00052   }
00053   
00054   
00055   void SMPSWebPageHelper::dataRetrieverWebPage(xgi::Output* out) const
00056   {
00057     stor::XHTMLMonitor theMonitor;
00058     stor::XHTMLMaker maker;
00059 
00060     stor::XHTMLMaker::Node* body = createWebPageBody(maker,
00061       "Data Retrieval",
00062       stateMachine_->getExternallyVisibleStateName(),
00063       stateMachine_->getStateName(),
00064       stateMachine_->getReasonForFailed()
00065     );
00066 
00067     addDOMforEventServers(maker, body);
00068     
00069     maker.addNode("hr", body);
00070     
00071     addDOMforDQMEventServers(maker, body);
00072     
00073     addDOMforHyperLinks(maker, body);
00074     
00075     // Dump the webpage to the output stream
00076     maker.out(*out);    
00077   } 
00078   
00079   
00080   void SMPSWebPageHelper::consumerStatisticsWebPage(xgi::Output* out) const
00081   {
00082     consumerWebPageHelper_.consumerStatistics(out,
00083       stateMachine_->getExternallyVisibleStateName(),
00084       stateMachine_->getStateName(),
00085       stateMachine_->getReasonForFailed(),
00086       stateMachine_->getStatisticsReporter(),
00087       stateMachine_->getRegistrationCollection(),
00088       stateMachine_->getEventQueueCollection(),
00089       stateMachine_->getDQMEventQueueCollection()
00090     );
00091   }
00092   
00093   
00094   void SMPSWebPageHelper::dqmEventStatisticsWebPage(xgi::Output* out) const
00095   {
00096     stor::XHTMLMonitor theMonitor;
00097     stor::XHTMLMaker maker;
00098 
00099     stor::XHTMLMaker::Node* body = createWebPageBody(maker,
00100       "DQM Event Processor",
00101       stateMachine_->getExternallyVisibleStateName(),
00102       stateMachine_->getStateName(),
00103       stateMachine_->getReasonForFailed()
00104     );
00105     
00106     const stor::DQMEventMonitorCollection& demc =
00107       stateMachine_->getStatisticsReporter()->getDQMEventMonitorCollection();
00108     addDOMforProcessedDQMEvents(maker, body, demc);
00109     addDOMforDQMEventStatistics(maker, body, demc);
00110 
00111     addDOMforHyperLinks(maker, body);
00112     
00113     // Dump the webpage to the output stream
00114     maker.out(*out);    
00115   } 
00116   
00117   
00118   void SMPSWebPageHelper::addDOMforHyperLinks
00119   (
00120     stor::XHTMLMaker& maker,
00121     stor::XHTMLMaker::Node *parent
00122   ) const
00123   {
00124     std::string url = appDescriptor_->getContextDescriptor()->getURL()
00125       + "/" + appDescriptor_->getURN();
00126     
00127     stor::XHTMLMaker::AttrMap linkAttr;
00128     stor::XHTMLMaker::Node *link;
00129     
00130     maker.addNode("hr", parent);
00131     
00132     linkAttr[ "href" ] = url;
00133     link = maker.addNode("a", parent, linkAttr);
00134     maker.addText(link, "Main web page");
00135     
00136     maker.addNode("hr", parent);
00137     
00138     linkAttr[ "href" ] = url + "/dataRetriever";
00139     link = maker.addNode("a", parent, linkAttr);
00140     maker.addText(link, "Data retriever web page");
00141     
00142     maker.addNode("hr", parent);
00143     
00144     linkAttr[ "href" ] = url + "/dqmEventStatistics";
00145     link = maker.addNode("a", parent, linkAttr);
00146     maker.addText(link, "DQM event processor statistics");
00147     
00148     maker.addNode("hr", parent);
00149     
00150     linkAttr[ "href" ] = url + "/consumerStatistics";
00151     link = maker.addNode("a", parent, linkAttr);
00152     maker.addText(link, "Consumer Statistics");
00153     
00154     maker.addNode("hr", parent);
00155   }
00156   
00157   
00158   void SMPSWebPageHelper::addDOMforConnectionInfo
00159   (
00160     stor::XHTMLMaker& maker,
00161     stor::XHTMLMaker::Node* parent,
00162     const DataRetrieverMonitorCollection::SummaryStats& summaryStats
00163   ) const
00164   {
00165     stor::XHTMLMaker::AttrMap colspanAttr;
00166     colspanAttr[ "colspan" ] = "2";
00167 
00168     stor::XHTMLMaker::AttrMap tableAttr = tableAttr_;
00169     tableAttr[ "width" ] = "50%";
00170 
00171     stor::XHTMLMaker::AttrMap widthAttr;
00172     widthAttr[ "width" ] = "70%";
00173  
00174     stor::XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr);
00175     
00176     stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00177     stor::XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00178     maker.addText(tableDiv, "Connection Information");
00179 
00180     // # of configured SMs
00181     tableRow = maker.addNode("tr", table, rowAttr_);
00182     tableDiv = maker.addNode("td", tableRow, widthAttr);
00183     maker.addText(tableDiv, "# of configured StorageManagers");
00184     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00185     const size_t configuredSMs = stateMachine_->getConfiguration()->
00186       getDataRetrieverParams().smRegistrationList_.size();
00187     maker.addInt(tableDiv, configuredSMs);
00188 
00189     // # of requested SMs connections
00190     tableRow = maker.addNode("tr", table, rowAttr_);
00191     tableDiv = maker.addNode("td", tableRow, widthAttr);
00192     maker.addText(tableDiv, "# of requested SM connections");
00193     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00194     maker.addInt(tableDiv, summaryStats.registeredSMs);
00195 
00196     // # of active SMs connections
00197     tableRow = maker.addNode("tr", table, rowAttr_);
00198     tableDiv = maker.addNode("td", tableRow, widthAttr);
00199     maker.addText(tableDiv, "# of active SM connections");
00200     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00201     maker.addInt(tableDiv, summaryStats.activeSMs);
00202 
00203     // # of connected event consumers
00204     tableRow = maker.addNode("tr", table, rowAttr_);
00205     tableDiv = maker.addNode("td", tableRow, widthAttr);
00206     maker.addText(tableDiv, "# of connected event consumers");
00207     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00208     stor::RegistrationCollection::ConsumerRegistrations consumers;
00209     stateMachine_->getRegistrationCollection()->
00210       getEventConsumers(consumers);
00211     maker.addInt(tableDiv, consumers.size());
00212 
00213     // # of connected DQM event (histogram) consumers
00214     tableRow = maker.addNode("tr", table, rowAttr_);
00215     tableDiv = maker.addNode("td", tableRow, widthAttr);
00216     maker.addText(tableDiv, "# of connected histogram consumers");
00217     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00218     stor::RegistrationCollection::DQMConsumerRegistrations dqmConsumers;
00219     stateMachine_->getRegistrationCollection()->
00220       getDQMEventConsumers(dqmConsumers);
00221     maker.addInt(tableDiv, dqmConsumers.size());
00222   }
00223   
00224   
00225   void SMPSWebPageHelper::addDOMforThroughputPerEventType
00226   (
00227     stor::XHTMLMaker& maker,
00228     stor::XHTMLMaker::Node* parent,
00229     const DataRetrieverMonitorCollection::SummaryStats& summaryStats
00230   ) const
00231   {
00232     stor::XHTMLMaker::AttrMap colspanAttr;
00233     colspanAttr[ "colspan" ] = "11";
00234     
00235     stor::XHTMLMaker::AttrMap subColspanAttr;
00236     
00237     stor::XHTMLMaker::AttrMap rowspanAttr;
00238     rowspanAttr[ "rowspan" ] = "3";
00239     rowspanAttr[ "width" ] = "30%";
00240 
00241     stor::XHTMLMaker::AttrMap noWrapAttr; 
00242     noWrapAttr[ "style" ] = "white-space: nowrap;";
00243 
00244     stor::XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00245     stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00246     stor::XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00247     maker.addText(tableDiv, "Throughput");
00248     
00249     tableRow = maker.addNode("tr", table, rowAttr_);
00250     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00251     maker.addText(tableDiv, "Requested Event Type");
00252     subColspanAttr[ "colspan" ] = "2";
00253     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00254     maker.addText(tableDiv, "");
00255     subColspanAttr[ "colspan" ] = "4";
00256     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00257     maker.addText(tableDiv, "Input");
00258     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00259     maker.addText(tableDiv, "Output");
00260 
00261     subColspanAttr[ "colspan" ] = "2";
00262     tableRow = maker.addNode("tr", table, rowAttr_);
00263     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00264     maker.addText(tableDiv, "Average Event Size (kB)");
00265     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00266     maker.addText(tableDiv, "Event Rate (Hz)");
00267     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00268     maker.addText(tableDiv, "Bandwidth (kB/s)");
00269     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00270     maker.addText(tableDiv, "Event Rate (Hz)");
00271     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00272     maker.addText(tableDiv, "Bandwidth (kB/s)");
00273 
00274     tableRow = maker.addNode("tr", table, rowAttr_);
00275     tableDiv = maker.addNode("th", tableRow);
00276     maker.addText(tableDiv, "overall");
00277     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00278     maker.addText(tableDiv, "last 60 s");
00279     tableDiv = maker.addNode("th", tableRow);
00280     maker.addText(tableDiv, "overall");
00281     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00282     maker.addText(tableDiv, "last 60 s");
00283     tableDiv = maker.addNode("th", tableRow);
00284     maker.addText(tableDiv, "overall");
00285     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00286     maker.addText(tableDiv, "last 60 s");
00287     tableDiv = maker.addNode("th", tableRow);
00288     maker.addText(tableDiv, "overall");
00289     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00290     maker.addText(tableDiv, "last 60 s");
00291     tableDiv = maker.addNode("th", tableRow);
00292     maker.addText(tableDiv, "overall");
00293     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00294     maker.addText(tableDiv, "last 60 s");
00295 
00296     if ( summaryStats.eventTypeStats.empty() )
00297     {
00298       stor::XHTMLMaker::AttrMap messageAttr = colspanAttr;
00299       messageAttr[ "align" ] = "center";
00300       
00301       stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00302       stor::XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow, messageAttr);
00303       maker.addText(tableDiv, "No data flowing, yet.");
00304       return;
00305     }
00306     
00307     bool evenRow = false;
00308     
00309     for (DataRetrieverMonitorCollection::SummaryStats::EventTypeStatList::const_iterator
00310            it = summaryStats.eventTypeStats.begin(), itEnd = summaryStats.eventTypeStats.end();
00311          it != itEnd; ++it)
00312     {
00313       stor::XHTMLMaker::AttrMap rowAttr = rowAttr_;
00314       if( evenRow )
00315       {
00316         rowAttr[ "style" ] = "background-color:#e0e0e0;";
00317         evenRow = false;
00318       }
00319        else
00320       {
00321         evenRow = true;
00322       }
00323       stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr);
00324       addRowForEventType(maker, tableRow, *it);
00325     }
00326 
00327     addSummaryRowForThroughput(maker, table, summaryStats);
00328   }
00329   
00330   
00331   void SMPSWebPageHelper::addRowForEventType
00332   (
00333     stor::XHTMLMaker& maker,
00334     stor::XHTMLMaker::Node* tableRow,
00335     DataRetrieverMonitorCollection::SummaryStats::EventTypeStats const& stats
00336   ) const
00337   {
00338     // Event type
00339     stor::XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00340     stor::XHTMLMaker::Node* pre = maker.addNode("pre", tableDiv);
00341     std::ostringstream eventType;
00342     stats.first->eventType(eventType);
00343     maker.addText(pre, eventType.str());
00344     
00345     // Average event size
00346     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00347     maker.addDouble(tableDiv, stats.second.getValueAverage(stor::MonitoredQuantity::FULL));
00348     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00349     maker.addDouble(tableDiv, stats.second.getValueAverage(stor::MonitoredQuantity::RECENT));
00350 
00351     // Input event rate
00352     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00353     maker.addDouble(tableDiv, stats.second.getSampleRate(stor::MonitoredQuantity::FULL));
00354     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00355     maker.addDouble(tableDiv, stats.second.getSampleRate(stor::MonitoredQuantity::RECENT));
00356 
00357     // Input bandwidth
00358     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00359     maker.addDouble(tableDiv, stats.second.getValueRate(stor::MonitoredQuantity::FULL));
00360     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00361     maker.addDouble(tableDiv, stats.second.getValueRate(stor::MonitoredQuantity::RECENT));
00362 
00363     // Get statistics for consumers requesting this event type
00364     stor::QueueIDs queueIDs;
00365     bool isEventConsumer =
00366       stateMachine_->getDataManager()->getQueueIDsFromDataEventRetrievers(
00367         boost::dynamic_pointer_cast<stor::EventConsumerRegistrationInfo>(stats.first),
00368         queueIDs
00369       );
00370     if ( ! isEventConsumer)
00371     {
00372       stateMachine_->getDataManager()->getQueueIDsFromDQMEventRetrievers(
00373         boost::dynamic_pointer_cast<stor::DQMEventConsumerRegistrationInfo>(stats.first),
00374         queueIDs
00375       );
00376     }
00377 
00378     if ( queueIDs.empty() )
00379     {
00380       stor::XHTMLMaker::AttrMap noConsumersAttr = tableLabelAttr_;
00381       noConsumersAttr[ "colspan" ] = "4";
00382       tableDiv = maker.addNode("td", tableRow, noConsumersAttr);
00383       maker.addText(tableDiv, "no consumers connected");
00384       return;
00385     }
00386     
00387     const stor::EventConsumerMonitorCollection& ecmc =
00388       stateMachine_->getStatisticsReporter()->getEventConsumerMonitorCollection();
00389     const stor::DQMConsumerMonitorCollection& dcmc =
00390       stateMachine_->getStatisticsReporter()->getDQMConsumerMonitorCollection();
00391     const stor::ConsumerMonitorCollection& cmc =
00392       isEventConsumer ?
00393       static_cast<const stor::ConsumerMonitorCollection&>(ecmc) :
00394       static_cast<const stor::ConsumerMonitorCollection&>(dcmc);
00395     
00396     double rateOverall = 0;
00397     double rateRecent = 0;
00398     double bandwidthOverall = 0;
00399     double bandwidthRecent = 0;
00400 
00401     for ( stor::QueueIDs::const_iterator it = queueIDs.begin(),
00402             itEnd = queueIDs.end(); it != itEnd; ++it)
00403     {
00404       stor::MonitoredQuantity::Stats result;
00405       if ( cmc.getServed(*it, result) )
00406       {
00407         rateOverall += result.getSampleRate(stor::MonitoredQuantity::FULL);
00408         rateRecent += result.getSampleRate(stor::MonitoredQuantity::RECENT);
00409         bandwidthOverall += result.getValueRate(stor::MonitoredQuantity::FULL) / 1024;
00410         bandwidthRecent += result.getValueRate(stor::MonitoredQuantity::RECENT) / 1024;
00411       }
00412     }
00413 
00414     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00415     maker.addDouble(tableDiv, rateOverall);
00416     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00417     maker.addDouble(tableDiv, rateRecent);
00418     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00419     maker.addDouble(tableDiv, bandwidthOverall);
00420     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00421     maker.addDouble(tableDiv, bandwidthRecent);
00422   }
00423   
00424   
00425   void SMPSWebPageHelper::addSummaryRowForThroughput
00426   (
00427     stor::XHTMLMaker& maker,
00428     stor::XHTMLMaker::Node* table,
00429     const DataRetrieverMonitorCollection::SummaryStats& summaryStats
00430   ) const
00431   {
00432     stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, specialRowAttr_);
00433     stor::XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00434     maker.addText(tableDiv, "Total");
00435 
00436     // Average event size
00437     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00438     maker.addDouble(tableDiv, summaryStats.sizeStats.getValueAverage(stor::MonitoredQuantity::FULL));
00439     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00440     maker.addDouble(tableDiv, summaryStats.sizeStats.getValueAverage(stor::MonitoredQuantity::RECENT));
00441 
00442     // Input event rate
00443     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00444     maker.addDouble(tableDiv, summaryStats.sizeStats.getSampleRate(stor::MonitoredQuantity::FULL));
00445     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00446     maker.addDouble(tableDiv, summaryStats.sizeStats.getSampleRate(stor::MonitoredQuantity::RECENT));
00447 
00448     // Input bandwidth
00449     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00450     maker.addDouble(tableDiv, summaryStats.sizeStats.getValueRate(stor::MonitoredQuantity::FULL));
00451     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00452     maker.addDouble(tableDiv, summaryStats.sizeStats.getValueRate(stor::MonitoredQuantity::RECENT));
00453     
00454     const stor::EventConsumerMonitorCollection& ecmc =
00455       stateMachine_->getStatisticsReporter()->getEventConsumerMonitorCollection();
00456     const stor::DQMConsumerMonitorCollection& dcmc =
00457       stateMachine_->getStatisticsReporter()->getDQMConsumerMonitorCollection();
00458     stor::ConsumerMonitorCollection::TotalStats ecmcStats, dcmcStats;
00459     ecmc.getTotalStats(ecmcStats);
00460     dcmc.getTotalStats(dcmcStats);
00461 
00462     // Output event rate
00463     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00464     maker.addDouble(tableDiv,
00465       ecmcStats.servedStats.getSampleRate(stor::MonitoredQuantity::FULL) +
00466       dcmcStats.servedStats.getSampleRate(stor::MonitoredQuantity::FULL)
00467     );
00468     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00469     maker.addDouble(tableDiv,
00470       ecmcStats.servedStats.getSampleRate(stor::MonitoredQuantity::RECENT) +
00471       dcmcStats.servedStats.getSampleRate(stor::MonitoredQuantity::RECENT)
00472     );
00473     
00474     // Output bandwidth
00475     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00476     maker.addDouble(tableDiv,
00477       (ecmcStats.servedStats.getValueRate(stor::MonitoredQuantity::FULL) +
00478         dcmcStats.servedStats.getValueRate(stor::MonitoredQuantity::FULL)) / 1024
00479     );
00480     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00481     maker.addDouble(tableDiv,
00482       (ecmcStats.servedStats.getValueRate(stor::MonitoredQuantity::RECENT) +
00483         dcmcStats.servedStats.getValueRate(stor::MonitoredQuantity::RECENT)) / 1024
00484     );
00485   }
00486   
00487   
00488   void SMPSWebPageHelper::addDOMforEventServers
00489   (
00490     stor::XHTMLMaker& maker,
00491     stor::XHTMLMaker::Node* parent
00492   ) const
00493   {
00494     stor::XHTMLMaker::AttrMap colspanAttr;
00495     colspanAttr[ "colspan" ] = "10";
00496     
00497     stor::XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00498     
00499     stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00500     stor::XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00501     maker.addText(tableDiv, "Event Servers");
00502     
00503     stor::XHTMLMaker::AttrMap rowspanAttr;
00504     rowspanAttr[ "rowspan" ] = "2";
00505     
00506     stor::XHTMLMaker::AttrMap subColspanAttr;
00507     subColspanAttr[ "colspan" ] = "2";
00508 
00509     stor::XHTMLMaker::AttrMap noWrapAttr; 
00510     noWrapAttr[ "style" ] = "white-space: nowrap;";
00511    
00512     // Header
00513     tableRow = maker.addNode("tr", table, specialRowAttr_);
00514     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00515     maker.addText(tableDiv, "Hostname");
00516     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00517     maker.addText(tableDiv, "Status");
00518     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00519     maker.addText(tableDiv, "Requested Event Type");
00520     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00521     maker.addText(tableDiv, "Max Request Rate (Hz)");
00522     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00523     maker.addText(tableDiv, "Event Rate (Hz)");
00524     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00525     maker.addText(tableDiv, "Average Event Size (kB)");
00526     tableDiv = maker.addNode("th", tableRow, subColspanAttr);
00527     maker.addText(tableDiv, "Bandwidth (kB/s)");
00528 
00529     tableRow = maker.addNode("tr", table, specialRowAttr_);
00530     tableDiv = maker.addNode("th", tableRow);
00531     maker.addText(tableDiv, "overall");
00532     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00533     maker.addText(tableDiv, "last 60 s");
00534     tableDiv = maker.addNode("th", tableRow);
00535     maker.addText(tableDiv, "overall");
00536     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00537     maker.addText(tableDiv, "last 60 s");
00538     tableDiv = maker.addNode("th", tableRow);
00539     maker.addText(tableDiv, "overall");
00540     tableDiv = maker.addNode("th", tableRow, noWrapAttr);
00541     maker.addText(tableDiv, "last 60 s");
00542 
00543     DataRetrieverMonitorCollection::EventTypeStatList eventTypeStats;
00544     stateMachine_->getStatisticsReporter()->getDataRetrieverMonitorCollection()
00545       .getStatsByEventTypes(eventTypeStats);
00546 
00547     DataRetrieverMonitorCollection::ConnectionStats connectionStats;
00548     stateMachine_->getStatisticsReporter()->getDataRetrieverMonitorCollection()
00549       .getStatsByConnection(connectionStats);
00550 
00551     if ( eventTypeStats.empty() )
00552     {
00553       stor::XHTMLMaker::AttrMap messageAttr = colspanAttr;
00554       messageAttr[ "align" ] = "center";
00555 
00556       tableRow = maker.addNode("tr", table, rowAttr_);
00557       tableDiv = maker.addNode("td", tableRow, messageAttr);
00558       maker.addText(tableDiv, "Not registered to any event servers yet");
00559       return;
00560     }
00561 
00562     bool evenRow = false;
00563 
00564     for (DataRetrieverMonitorCollection::EventTypeStatList::const_iterator
00565            it = eventTypeStats.begin(), itEnd = eventTypeStats.end();
00566          it != itEnd; ++it)
00567     {
00568       stor::XHTMLMaker::AttrMap rowAttr = rowAttr_;
00569       if( evenRow )
00570       {
00571         rowAttr[ "style" ] = "background-color:#e0e0e0;";
00572         evenRow = false;
00573       }
00574       else
00575       {
00576         evenRow = true;
00577       }
00578       stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr);
00579       addRowForEventServer(maker, tableRow, *it);
00580       
00581       const std::string currentSourceURL = it->regPtr->sourceURL();
00582 
00583       if ( (it+1) == eventTypeStats.end() ||
00584         (it+1)->regPtr->sourceURL() != currentSourceURL )
00585       {
00586         addSummaryRowForEventServer(maker, table,
00587           connectionStats.find(currentSourceURL));
00588       }
00589     }
00590   }
00591   
00592   
00593   void SMPSWebPageHelper::addRowForEventServer
00594   (
00595     stor::XHTMLMaker& maker,
00596     stor::XHTMLMaker::Node* tableRow,
00597     DataRetrieverMonitorCollection::EventTypeStats const& stats
00598   ) const
00599   {
00600     stor::XHTMLMaker::Node* tableDiv;
00601 
00602     // Hostname
00603     addDOMforSMhost(maker, tableRow, stats.regPtr->sourceURL());
00604 
00605     // Status
00606     if ( stats.connectionStatus == DataRetrieverMonitorCollection::CONNECTED )
00607     {
00608       tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
00609       maker.addText(tableDiv, "Connected");
00610     }
00611     else
00612     {
00613       stor::XHTMLMaker::AttrMap statusAttr = tableLabelAttr_;
00614       statusAttr[ "style" ] = "color:brown;";
00615       tableDiv = maker.addNode("td", tableRow, statusAttr);
00616       std::ostringstream status;
00617       status << stats.connectionStatus;
00618       maker.addText(tableDiv, status.str());
00619     }
00620 
00621     // Requested event type
00622     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
00623     stor::XHTMLMaker::Node* pre = maker.addNode("pre", tableDiv);
00624     std::ostringstream eventType;
00625     stats.regPtr->eventType(eventType);
00626     maker.addText(pre, eventType.str());
00627 
00628     // Max request rate
00629     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00630     const stor::utils::Duration_t interval =
00631       stats.regPtr->minEventRequestInterval();
00632     if ( interval.is_not_a_date_time() )
00633       maker.addText(tableDiv, "unlimited");
00634     else
00635       maker.addDouble(tableDiv, 1 / stor::utils::durationToSeconds(interval), 1);
00636 
00637     // Event rate
00638     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00639     maker.addDouble(tableDiv, stats.sizeStats.getSampleRate(stor::MonitoredQuantity::FULL));
00640     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00641     maker.addDouble(tableDiv, stats.sizeStats.getSampleRate(stor::MonitoredQuantity::RECENT));
00642 
00643     // Average event size
00644     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00645     maker.addDouble(tableDiv, stats.sizeStats.getValueAverage(stor::MonitoredQuantity::FULL));
00646     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00647     maker.addDouble(tableDiv, stats.sizeStats.getValueAverage(stor::MonitoredQuantity::RECENT));
00648     
00649     // Bandwidth
00650     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00651     maker.addDouble(tableDiv, stats.sizeStats.getValueRate(stor::MonitoredQuantity::FULL));
00652     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00653     maker.addDouble(tableDiv, stats.sizeStats.getValueRate(stor::MonitoredQuantity::RECENT));
00654   }
00655   
00656   
00657   void SMPSWebPageHelper::addSummaryRowForEventServer
00658   (
00659     stor::XHTMLMaker& maker,
00660     stor::XHTMLMaker::Node* table,
00661     DataRetrieverMonitorCollection::ConnectionStats::const_iterator pos
00662   ) const
00663   {
00664     stor::XHTMLMaker::Node* tableRow = maker.addNode("tr", table, specialRowAttr_);
00665     
00666     // Hostname
00667     addDOMforSMhost(maker, tableRow, pos->first);
00668 
00669     // Status, requst type, and max request rate not filled
00670     stor::XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00671     tableDiv = maker.addNode("td", tableRow);
00672     tableDiv = maker.addNode("td", tableRow);
00673     
00674     // Event rate
00675     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00676     maker.addDouble(tableDiv, pos->second.getSampleRate(stor::MonitoredQuantity::FULL));
00677     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00678     maker.addDouble(tableDiv, pos->second.getSampleRate(stor::MonitoredQuantity::RECENT));
00679 
00680     // Average event size
00681     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00682     maker.addDouble(tableDiv, pos->second.getValueAverage(stor::MonitoredQuantity::FULL));
00683     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00684     maker.addDouble(tableDiv, pos->second.getValueAverage(stor::MonitoredQuantity::RECENT));
00685     
00686     // Bandwidth
00687     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00688     maker.addDouble(tableDiv, pos->second.getValueRate(stor::MonitoredQuantity::FULL));
00689     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00690     maker.addDouble(tableDiv, pos->second.getValueRate(stor::MonitoredQuantity::RECENT));
00691   }
00692   
00693   
00694   void SMPSWebPageHelper::addDOMforSMhost
00695   (
00696     stor::XHTMLMaker& maker,
00697     stor::XHTMLMaker::Node* tableRow,
00698     const std::string& sourceURL
00699   ) const
00700   {
00701     stor::XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
00702     std::string::size_type startPos = sourceURL.find("//");
00703     if ( startPos == std::string::npos )
00704       startPos = 0; 
00705     else
00706       startPos += 2;
00707     const std::string::size_type endPos = sourceURL.find('.');
00708     const std::string hostname = sourceURL.substr(startPos,(endPos-startPos));
00709     stor::XHTMLMaker::AttrMap linkAttr;
00710     linkAttr[ "href" ] = sourceURL + "/consumerStatistics";
00711     stor::XHTMLMaker::Node* link = maker.addNode("a", tableDiv, linkAttr);
00712     maker.addText(link, hostname);
00713   }
00714   
00715   
00716   void SMPSWebPageHelper::addDOMforDQMEventServers
00717   (
00718     stor::XHTMLMaker& maker,
00719     stor::XHTMLMaker::Node* parent
00720   ) const
00721   {
00722   }
00723   
00724 } // namespace smproxy
00725 
00726