CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/EventFilter/StorageManager/src/SMWebPageHelper.cc

Go to the documentation of this file.
00001 // $Id: SMWebPageHelper.cc,v 1.5 2011/11/08 10:48:41 mommsen Exp $
00003 
00004 #include <iomanip>
00005 #include <iostream>
00006 #include <sstream>
00007 #include <stdio.h>
00008 
00009 #include "boost/lexical_cast.hpp"
00010 
00011 #include "EventFilter/StorageManager/interface/AlarmHandler.h"
00012 #include "EventFilter/StorageManager/interface/EventConsumerMonitorCollection.h"
00013 #include "EventFilter/StorageManager/interface/FilesMonitorCollection.h"
00014 #include "EventFilter/StorageManager/interface/FragmentMonitorCollection.h"
00015 #include "EventFilter/StorageManager/interface/MonitoredQuantity.h"
00016 #include "EventFilter/StorageManager/interface/RegistrationCollection.h"
00017 #include "EventFilter/StorageManager/interface/ResourceMonitorCollection.h"
00018 #include "EventFilter/StorageManager/interface/RunMonitorCollection.h"
00019 #include "EventFilter/StorageManager/interface/StreamsMonitorCollection.h"
00020 #include "EventFilter/StorageManager/interface/SMWebPageHelper.h"
00021 #include "EventFilter/StorageManager/interface/XHTMLMonitor.h"
00022 #include "EventFilter/StorageManager/src/ConsumerWebPageHelper.icc"
00023 
00024 #include "toolbox/net/Utils.h"
00025 
00026 
00027 namespace stor
00028 {
00029 
00030   SMWebPageHelper::SMWebPageHelper
00031   (
00032     xdaq::ApplicationDescriptor* appDesc,
00033     SharedResourcesPtr sharedResources
00034   ) :
00035   WebPageHelper<SMWebPageHelper>(appDesc, "$Name: V08-04-03-01 $", this, &stor::SMWebPageHelper::addDOMforHyperLinks),
00036   sharedResources_(sharedResources),
00037   consumerWebPageHelper_(appDesc, "$Name: V08-04-03-01 $", this, &stor::SMWebPageHelper::addDOMforHyperLinks)
00038   {}
00039 
00040 
00041   void SMWebPageHelper::defaultWebPage(xgi::Output *out) const
00042   {
00043     XHTMLMonitor theMonitor;
00044     XHTMLMaker maker;
00045     
00046     StatisticsReporterPtr statReporter = sharedResources_->statisticsReporter_;
00047     
00048     // Create the body with the standard header
00049     XHTMLMaker::Node* body = createWebPageBody(maker, "Main",
00050       statReporter->getStateMachineMonitorCollection());
00051     
00052     // Run and event summary
00053     addDOMforRunMonitor(maker, body, statReporter->getRunMonitorCollection());
00054     
00055     // Resource usage
00056     addDOMforResourceUsage(maker, body, 
00057       statReporter->getResourceMonitorCollection(),
00058       statReporter->getThroughputMonitorCollection());
00059     
00060     // Add the received data statistics table
00061     addDOMforFragmentMonitor(maker, body,
00062       statReporter->getFragmentMonitorCollection());
00063     
00064     addDOMforHyperLinks(maker, body);
00065     
00066     // Dump the webpage to the output stream
00067     maker.out(*out);
00068   }
00069   
00070   
00071   void SMWebPageHelper::storedDataWebPage(xgi::Output *out) const
00072   {
00073     XHTMLMonitor theMonitor;
00074     XHTMLMaker maker;
00075     
00076     StatisticsReporterPtr statReporter = sharedResources_->statisticsReporter_;
00077     
00078     // Create the body with the standard header
00079     XHTMLMaker::Node* body = createWebPageBody(maker, "Stored Data",
00080       statReporter->getStateMachineMonitorCollection());
00081     
00082     addDOMforStoredData(maker, body, statReporter->getStreamsMonitorCollection());
00083     
00084     maker.addNode("hr", body);
00085     
00086     addDOMforConfigString(maker, body, sharedResources_->configuration_->getDiskWritingParams());  
00087     
00088     addDOMforHyperLinks(maker, body);
00089     
00090     // Dump the webpage to the output stream
00091     maker.out(*out);
00092   }
00093   
00094   
00095   void SMWebPageHelper::filesWebPage(xgi::Output *out) const
00096   {
00097     XHTMLMonitor theMonitor;
00098     XHTMLMaker maker;
00099     
00100     StatisticsReporterPtr statReporter = sharedResources_->statisticsReporter_;
00101     
00102     // Create the body with the standard header
00103     XHTMLMaker::Node* body = createWebPageBody(maker, "Files",
00104       statReporter->getStateMachineMonitorCollection());
00105     
00106     addDOMforFiles(maker, body, statReporter->getFilesMonitorCollection());  
00107     
00108     addDOMforHyperLinks(maker, body);
00109     
00110     // Dump the webpage to the output stream
00111     maker.out(*out);
00112   }
00113   
00114   
00115   void SMWebPageHelper::consumerStatistics(xgi::Output *out) const
00116   {
00117     const StateMachineMonitorCollection& stateMachineMonitorCollection =
00118       sharedResources_->statisticsReporter_->getStateMachineMonitorCollection();
00119 
00120     std::string errorMsg;
00121     stateMachineMonitorCollection.statusMessage(errorMsg);
00122 
00123     consumerWebPageHelper_.consumerStatistics(out,
00124       stateMachineMonitorCollection.externallyVisibleState(),
00125       stateMachineMonitorCollection.innerStateName(),
00126       errorMsg,
00127       sharedResources_->statisticsReporter_,
00128       sharedResources_->registrationCollection_,
00129       sharedResources_->eventQueueCollection_,
00130       sharedResources_->dqmEventQueueCollection_
00131     );
00132   }
00133   
00134   
00135   void SMWebPageHelper::resourceBrokerOverview(xgi::Output *out) const
00136   {
00137     XHTMLMonitor theMonitor;
00138     XHTMLMaker maker;
00139     
00140     StatisticsReporterPtr statReporter = sharedResources_->statisticsReporter_;
00141     
00142     // Create the body with the standard header
00143     XHTMLMaker::Node* body = createWebPageBody(maker, "Resource Broker Overview",
00144       statReporter->getStateMachineMonitorCollection());
00145     
00146     addOutputModuleTables(maker, body,
00147       statReporter->getDataSenderMonitorCollection());  
00148     
00149     maker.addNode("hr", body);
00150     
00151     addResourceBrokerList(maker, body,
00152       statReporter->getDataSenderMonitorCollection());
00153     
00154     addDOMforHyperLinks(maker, body);
00155     
00156     // Dump the webpage to the output stream
00157     maker.out(*out);
00158   }
00159   
00160   
00161   void SMWebPageHelper::resourceBrokerDetail
00162   (
00163     xgi::Output *out,
00164     const long long& uniqueRBID
00165   ) const
00166   {
00167     XHTMLMonitor theMonitor;
00168     XHTMLMaker maker;
00169     
00170     StatisticsReporterPtr statReporter = sharedResources_->statisticsReporter_;
00171     
00172     // Create the body with the standard header
00173     std::ostringstream pageTitle;
00174     pageTitle << "Resource Broker " << uniqueRBID << " Detail";
00175     XHTMLMaker::Node* body = createWebPageBody(maker, pageTitle.str(),
00176       statReporter->getStateMachineMonitorCollection());
00177     
00178     addResourceBrokerDetails(maker, body, uniqueRBID,
00179       statReporter->getDataSenderMonitorCollection());  
00180     
00181     addOutputModuleStatistics(maker, body, uniqueRBID,
00182       statReporter->getDataSenderMonitorCollection());  
00183     
00184     addFilterUnitList(maker, body, uniqueRBID,
00185       statReporter->getDataSenderMonitorCollection());  
00186     
00187     addDOMforHyperLinks(maker, body);
00188     
00189     // Dump the webpage to the output stream
00190     maker.out(*out);
00191   }
00192   
00193   
00194   void SMWebPageHelper::dqmEventWebPage(xgi::Output* out) const
00195   {
00196     XHTMLMonitor theMonitor;
00197     XHTMLMaker maker;
00198     
00199     StatisticsReporterPtr statReporter = sharedResources_->statisticsReporter_;
00200     
00201     // Create the body with the standard header
00202     XHTMLMaker::Node* body = createWebPageBody(maker, "DQM Event Processor",
00203       statReporter->getStateMachineMonitorCollection());
00204     
00205     addDOMforProcessedDQMEvents(maker, body, statReporter->getDQMEventMonitorCollection());  
00206     addDOMforDQMEventStatistics(maker, body, statReporter->getDQMEventMonitorCollection());  
00207     
00208     addDOMforHyperLinks(maker, body);
00209     
00210     // Dump the webpage to the output stream
00211     maker.out(*out);
00212   }
00213   
00214   
00215   void SMWebPageHelper::throughputWebPage(xgi::Output *out) const
00216   {
00217     XHTMLMonitor theMonitor;
00218     XHTMLMaker maker;
00219     
00220     StatisticsReporterPtr statReporter = sharedResources_->statisticsReporter_;
00221     
00222     // Create the body with the standard header
00223     XHTMLMaker::Node* body = createWebPageBody(maker, "Throughput",
00224       statReporter->getStateMachineMonitorCollection());
00225     
00226     addDOMforThroughputStatistics(maker, body, statReporter->getThroughputMonitorCollection());  
00227     
00228     addDOMforHyperLinks(maker, body);
00229     
00230     // Dump the webpage to the output stream
00231     maker.out(*out);
00232   }
00233   
00234   
00235   XHTMLMaker::Node* SMWebPageHelper::createWebPageBody
00236   (
00237     XHTMLMaker& maker,
00238     const std::string& pageTitle,
00239     const StateMachineMonitorCollection& stateMachineMonitorCollection
00240   ) const
00241   {
00242     std::string errorMsg;
00243     stateMachineMonitorCollection.statusMessage(errorMsg);
00244     
00245     return WebPageHelper<SMWebPageHelper>::createWebPageBody(
00246       maker,
00247       pageTitle,
00248       stateMachineMonitorCollection.externallyVisibleState(),
00249       stateMachineMonitorCollection.innerStateName(),
00250       errorMsg
00251     );
00252   }
00253   
00254   
00255   void SMWebPageHelper::addDOMforHyperLinks
00256   (
00257     XHTMLMaker& maker,
00258     XHTMLMaker::Node *parent
00259   ) const
00260   {
00261     std::string url = appDescriptor_->getContextDescriptor()->getURL()
00262       + "/" + appDescriptor_->getURN();
00263     
00264     XHTMLMaker::AttrMap linkAttr;
00265     XHTMLMaker::Node *link;
00266     
00267     maker.addNode("hr", parent);
00268     
00269     linkAttr[ "href" ] = url;
00270     link = maker.addNode("a", parent, linkAttr);
00271     maker.addText(link, "Main web page");
00272     
00273     maker.addNode("hr", parent);
00274     
00275     linkAttr[ "href" ] = url + "/storedData";
00276     link = maker.addNode("a", parent, linkAttr);
00277     maker.addText(link, "Stored data web page");
00278     
00279     maker.addNode("hr", parent);
00280     
00281     linkAttr[ "href" ] = url + "/rbsenderlist";
00282     link = maker.addNode("a", parent, linkAttr);
00283     maker.addText(link, "RB Sender list web page");
00284     
00285     maker.addNode("hr", parent);
00286     
00287     linkAttr[ "href" ] = url + "/fileStatistics";
00288     link = maker.addNode("a", parent, linkAttr);
00289     maker.addText(link, "File Statistics web page");
00290     
00291     maker.addNode("hr", parent);
00292     
00293     linkAttr[ "href" ] = url + "/consumerStatistics";
00294     link = maker.addNode("a", parent, linkAttr);
00295     maker.addText(link, "Consumer Statistics");
00296     
00297     maker.addNode("hr", parent);
00298     
00299     linkAttr[ "href" ] = url + "/dqmEventStatistics";
00300     link = maker.addNode("a", parent, linkAttr);
00301     maker.addText(link, "DQM event processor statistics");
00302     
00303     maker.addNode("hr", parent);
00304     
00305     linkAttr[ "href" ] = url + "/throughputStatistics";
00306     link = maker.addNode("a", parent, linkAttr);
00307     maker.addText(link, "Throughput statistics");
00308     
00309     maker.addNode("hr", parent);
00310   }
00311   
00312   
00313   void SMWebPageHelper::addDOMforResourceUsage
00314   (
00315     XHTMLMaker& maker,
00316     XHTMLMaker::Node *parent,
00317     ResourceMonitorCollection const& rmc,
00318     ThroughputMonitorCollection const& tmc
00319   ) const
00320   {
00321     ResourceMonitorCollection::Stats rmcStats;
00322     rmc.getStats(rmcStats);
00323     MonitoredQuantity::Stats poolUsageStats;
00324     tmc.getPoolUsageMQ().getStats(poolUsageStats);
00325     
00326     XHTMLMaker::AttrMap halfWidthAttr;
00327     halfWidthAttr[ "width" ] = "50%";
00328     
00329     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00330     
00331     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00332     
00333     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow, halfWidthAttr);
00334     addTableForResourceUsages(maker, tableDiv, rmcStats, poolUsageStats);
00335     
00336     tableDiv = maker.addNode("td", tableRow, halfWidthAttr);
00337     addTableForDiskUsages(maker, tableDiv, rmcStats);
00338   }
00339   
00340   
00341   void SMWebPageHelper::addTableForResourceUsages
00342   (
00343     XHTMLMaker& maker,
00344     XHTMLMaker::Node *parent,
00345     ResourceMonitorCollection::Stats const& rmcStats,
00346     MonitoredQuantity::Stats const& poolUsageStats
00347   ) const
00348   {
00349     XHTMLMaker::AttrMap colspanAttr;
00350     colspanAttr[ "colspan" ] = "2";
00351     
00352     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00353     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00354     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00355     maker.addText(tableDiv, "Resource Usage");
00356     
00357     addRowsForMemoryUsage(maker, table, poolUsageStats);
00358     addRowsForWorkers(maker, table, rmcStats);
00359     addRowsForSataBeast(maker, table, rmcStats);
00360   }
00361   
00362   
00363   void SMWebPageHelper::addRowsForMemoryUsage
00364   (
00365     XHTMLMaker& maker,
00366     XHTMLMaker::Node *table,
00367     MonitoredQuantity::Stats const& stats
00368   ) const
00369   {
00370     XHTMLMaker::AttrMap colspanAttr;
00371     colspanAttr[ "colspan" ] = "2";
00372     
00373     XHTMLMaker::AttrMap tableLabelAttr = tableLabelAttr_;
00374     tableLabelAttr[ "width" ] = "54%";
00375     
00376     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
00377     tableValueAttr[ "width" ] = "46%";
00378     
00379     // Memory pool usage
00380     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00381     XHTMLMaker::Node* tableDiv;
00382     if ( stats.getSampleCount() > 0 )
00383     {
00384       tableDiv = maker.addNode("td", tableRow);
00385       maker.addText(tableDiv, "Memory pool used (bytes)");
00386       tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00387       maker.addDouble( tableDiv, stats.getLastSampleValue(), 0 );
00388     }
00389     else
00390     {
00391       tableDiv = maker.addNode("td", tableRow, colspanAttr);
00392       maker.addText(tableDiv, "Memory pool pointer not yet available");
00393     }
00394   }
00395   
00396   
00397   void SMWebPageHelper::addRowsForWorkers
00398   (
00399     XHTMLMaker& maker,
00400     XHTMLMaker::Node *table,
00401     ResourceMonitorCollection::Stats const& stats
00402   ) const
00403   {
00404     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
00405     tableValueAttr[ "width" ] = "46%";
00406     
00407     // # copy worker
00408     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00409     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00410     maker.addText(tableDiv, "# CopyWorker");
00411     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00412     maker.addInt( tableDiv, stats.numberOfCopyWorkers );
00413     
00414     // # inject worker
00415     tableRow = maker.addNode("tr", table, rowAttr_);
00416     tableDiv = maker.addNode("td", tableRow);
00417     maker.addText(tableDiv, "# InjectWorker");
00418     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00419     maker.addInt( tableDiv, stats.numberOfInjectWorkers );
00420   }
00421   
00422   
00423   void SMWebPageHelper::addRowsForSataBeast
00424   (
00425     XHTMLMaker& maker,
00426     XHTMLMaker::Node *table,
00427     ResourceMonitorCollection::Stats const& stats
00428   ) const
00429   {
00430     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
00431     tableValueAttr[ "width" ] = "46%";
00432     
00433     XHTMLMaker::Node *tableRow, *tableDiv;
00434     
00435     XHTMLMaker::AttrMap warningAttr = rowAttr_;
00436     
00437     if (stats.sataBeastStatus < 0 )
00438     {
00439       warningAttr[ "bgcolor" ] = alarmColors_.find(AlarmHandler::WARNING)->second;
00440       
00441       XHTMLMaker::AttrMap colspanAttr = tableLabelAttr_;
00442       colspanAttr[ "colspan" ] = "2";
00443       
00444       tableRow = maker.addNode("tr", table, warningAttr);
00445       tableDiv = maker.addNode("td", tableRow, colspanAttr);
00446       maker.addText(tableDiv, "No SATA disks found");
00447     }
00448     else
00449     {
00450       if ( stats.sataBeastStatus > 0 )
00451         warningAttr[ "bgcolor" ] = alarmColors_.find(AlarmHandler::ERROR)->second;
00452       tableRow = maker.addNode("tr", table, warningAttr);
00453       tableDiv = maker.addNode("td", tableRow);
00454       maker.addText(tableDiv, "SATA beast status");
00455       tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00456       maker.addInt( tableDiv, stats.sataBeastStatus );
00457     }
00458   }
00459   
00460   
00461   void SMWebPageHelper::addTableForDiskUsages
00462   (
00463     XHTMLMaker& maker,
00464     XHTMLMaker::Node *parent,
00465     ResourceMonitorCollection::Stats const& stats
00466   ) const
00467   {
00468     XHTMLMaker::AttrMap colspanAttr;
00469     colspanAttr[ "colspan" ] = "2";
00470     
00471     XHTMLMaker::AttrMap tableLabelAttr = tableLabelAttr_;
00472     tableLabelAttr[ "width" ] = "54%";
00473     
00474     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
00475     tableValueAttr[ "width" ] = "46%";
00476     
00477     XHTMLMaker::AttrMap warningAttr = rowAttr_;
00478     
00479     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00480     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00481     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00482     maker.addText(tableDiv, "Disk Space Usage");
00483     
00484     
00485     for (ResourceMonitorCollection::DiskUsageStatsPtrList::const_iterator
00486            it = stats.diskUsageStatsList.begin(),
00487            itEnd = stats.diskUsageStatsList.end();
00488          it != itEnd;
00489          ++it)
00490     {
00491       warningAttr[ "bgcolor" ] = alarmColors_.find( (*it)->alarmState )->second;
00492       tableRow = maker.addNode("tr", table, warningAttr);
00493       tableDiv = maker.addNode("td", tableRow);
00494       maker.addText(tableDiv, (*it)->pathName);
00495       tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00496       if ( (*it)->diskSize > 0 )
00497       {
00498         std::ostringstream tmpString;
00499         tmpString << std::fixed << std::setprecision(0) <<
00500           (*it)->relDiskUsage << "% (" <<
00501           (*it)->absDiskUsage << " of " << 
00502           (*it)->diskSize << " GB)";
00503         maker.addText(tableDiv, tmpString.str());
00504       }
00505       else
00506       {
00507         maker.addText(tableDiv, "not mounted");
00508       }
00509     }
00510   }
00511   
00512   
00513   void SMWebPageHelper::addDOMforFragmentMonitor
00514   (
00515     XHTMLMaker& maker,
00516     XHTMLMaker::Node *parent,
00517     FragmentMonitorCollection const& fmc
00518   ) const
00519   {
00520     FragmentMonitorCollection::FragmentStats stats;
00521     fmc.getStats(stats);
00522     
00523     XHTMLMaker::AttrMap colspanAttr;
00524     colspanAttr[ "colspan" ] = "4";
00525     
00526     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00527     
00528     // Received Data Statistics header
00529     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00530     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00531     maker.addText(tableDiv, "Received I2O Frames");
00532     
00533     // Parameter/Value header
00534     tableRow = maker.addNode("tr", table, rowAttr_);
00535     tableDiv = maker.addNode("th", tableRow);
00536     maker.addText(tableDiv, "Parameter");
00537     tableDiv = maker.addNode("th", tableRow);
00538     maker.addText(tableDiv, "Total");
00539     tableDiv = maker.addNode("th", tableRow);
00540     maker.addText(tableDiv, "Events");
00541     tableDiv = maker.addNode("th", tableRow);
00542     maker.addText(tableDiv, "DQM histos");
00543     
00544     addFragmentStats(maker, table, stats,  MonitoredQuantity::FULL);
00545     
00546     addFragmentStats(maker, table, stats,  MonitoredQuantity::RECENT);
00547   }
00548   
00549   void SMWebPageHelper::addFragmentStats
00550   (
00551     XHTMLMaker& maker,
00552     XHTMLMaker::Node *table,
00553     FragmentMonitorCollection::FragmentStats const& stats,
00554     const MonitoredQuantity::DataSetType dataSet
00555   ) const
00556   {
00557     // Mean performance header
00558     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00559     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow);
00560     if ( dataSet == MonitoredQuantity::FULL )
00561       maker.addText(tableDiv, "Performance for full run");
00562     else
00563       maker.addText(tableDiv, "Recent performance for last");
00564     
00565     addDurationToTableHead(maker, tableRow,
00566       stats.allFragmentSizeStats.getDuration(dataSet));
00567     addDurationToTableHead(maker, tableRow,
00568       stats.eventFragmentSizeStats.getDuration(dataSet));
00569     addDurationToTableHead(maker, tableRow,
00570       stats.dqmEventFragmentSizeStats.getDuration(dataSet));
00571     
00572     addRowForFramesReceived(maker, table, stats, dataSet);
00573     addRowForBandwidth(maker, table, stats, dataSet);
00574     addRowForRate(maker, table, stats, dataSet);
00575     addRowForLatency(maker, table, stats, dataSet);
00576     if ( dataSet == MonitoredQuantity::FULL )
00577     {
00578       addRowForTotalVolume(maker, table, stats, dataSet);
00579     }
00580     else
00581     {
00582       addRowForMaxBandwidth(maker, table, stats, dataSet);
00583       addRowForMinBandwidth(maker, table, stats, dataSet);
00584     }
00585   }
00586   
00587   
00588   void SMWebPageHelper::addRowForFramesReceived
00589   (
00590     XHTMLMaker& maker,
00591     XHTMLMaker::Node *table,
00592     FragmentMonitorCollection::FragmentStats const& stats,
00593     const MonitoredQuantity::DataSetType dataSet
00594   ) const
00595   {
00596     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00597     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00598     maker.addText(tableDiv, "Frames Received");
00599     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00600     maker.addInt( tableDiv, stats.allFragmentSizeStats.getSampleCount(dataSet) );
00601     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00602     maker.addInt( tableDiv, stats.eventFragmentSizeStats.getSampleCount(dataSet) );
00603     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00604     maker.addInt( tableDiv, stats.dqmEventFragmentSizeStats.getSampleCount(dataSet) );
00605   }
00606   
00607   
00608   void SMWebPageHelper::addRowForBandwidth
00609   (
00610     XHTMLMaker& maker,
00611     XHTMLMaker::Node *table,
00612     FragmentMonitorCollection::FragmentStats const& stats,
00613     const MonitoredQuantity::DataSetType dataSet
00614   ) const
00615   {
00616     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00617     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00618     maker.addText(tableDiv, "Bandwidth (MB/s)");
00619     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00620     maker.addDouble( tableDiv, stats.allFragmentSizeStats.getValueRate(dataSet) );
00621     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00622     maker.addDouble( tableDiv, stats.eventFragmentSizeStats.getValueRate(dataSet) );
00623     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00624     maker.addDouble( tableDiv, stats.dqmEventFragmentSizeStats.getValueRate(dataSet) );
00625   }
00626   
00627   
00628   void SMWebPageHelper::addRowForRate
00629   (
00630     XHTMLMaker& maker,
00631     XHTMLMaker::Node *table,
00632     FragmentMonitorCollection::FragmentStats const& stats,
00633     const MonitoredQuantity::DataSetType dataSet
00634   ) const
00635   {
00636     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00637     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00638     maker.addText(tableDiv, "Rate (frames/s)");
00639     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00640     maker.addDouble( tableDiv, stats.allFragmentSizeStats.getSampleRate(dataSet) );
00641     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00642     maker.addDouble( tableDiv, stats.eventFragmentSizeStats.getSampleRate(dataSet) );
00643     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00644     maker.addDouble( tableDiv, stats.dqmEventFragmentSizeStats.getSampleRate(dataSet) );
00645   }
00646   
00647   
00648   void SMWebPageHelper::addRowForLatency
00649   (
00650     XHTMLMaker& maker,
00651     XHTMLMaker::Node *table,
00652     FragmentMonitorCollection::FragmentStats const& stats,
00653     const MonitoredQuantity::DataSetType dataSet
00654   ) const
00655   {
00656     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00657     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00658     maker.addText(tableDiv, "Latency (us/frame)");
00659     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00660     maker.addDouble( tableDiv, stats.allFragmentSizeStats.getSampleLatency(dataSet) );
00661     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00662     maker.addDouble( tableDiv, stats.eventFragmentSizeStats.getSampleLatency(dataSet) );
00663     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00664     maker.addDouble( tableDiv, stats.dqmEventFragmentSizeStats.getSampleLatency(dataSet) );
00665   }
00666   
00667   
00668   void SMWebPageHelper::addRowForTotalVolume
00669   (
00670     XHTMLMaker& maker,
00671     XHTMLMaker::Node *table,
00672     FragmentMonitorCollection::FragmentStats const& stats,
00673     const MonitoredQuantity::DataSetType dataSet
00674   ) const
00675   {
00676     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00677     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00678     maker.addText(tableDiv, "Total volume received (MB)");
00679     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00680     maker.addDouble( tableDiv, stats.allFragmentSizeStats.getValueSum(dataSet), 3 );
00681     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00682     maker.addDouble( tableDiv, stats.eventFragmentSizeStats.getValueSum(dataSet), 3 );
00683     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00684     maker.addDouble( tableDiv, stats.dqmEventFragmentSizeStats.getValueSum(dataSet), 3 );
00685   }
00686   
00687   
00688   void SMWebPageHelper::addRowForMaxBandwidth
00689   (
00690     XHTMLMaker& maker,
00691     XHTMLMaker::Node *table,
00692     FragmentMonitorCollection::FragmentStats const& stats,
00693     const MonitoredQuantity::DataSetType dataSet
00694   ) const
00695   {
00696     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00697     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00698     maker.addText(tableDiv, "Maximum Bandwidth (MB/s)");
00699     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00700     maker.addDouble( tableDiv, stats.allFragmentBandwidthStats.getValueMax(dataSet) );
00701     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00702     maker.addDouble( tableDiv, stats.eventFragmentBandwidthStats.getValueMax(dataSet) );
00703     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00704     maker.addDouble( tableDiv, stats.dqmEventFragmentBandwidthStats.getValueMax(dataSet) );
00705   }
00706   
00707   
00708   void SMWebPageHelper::addRowForMinBandwidth
00709   (
00710     XHTMLMaker& maker,
00711     XHTMLMaker::Node *table,
00712     FragmentMonitorCollection::FragmentStats const& stats,
00713     const MonitoredQuantity::DataSetType dataSet
00714   ) const
00715   {
00716     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00717     XHTMLMaker::Node* tableDiv = maker.addNode("td", tableRow);
00718     maker.addText(tableDiv, "Minimum Bandwidth (MB/s)");
00719     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00720     maker.addDouble( tableDiv, stats.allFragmentBandwidthStats.getValueMin(dataSet) );
00721     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00722     maker.addDouble( tableDiv, stats.eventFragmentBandwidthStats.getValueMin(dataSet) );
00723     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00724     maker.addDouble( tableDiv, stats.dqmEventFragmentBandwidthStats.getValueMin(dataSet) );
00725   }
00726   
00727   
00728   void SMWebPageHelper::addDOMforRunMonitor
00729   (
00730     XHTMLMaker& maker,
00731     XHTMLMaker::Node *parent,
00732     RunMonitorCollection const& rmc
00733   ) const
00734   {
00735     MonitoredQuantity::Stats eventIDsReceivedStats;
00736     rmc.getEventIDsReceivedMQ().getStats(eventIDsReceivedStats);
00737     MonitoredQuantity::Stats errorEventIDsReceivedStats;
00738     rmc.getErrorEventIDsReceivedMQ().getStats(errorEventIDsReceivedStats);
00739     MonitoredQuantity::Stats unwantedEventIDsReceivedStats;
00740     rmc.getUnwantedEventIDsReceivedMQ().getStats(unwantedEventIDsReceivedStats);
00741     MonitoredQuantity::Stats runNumbersSeenStats;
00742     rmc.getRunNumbersSeenMQ().getStats(runNumbersSeenStats);
00743     MonitoredQuantity::Stats lumiSectionsSeenStats;
00744     rmc.getLumiSectionsSeenMQ().getStats(lumiSectionsSeenStats);
00745     MonitoredQuantity::Stats eolsSeenStats;
00746     rmc.getEoLSSeenMQ().getStats(eolsSeenStats);
00747     
00748     XHTMLMaker::AttrMap colspanAttr;
00749     colspanAttr[ "colspan" ] = "6";
00750     
00751     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
00752     tableValueAttr[ "width" ] = "16%";
00753     
00754     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00755     
00756     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00757     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00758     maker.addText(tableDiv, "Storage Manager Statistics");
00759     
00760     // Run number and lumi section
00761     tableRow = maker.addNode("tr", table, rowAttr_);
00762     tableDiv = maker.addNode("td", tableRow);
00763     maker.addText(tableDiv, "Run number");
00764     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00765     maker.addDouble( tableDiv, runNumbersSeenStats.getLastSampleValue(), 0 );
00766     tableDiv = maker.addNode("td", tableRow);
00767     maker.addText(tableDiv, "Current lumi section");
00768     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00769     maker.addDouble( tableDiv, lumiSectionsSeenStats.getLastSampleValue(), 0 );
00770     tableDiv = maker.addNode("td", tableRow);
00771     maker.addText(tableDiv, "Last EoLS");
00772     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00773     maker.addDouble( tableDiv, eolsSeenStats.getLastSampleValue(), 0 );
00774     
00775     // Total events received
00776     tableRow = maker.addNode("tr", table, specialRowAttr_);
00777     tableDiv = maker.addNode("td", tableRow);
00778     maker.addText(tableDiv, "Events received (non-unique)");
00779     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00780     maker.addInt( tableDiv, eventIDsReceivedStats.getSampleCount() );
00781     tableDiv = maker.addNode("td", tableRow);
00782     maker.addText(tableDiv, "Error events received");
00783     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00784     maker.addInt( tableDiv, errorEventIDsReceivedStats.getSampleCount() );
00785     tableDiv = maker.addNode("td", tableRow);
00786     maker.addText(tableDiv, "Unwanted events received");
00787     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00788     maker.addInt( tableDiv, unwantedEventIDsReceivedStats.getSampleCount() );
00789     
00790     // Last event IDs
00791     tableRow = maker.addNode("tr", table, rowAttr_);
00792     tableDiv = maker.addNode("td", tableRow);
00793     maker.addText(tableDiv, "Last event ID");
00794     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00795     maker.addDouble( tableDiv, eventIDsReceivedStats.getLastSampleValue(), 0 );
00796     tableDiv = maker.addNode("td", tableRow);
00797     maker.addText(tableDiv, "Last error event ID");
00798     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00799     maker.addDouble( tableDiv, errorEventIDsReceivedStats.getLastSampleValue(), 0 );
00800     tableDiv = maker.addNode("td", tableRow);
00801     maker.addText(tableDiv, "Last unwanted event ID");
00802     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
00803     maker.addDouble( tableDiv, unwantedEventIDsReceivedStats.getLastSampleValue(), 0 );
00804   }
00805   
00806   
00807   void SMWebPageHelper::addDOMforStoredData
00808   (
00809     XHTMLMaker& maker,
00810     XHTMLMaker::Node *parent,
00811     StreamsMonitorCollection const& smc
00812   ) const
00813   {
00814     MonitoredQuantity::Stats allStreamsVolumeStats;
00815     smc.getAllStreamsVolumeMQ().getStats(allStreamsVolumeStats);
00816     
00817     XHTMLMaker::AttrMap tableValueWidthAttr;
00818     tableValueWidthAttr[ "width" ] = "11%";
00819     
00820     XHTMLMaker::AttrMap rowspanAttr = tableValueWidthAttr;
00821     rowspanAttr[ "rowspan" ] = "2";
00822     rowspanAttr[ "valign" ] = "top";
00823     
00824     XHTMLMaker::AttrMap colspanAttr;
00825     colspanAttr[ "colspan" ] = "9";
00826     
00827     XHTMLMaker::AttrMap bandwidthColspanAttr;
00828     bandwidthColspanAttr[ "colspan" ] = "4";
00829     
00830     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
00831     
00832     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
00833     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
00834     maker.addText(tableDiv, "Stored Data Statistics");
00835     
00836     // Header
00837     tableRow = maker.addNode("tr", table, specialRowAttr_);
00838     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00839     maker.addText(tableDiv, "Stream");
00840     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00841     maker.addText(tableDiv, "Fraction to disk");
00842     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00843     maker.addText(tableDiv, "Files");
00844     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00845     maker.addText(tableDiv, "Events");
00846     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00847     maker.addText(tableDiv, "Events/s");
00848     tableDiv = maker.addNode("th", tableRow, rowspanAttr);
00849     maker.addText(tableDiv, "Volume (MB)");
00850     tableDiv = maker.addNode("th", tableRow, bandwidthColspanAttr);
00851     maker.addText(tableDiv, "Bandwidth (MB/s)");
00852     
00853     tableRow = maker.addNode("tr", table, specialRowAttr_);
00854     tableDiv = maker.addNode("th", tableRow, tableValueWidthAttr);
00855     maker.addText(tableDiv, "average");
00856     tableDiv = maker.addNode("th", tableRow, tableValueWidthAttr);
00857     maker.addText(tableDiv, "min");
00858     tableDiv = maker.addNode("th", tableRow, tableValueWidthAttr);
00859     maker.addText(tableDiv, "max");
00860     
00861     if (! smc.streamRecordsExist())
00862     {
00863       tableRow = maker.addNode("tr", table, rowAttr_);
00864       tableDiv = maker.addNode("td", tableRow, colspanAttr);
00865       maker.addText(tableDiv, "no streams available yet");
00866       return;
00867     }
00868     // Mean performance
00869     tableRow = maker.addNode("tr", table, rowAttr_);
00870     tableDiv = maker.addNode("th", tableRow, colspanAttr);
00871     {
00872       std::ostringstream tmpString;
00873       tmpString << "Mean performance for " <<
00874         allStreamsVolumeStats.getDuration().total_seconds() << " s";
00875       maker.addText(tableDiv, tmpString.str());
00876     }
00877     listStreamRecordsStats(maker, table, smc, MonitoredQuantity::FULL);
00878     
00879     
00880     // Recent performance
00881     tableRow = maker.addNode("tr", table, rowAttr_);
00882     tableDiv = maker.addNode("th", tableRow, colspanAttr);
00883     {
00884       std::ostringstream tmpString;
00885       tmpString << "Recent performance for the last " <<
00886         allStreamsVolumeStats.getDuration(MonitoredQuantity::RECENT).total_seconds() << " s";
00887       maker.addText(tableDiv, tmpString.str());
00888     }
00889     listStreamRecordsStats(maker, table, smc, MonitoredQuantity::RECENT);
00890   }
00891   
00892   
00893   void SMWebPageHelper::addDOMforConfigString
00894   (
00895     XHTMLMaker& maker,
00896     XHTMLMaker::Node *parent,
00897     DiskWritingParams const& dwParams
00898   ) const
00899   {
00900     XHTMLMaker::Node* table = maker.addNode("table", parent);
00901     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, specialRowAttr_);
00902     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow);
00903     maker.addText(tableDiv, "SM Configuration");
00904     tableRow = maker.addNode("tr", table, rowAttr_);
00905     tableDiv = maker.addNode("td", tableRow);
00906     XHTMLMaker::AttrMap textareaAttr;
00907     textareaAttr[ "rows" ] = "10";
00908     textareaAttr[ "cols" ] = "100";
00909     textareaAttr[ "scroll" ] = "yes";
00910     textareaAttr[ "readonly" ];
00911     textareaAttr[ "title" ] = "SM config";
00912     XHTMLMaker::Node* textarea = maker.addNode("textarea", tableDiv, textareaAttr);
00913     maker.addText(textarea, dwParams.streamConfiguration_);
00914   }  
00915   
00916   
00917   void SMWebPageHelper::listStreamRecordsStats
00918   (
00919     XHTMLMaker& maker,
00920     XHTMLMaker::Node *table,
00921     StreamsMonitorCollection const& smc,
00922     const MonitoredQuantity::DataSetType dataSet
00923   ) const
00924   {
00925     StreamsMonitorCollection::StreamRecordList streamRecords;
00926     smc.getStreamRecords(streamRecords);
00927     MonitoredQuantity::Stats allStreamsFileCountStats;
00928     smc.getAllStreamsFileCountMQ().getStats(allStreamsFileCountStats);
00929     MonitoredQuantity::Stats allStreamsVolumeStats;
00930     smc.getAllStreamsVolumeMQ().getStats(allStreamsVolumeStats);
00931     MonitoredQuantity::Stats allStreamsBandwidthStats;
00932     smc.getAllStreamsBandwidthMQ().getStats(allStreamsBandwidthStats);
00933     
00934     XHTMLMaker::Node *tableRow, *tableDiv;
00935     
00936     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
00937     tableValueAttr[ "width" ] = "11%";
00938     
00939     
00940     for (
00941       StreamsMonitorCollection::StreamRecordList::const_iterator 
00942         it = streamRecords.begin(), itEnd = streamRecords.end();
00943       it != itEnd;
00944       ++it
00945     )
00946     {
00947       MonitoredQuantity::Stats streamFileCountStats;
00948       (*it)->fileCount.getStats(streamFileCountStats);
00949       MonitoredQuantity::Stats streamVolumeStats;
00950       (*it)->volume.getStats(streamVolumeStats);
00951       MonitoredQuantity::Stats streamBandwidthStats;
00952       (*it)->bandwidth.getStats(streamBandwidthStats);
00953       
00954       
00955       tableRow = maker.addNode("tr", table, rowAttr_);
00956       tableDiv = maker.addNode("td", tableRow);
00957       maker.addText(tableDiv, (*it)->streamName);
00958       tableDiv = maker.addNode("td", tableRow);
00959       maker.addDouble(tableDiv, (*it)->fractionToDisk, 2);
00960       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00961       maker.addInt( tableDiv, streamFileCountStats.getSampleCount(dataSet) );
00962       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00963       maker.addInt( tableDiv, streamVolumeStats.getSampleCount(dataSet) );
00964       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00965       maker.addDouble( tableDiv, streamVolumeStats.getSampleRate(dataSet), 1 );
00966       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00967       maker.addDouble( tableDiv, streamVolumeStats.getValueSum(dataSet), 1 );
00968       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00969       maker.addDouble( tableDiv, streamBandwidthStats.getValueRate(dataSet) );
00970       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00971       maker.addDouble( tableDiv, streamBandwidthStats.getValueMin(dataSet) );
00972       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00973       maker.addDouble( tableDiv, streamBandwidthStats.getValueMax(dataSet) );
00974     }
00975     
00976     tableRow = maker.addNode("tr", table, specialRowAttr_);
00977     tableDiv = maker.addNode("td", tableRow);
00978     maker.addText(tableDiv, "Total");
00979     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00980     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00981     maker.addInt( tableDiv, allStreamsFileCountStats.getSampleCount(dataSet) );
00982     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00983     maker.addInt( tableDiv, allStreamsVolumeStats.getSampleCount(dataSet) );
00984     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00985     maker.addDouble( tableDiv, allStreamsVolumeStats.getSampleRate(dataSet), 1 );
00986     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00987     maker.addDouble( tableDiv, allStreamsVolumeStats.getValueSum(dataSet), 1 );
00988     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00989     maker.addDouble( tableDiv, allStreamsBandwidthStats.getValueRate(dataSet) );
00990     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00991     maker.addDouble( tableDiv, allStreamsBandwidthStats.getValueMin(dataSet) );
00992     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
00993     maker.addDouble( tableDiv, allStreamsBandwidthStats.getValueMax(dataSet) );
00994   }
00995   
00996   
00997   void SMWebPageHelper::addDOMforFiles
00998   (
00999     XHTMLMaker& maker,
01000     XHTMLMaker::Node *parent,
01001     FilesMonitorCollection const& fmc
01002   ) const
01003   {
01004     FilesMonitorCollection::FileRecordList fileRecords;
01005     fmc.getFileRecords(fileRecords);
01006     
01007     XHTMLMaker::AttrMap colspanAttr;
01008     colspanAttr[ "colspan" ] = "6";
01009     
01010     XHTMLMaker::AttrMap tableLabelAttr = tableLabelAttr_;
01011     tableLabelAttr[ "align" ] = "center";
01012     
01013     XHTMLMaker::AttrMap tableValueWidthAttr;
01014     tableValueWidthAttr[ "width" ] = "11%";
01015     
01016     XHTMLMaker::AttrMap tableCounterWidthAttr;
01017     tableCounterWidthAttr[ "width" ] = "5%";
01018     
01019     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01020     
01021     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01022     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01023     maker.addText(tableDiv, "File Statistics (most recent first)");
01024     
01025     // Header
01026     tableRow = maker.addNode("tr", table, specialRowAttr_);
01027     tableDiv = maker.addNode("th", tableRow, tableCounterWidthAttr);
01028     maker.addText(tableDiv, "#");
01029     tableDiv = maker.addNode("th", tableRow);
01030     maker.addText(tableDiv, "Pathname");
01031     tableDiv = maker.addNode("th", tableRow, tableValueWidthAttr);
01032     maker.addText(tableDiv, "Events");
01033     tableDiv = maker.addNode("th", tableRow, tableValueWidthAttr);
01034     maker.addText(tableDiv, "Size (Bytes)");
01035     tableDiv = maker.addNode("th", tableRow, tableValueWidthAttr);
01036     maker.addText(tableDiv, "Closing reason");
01037     tableDiv = maker.addNode("th", tableRow, tableValueWidthAttr);
01038     maker.addText(tableDiv, "Adler32");
01039     
01040     // File list
01041     if (fileRecords.empty())
01042     {
01043       tableRow = maker.addNode("tr", table, rowAttr_);
01044       tableDiv = maker.addNode("td", tableRow, colspanAttr);
01045       maker.addText(tableDiv, "no files available yet");
01046       return;
01047     }
01048     
01049     for (
01050       FilesMonitorCollection::FileRecordList::const_reverse_iterator 
01051         it = fileRecords.rbegin(), itEnd = fileRecords.rend();
01052       it != itEnd;
01053       ++it
01054     )
01055     {
01056       tableRow = maker.addNode("tr", table, rowAttr_);
01057       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01058       maker.addInt( tableDiv, (*it)->entryCounter );
01059       tableDiv = maker.addNode("td", tableRow);
01060       maker.addText(tableDiv, (*it)->completeFileName());
01061       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01062       maker.addInt( tableDiv, (*it)->eventCount );
01063       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01064       maker.addInt( tableDiv, (*it)->fileSize );
01065       tableDiv = maker.addNode("td", tableRow, tableLabelAttr);
01066       maker.addText(tableDiv, (*it)->closingReason());
01067       tableDiv = maker.addNode("td", tableRow, tableLabelAttr);
01068       maker.addHex(tableDiv, (*it)->adler32);
01069     }
01070   }
01071   
01072   
01073   void SMWebPageHelper::addDOMforThroughputStatistics
01074   (
01075     XHTMLMaker& maker,
01076     XHTMLMaker::Node *parent,
01077     ThroughputMonitorCollection const& tmc
01078   ) const
01079   {
01080     XHTMLMaker::AttrMap colspanAttr;
01081     colspanAttr[ "colspan" ] = "21";
01082     
01083     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01084     
01085     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01086     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01087     maker.addText(tableDiv, "Throughput Statistics");
01088     
01089     // Header
01090     tableRow = maker.addNode("tr", table, specialRowAttr_);
01091     tableDiv = maker.addNode("th", tableRow);
01092     maker.addText(tableDiv, "Time (UTC)");
01093     tableDiv = maker.addNode("th", tableRow);
01094     maker.addText(tableDiv, "Memory pool usage (bytes)");
01095     tableDiv = maker.addNode("th", tableRow);
01096     maker.addText(tableDiv, "Instantaneous Number of Fragments in Fragment Queue");
01097     tableDiv = maker.addNode("th", tableRow);
01098     maker.addText(tableDiv, "Memory used in Fragment Queue (MB)");
01099     tableDiv = maker.addNode("th", tableRow);
01100     maker.addText(tableDiv, "Number of Fragments Popped from Fragment Queue (Hz)");
01101     tableDiv = maker.addNode("th", tableRow);
01102     maker.addText(tableDiv, "Data Rate Popped from Fragment Queue (MB/sec)");
01103     tableDiv = maker.addNode("th", tableRow);
01104     maker.addText(tableDiv, "Fragment Processor Thread Busy Percentage");
01105     tableDiv = maker.addNode("th", tableRow);
01106     maker.addText(tableDiv, "Instantaneous Number of Events in Fragment Store");
01107     tableDiv = maker.addNode("th", tableRow);
01108     maker.addText(tableDiv, "Memory used in Fragment Store (MB)");
01109     tableDiv = maker.addNode("th", tableRow);
01110     maker.addText(tableDiv, "Instantaneous Number of Events in Stream Queue");
01111     tableDiv = maker.addNode("th", tableRow);
01112     maker.addText(tableDiv, "Memory used in Stream Queue (MB)");
01113     tableDiv = maker.addNode("th", tableRow);
01114     maker.addText(tableDiv, "Number of Events Popped from Stream Queue (Hz)");
01115     tableDiv = maker.addNode("th", tableRow);
01116     maker.addText(tableDiv, "Data Rate Popped from Stream Queue (MB/sec)");
01117     tableDiv = maker.addNode("th", tableRow);
01118     maker.addText(tableDiv, "Disk Writer Thread Busy Percentage");
01119     tableDiv = maker.addNode("th", tableRow);
01120     maker.addText(tableDiv, "Number of Events Written to Disk (Hz)");
01121     tableDiv = maker.addNode("th", tableRow);
01122     maker.addText(tableDiv, "Data  Rate to Disk (MB/sec)");
01123     tableDiv = maker.addNode("th", tableRow);
01124     maker.addText(tableDiv, "Instantaneous Number of DQMEvents in DQMEvent Queue");
01125     tableDiv = maker.addNode("th", tableRow);
01126     maker.addText(tableDiv, "Memory used in DQMEvent Queue (MB)");
01127     tableDiv = maker.addNode("th", tableRow);
01128     maker.addText(tableDiv, "Number of DQMEvents Popped from DQMEvent Queue (Hz)");
01129     tableDiv = maker.addNode("th", tableRow);
01130     maker.addText(tableDiv, "Data Rate Popped from DQMEvent Queue (MB/sec)");
01131     tableDiv = maker.addNode("th", tableRow);
01132     maker.addText(tableDiv, "DQMEvent Processor Thread Busy Percentage");
01133     
01134     ThroughputMonitorCollection::Stats stats;
01135     tmc.getStats(stats);
01136     
01137     addRowForThroughputStatistics(maker, table, stats.average, true);
01138     
01139     for (ThroughputMonitorCollection::Stats::Snapshots::const_iterator
01140            it = stats.snapshots.begin(),
01141            itEnd = stats.snapshots.end();
01142          it != itEnd;
01143          ++it)
01144     {
01145       addRowForThroughputStatistics(maker, table, (*it));
01146     }
01147     
01148     addRowForThroughputStatistics(maker, table, stats.average, true);
01149   }
01150   
01151   
01152   void SMWebPageHelper::addRowForThroughputStatistics
01153   (
01154     XHTMLMaker& maker,
01155     XHTMLMaker::Node* table,
01156     const ThroughputMonitorCollection::Stats::Snapshot& snapshot,
01157     const bool isAverage
01158   ) const
01159   {
01160     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01161     XHTMLMaker::Node* tableDiv;
01162     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
01163     
01164     if (isAverage)
01165     {
01166       tableValueAttr[ "style" ] = "background-color: yellow;";
01167       tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01168       std::ostringstream avg;
01169       avg << "<" << snapshot.duration.total_seconds() << "s>";
01170       maker.addText(tableDiv, avg.str());
01171     }
01172     else
01173     {
01174       tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01175       maker.addText( tableDiv, utils::timeStampUTC(snapshot.absoluteTime) );
01176     }
01177     
01178     // memory pool usage
01179     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01180     maker.addDouble( tableDiv, snapshot.poolUsage, 0 );
01181     
01182     // number of fragments in fragment queue
01183     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01184     maker.addDouble( tableDiv, snapshot.entriesInFragmentQueue, 0 );
01185     
01186     // memory used in fragment queue
01187     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01188     maker.addDouble( tableDiv, snapshot.memoryUsedInFragmentQueue, 1 );
01189     
01190     // number of fragments popped from fragment queue
01191     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01192     maker.addDouble( tableDiv, snapshot.fragmentQueueRate, 0 );
01193     
01194     // data rate popped from fragment queue
01195     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01196     maker.addDouble( tableDiv, snapshot.fragmentQueueBandwidth, 1 );
01197     
01198     // fragment processor thread busy percentage
01199     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01200     maker.addDouble( tableDiv, snapshot.fragmentProcessorBusy, 1 );
01201     
01202     // number of events in fragment store
01203     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01204     maker.addDouble( tableDiv, snapshot.fragmentStoreSize, 0 );
01205     
01206     // memory used in fragment store
01207     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01208     maker.addDouble( tableDiv, snapshot.fragmentStoreMemoryUsed, 1 );
01209     
01210     // number of events in stream queue
01211     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01212     maker.addDouble( tableDiv, snapshot.entriesInStreamQueue, 0 );
01213     
01214     // memory used in stream queue
01215     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01216     maker.addDouble( tableDiv, snapshot.memoryUsedInStreamQueue, 1 );
01217     
01218     // number of events popped from stream queue
01219     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01220     maker.addDouble( tableDiv, snapshot.streamQueueRate, 0 );
01221     
01222     // data rate popped from stream queue
01223     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01224     maker.addDouble( tableDiv, snapshot.streamQueueBandwidth, 1 );
01225   
01226     // disk writer thread busy percentage
01227     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01228     maker.addDouble( tableDiv, snapshot.diskWriterBusy, 1 );
01229   
01230     // number of events written to disk
01231     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01232     maker.addDouble( tableDiv, snapshot.writtenEventsRate, 0 );
01233     
01234     // date rate written to disk
01235     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01236     maker.addDouble( tableDiv, snapshot.writtenEventsBandwidth, 1 );
01237     
01238     // number of dqm events in DQMEvent queue
01239     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01240     maker.addDouble( tableDiv, snapshot.entriesInDQMQueue, 0 );
01241     
01242     // memory used in DQMEvent queue
01243     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01244     maker.addDouble( tableDiv, snapshot.memoryUsedInDQMQueue, 1 );
01245     
01246     // number of dqm events popped from DQMEvent queue
01247     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01248     maker.addDouble( tableDiv, snapshot.dqmQueueRate, 0 );
01249     
01250     // data rate popped from DQMEvent queue
01251     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01252     maker.addDouble( tableDiv, snapshot.dqmQueueBandwidth, 1 );
01253     
01254     // DQMEvent processor thread busy percentage
01255     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01256     maker.addDouble( tableDiv, snapshot.dqmEventProcessorBusy, 1 );
01257   }
01258   
01259   
01260   void SMWebPageHelper::addOutputModuleTables
01261   (
01262     XHTMLMaker& maker,
01263     XHTMLMaker::Node *parent,
01264     DataSenderMonitorCollection const& dsmc
01265   ) const
01266   {
01267     DataSenderMonitorCollection::OutputModuleResultsList resultsList =
01268       dsmc.getTopLevelOutputModuleResults();
01269     
01270     addOutputModuleSummary(maker, parent, resultsList);
01271     addOutputModuleStatistics(maker, parent, resultsList);
01272   }
01273   
01274   
01275   void SMWebPageHelper::addOutputModuleStatistics
01276   (
01277     XHTMLMaker& maker,
01278     XHTMLMaker::Node *parent,
01279     long long uniqueRBID,
01280     DataSenderMonitorCollection const& dsmc
01281   ) const
01282   {
01283     DataSenderMonitorCollection::OutputModuleResultsList resultsList =
01284       dsmc.getOutputModuleResultsForRB(uniqueRBID);
01285     
01286     addOutputModuleStatistics(maker, parent, resultsList);
01287   }
01288   
01289   
01290   void SMWebPageHelper::addOutputModuleStatistics
01291   (
01292     XHTMLMaker& maker,
01293     XHTMLMaker::Node *parent,
01294     DataSenderMonitorCollection::OutputModuleResultsList const& resultsList
01295   ) const
01296   {
01297     XHTMLMaker::AttrMap colspanAttr;
01298     colspanAttr[ "colspan" ] = "7";
01299     
01300     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01301     
01302     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01303     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01304     maker.addText(tableDiv, "Received Data Statistics (by output module)");
01305     
01306     // Header
01307     tableRow = maker.addNode("tr", table, specialRowAttr_);
01308     tableDiv = maker.addNode("th", tableRow);
01309     maker.addText(tableDiv, "Output Module");
01310     tableDiv = maker.addNode("th", tableRow);
01311     maker.addText(tableDiv, "Events");
01312     tableDiv = maker.addNode("th", tableRow);
01313     maker.addText(tableDiv, "Size (MB)");
01314     tableDiv = maker.addNode("th", tableRow);
01315     maker.addText(tableDiv, "Size/Evt (KB)");
01316     tableDiv = maker.addNode("th", tableRow);
01317     maker.addText(tableDiv, "RMS (KB)");
01318     tableDiv = maker.addNode("th", tableRow);
01319     maker.addText(tableDiv, "Min (KB)");
01320     tableDiv = maker.addNode("th", tableRow);
01321     maker.addText(tableDiv, "Max (KB)");
01322     
01323     if (resultsList.empty())
01324     {
01325       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01326       messageAttr[ "align" ] = "center";
01327       
01328       tableRow = maker.addNode("tr", table, rowAttr_);
01329       tableDiv = maker.addNode("td", tableRow, messageAttr);
01330       maker.addText(tableDiv, "No output modules are available yet.");
01331       return;
01332     }
01333     else
01334     {
01335       for (unsigned int idx = 0; idx < resultsList.size(); ++idx)
01336       {
01337         std::string outputModuleLabel = resultsList[idx]->name;
01338         
01339         tableRow = maker.addNode("tr", table, rowAttr_);
01340         tableDiv = maker.addNode("td", tableRow);
01341         maker.addText(tableDiv, outputModuleLabel);
01342         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01343         maker.addInt( tableDiv, resultsList[idx]->eventStats.getSampleCount() );
01344         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01345         maker.addDouble( tableDiv,
01346           resultsList[idx]->eventStats.getValueSum()/(double)0x100000 );
01347         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01348         maker.addDouble( tableDiv,
01349           resultsList[idx]->eventStats.getValueAverage()/(double)0x400 );
01350         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01351         maker.addDouble( tableDiv,
01352           resultsList[idx]->eventStats.getValueRMS()/(double)0x400 );
01353         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01354         maker.addDouble( tableDiv,
01355           resultsList[idx]->eventStats.getValueMin()/(double)0x400 );
01356         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01357         maker.addDouble( tableDiv,
01358           resultsList[idx]->eventStats.getValueMax()/(double)0x400 );
01359       }
01360     }
01361   }
01362   
01363   
01364   void SMWebPageHelper::addOutputModuleSummary
01365   (
01366     XHTMLMaker& maker,
01367     XHTMLMaker::Node *parent,
01368     DataSenderMonitorCollection::OutputModuleResultsList const& resultsList
01369   ) const
01370   {
01371     XHTMLMaker::AttrMap colspanAttr;
01372     colspanAttr[ "colspan" ] = "3";
01373     
01374     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01375     
01376     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01377     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01378     maker.addText(tableDiv, "Output Module Summary");
01379     
01380     // Header
01381     tableRow = maker.addNode("tr", table, specialRowAttr_);
01382     tableDiv = maker.addNode("th", tableRow);
01383     maker.addText(tableDiv, "Name");
01384     tableDiv = maker.addNode("th", tableRow);
01385     maker.addText(tableDiv, "ID");
01386     tableDiv = maker.addNode("th", tableRow);
01387     maker.addText(tableDiv, "Header Size (bytes)");
01388     
01389     if (resultsList.empty())
01390     {
01391       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01392       messageAttr[ "align" ] = "center";
01393       
01394       tableRow = maker.addNode("tr", table, rowAttr_);
01395       tableDiv = maker.addNode("td", tableRow, messageAttr);
01396       maker.addText(tableDiv, "No output modules are available yet.");
01397       return;
01398     }
01399     else
01400     {
01401       for (unsigned int idx = 0; idx < resultsList.size(); ++idx)
01402       {
01403         tableRow = maker.addNode("tr", table, rowAttr_);
01404         tableDiv = maker.addNode("td", tableRow);
01405         maker.addText(tableDiv, resultsList[idx]->name);
01406         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01407         maker.addInt( tableDiv, resultsList[idx]->id );
01408         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01409         maker.addInt( tableDiv, resultsList[idx]->initMsgSize );
01410       }
01411     }
01412   }
01413   
01414   
01415   void SMWebPageHelper::addResourceBrokerList
01416   (
01417     XHTMLMaker& maker,
01418     XHTMLMaker::Node *parent,
01419     DataSenderMonitorCollection const& dsmc
01420   ) const
01421   {
01422     DataSenderMonitorCollection::ResourceBrokerResultsList rbResultsList =
01423       dsmc.getAllResourceBrokerResults();
01424     std::sort(rbResultsList.begin(), rbResultsList.end(), compareRBResultPtrValues);
01425     
01426     XHTMLMaker::AttrMap colspanAttr;
01427     colspanAttr[ "colspan" ] = "15";
01428     
01429     XHTMLMaker::AttrMap tableSuspiciousValueAttr = tableValueAttr_;
01430     tableSuspiciousValueAttr[ "style" ] = "background-color: yellow;";
01431     
01432     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01433     
01434     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01435     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01436     maker.addText(tableDiv, "Data Sender Overview");
01437     
01438     // Header
01439     tableRow = maker.addNode("tr", table, specialRowAttr_);
01440     tableDiv = maker.addNode("th", tableRow);
01441     maker.addText(tableDiv, "Resource Broker URL");
01442     tableDiv = maker.addNode("th", tableRow);
01443     maker.addText(tableDiv, "RB instance");
01444     tableDiv = maker.addNode("th", tableRow);
01445     maker.addText(tableDiv, "RB TID");
01446     tableDiv = maker.addNode("th", tableRow);
01447     maker.addText(tableDiv, "# of FUs");
01448     tableDiv = maker.addNode("th", tableRow);
01449     maker.addText(tableDiv, "# of INIT messages");
01450     tableDiv = maker.addNode("th", tableRow);
01451     maker.addText(tableDiv, "# of events");
01452     tableDiv = maker.addNode("th", tableRow);
01453     maker.addText(tableDiv, "# of error events");
01454     tableDiv = maker.addNode("th", tableRow);
01455     maker.addText(tableDiv, "# of faulty events");
01456     tableDiv = maker.addNode("th", tableRow);
01457     maker.addText(tableDiv, "# of outstanding data discards");
01458     tableDiv = maker.addNode("th", tableRow);
01459     maker.addText(tableDiv, "# of DQM events");
01460     tableDiv = maker.addNode("th", tableRow);
01461     maker.addText(tableDiv, "# of faulty DQM events");
01462     tableDiv = maker.addNode("th", tableRow);
01463     maker.addText(tableDiv, "# of outstanding DQM discards");
01464     tableDiv = maker.addNode("th", tableRow);
01465     maker.addText(tableDiv, "# of ignored discards");
01466     tableDiv = maker.addNode("th", tableRow);
01467     maker.addText(tableDiv, "Recent event rate (Hz)");
01468     tableDiv = maker.addNode("th", tableRow);
01469     maker.addText(tableDiv, "Last event number received");
01470     
01471     if (rbResultsList.empty())
01472     {
01473       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01474       messageAttr[ "align" ] = "center";
01475       
01476       tableRow = maker.addNode("tr", table, rowAttr_);
01477       tableDiv = maker.addNode("td", tableRow, messageAttr);
01478       maker.addText(tableDiv, "No data senders have registered yet.");
01479       return;
01480     }
01481     else
01482     {
01483       for (unsigned int idx = 0; idx < rbResultsList.size(); ++idx)
01484       {
01485         tableRow = maker.addNode("tr", table, rowAttr_);
01486         
01487         tableDiv = maker.addNode("td", tableRow);
01488         XHTMLMaker::AttrMap linkAttr;
01489         linkAttr[ "href" ] = baseURL() + "/rbsenderdetail?id=" +
01490           boost::lexical_cast<std::string>(rbResultsList[idx]->uniqueRBID);
01491         XHTMLMaker::Node* link = maker.addNode("a", tableDiv, linkAttr);
01492         maker.addText(link, rbResultsList[idx]->key.hltURL);
01493         
01494         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01495         maker.addInt( tableDiv, rbResultsList[idx]->key.hltInstance );
01496         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01497         maker.addInt( tableDiv, rbResultsList[idx]->key.hltTid );
01498         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01499         maker.addInt( tableDiv, rbResultsList[idx]->filterUnitCount );
01500         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01501         maker.addInt(tableDiv, rbResultsList[idx]->initMsgCount );
01502         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01503         maker.addInt( tableDiv, rbResultsList[idx]->eventStats.getSampleCount() );
01504         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01505         maker.addInt( tableDiv, rbResultsList[idx]->errorEventStats.getSampleCount() );
01506         
01507         if (rbResultsList[idx]->faultyEventStats.getSampleCount() != 0)
01508         {
01509           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01510         }
01511         else
01512         {
01513           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01514         }
01515         maker.addInt( tableDiv, rbResultsList[idx]->faultyEventStats.getSampleCount() );
01516         
01517         if (rbResultsList[idx]->outstandingDataDiscardCount != 0)
01518         {
01519           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01520         }
01521         else
01522         {
01523           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01524         }
01525         maker.addInt( tableDiv, rbResultsList[idx]->outstandingDataDiscardCount );
01526         
01527         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01528         maker.addInt( tableDiv, rbResultsList[idx]->dqmEventStats.getSampleCount() );
01529         
01530         if (rbResultsList[idx]->faultyDQMEventStats.getSampleCount() != 0)
01531         {
01532           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01533         }
01534         else
01535         {
01536           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01537         }
01538         maker.addInt( tableDiv, rbResultsList[idx]->faultyDQMEventStats.getSampleCount() );
01539         
01540         if (rbResultsList[idx]->outstandingDQMDiscardCount != 0)
01541         {
01542           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01543         }
01544         else
01545         {
01546           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01547         }
01548         maker.addInt( tableDiv, rbResultsList[idx]->outstandingDQMDiscardCount );
01549         
01550         const int skippedDiscards = rbResultsList[idx]->skippedDiscardStats.getSampleCount();
01551         if (skippedDiscards != 0)
01552         {
01553           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01554         }
01555         else
01556         {
01557           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01558         }
01559         maker.addInt( tableDiv, skippedDiscards );
01560         
01561         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01562         maker.addDouble( tableDiv, rbResultsList[idx]->eventStats.
01563           getSampleRate(MonitoredQuantity::RECENT) );
01564         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01565         maker.addInt( tableDiv, rbResultsList[idx]->lastEventNumber );
01566       }
01567     }
01568   }
01569   
01570 
01571   void SMWebPageHelper::addResourceBrokerDetails
01572   (
01573     XHTMLMaker& maker,
01574     XHTMLMaker::Node *parent,
01575     long long uniqueRBID,
01576     DataSenderMonitorCollection const& dsmc
01577   ) const
01578   {
01579     DataSenderMonitorCollection::RBResultPtr rbResultPtr =
01580       dsmc.getOneResourceBrokerResult(uniqueRBID);
01581     
01582     if (rbResultPtr.get() == 0)
01583     {
01584       maker.addText(parent, "The requested resource broker page is not currently available.");
01585       return;
01586     }
01587     
01588     int tmpDuration;
01589     std::string tmpText;
01590     
01591     XHTMLMaker::AttrMap colspanAttr;
01592     colspanAttr[ "colspan" ] = "2";
01593     
01594     XHTMLMaker::AttrMap tableAttr = tableAttr_;
01595     tableAttr[ "width" ] = "";
01596     
01597     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr);
01598     
01599     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01600     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01601     maker.addText(tableDiv, "Resource Broker Details");
01602     
01603     // Header
01604     tableRow = maker.addNode("tr", table, specialRowAttr_);
01605     tableDiv = maker.addNode("th", tableRow);
01606     maker.addText(tableDiv, "Parameter");
01607     tableDiv = maker.addNode("th", tableRow);
01608     maker.addText(tableDiv, "Value");
01609     
01610     tableRow = maker.addNode("tr", table, rowAttr_);
01611     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01612     maker.addText(tableDiv, "URL");
01613     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01614     XHTMLMaker::AttrMap linkAttr;
01615     linkAttr[ "href" ] = rbResultPtr->key.hltURL + "/urn:xdaq-application:lid=" +
01616       boost::lexical_cast<std::string>(rbResultPtr->key.hltLocalId);
01617     XHTMLMaker::Node* link = maker.addNode("a", tableDiv, linkAttr);
01618     maker.addText(link, rbResultPtr->key.hltURL);
01619     
01620     tableRow = maker.addNode("tr", table, rowAttr_);
01621     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01622     maker.addText(tableDiv, "Class Name");
01623     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01624     maker.addText(tableDiv, rbResultPtr->key.hltClassName);
01625     
01626     tableRow = maker.addNode("tr", table, rowAttr_);
01627     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01628     maker.addText(tableDiv, "Instance");
01629     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01630     maker.addInt( tableDiv, rbResultPtr->key.hltInstance );
01631     
01632     tableRow = maker.addNode("tr", table, rowAttr_);
01633     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01634     maker.addText(tableDiv, "Local ID");
01635     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01636     maker.addInt( tableDiv, rbResultPtr->key.hltLocalId );
01637     
01638     tableRow = maker.addNode("tr", table, rowAttr_);
01639     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01640     maker.addText(tableDiv, "Tid");
01641     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01642     maker.addInt( tableDiv, rbResultPtr->key.hltTid );
01643     
01644     tableRow = maker.addNode("tr", table, rowAttr_);
01645     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01646     maker.addText(tableDiv, "INIT Message Count");
01647     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01648     maker.addInt( tableDiv, rbResultPtr->initMsgCount );
01649     
01650     tableRow = maker.addNode("tr", table, rowAttr_);
01651     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01652     maker.addText(tableDiv, "Event Count");
01653     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01654     maker.addInt( tableDiv, rbResultPtr->eventStats.getSampleCount() );
01655     
01656     tableRow = maker.addNode("tr", table, rowAttr_);
01657     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01658     maker.addText(tableDiv, "Error Event Count");
01659     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01660     maker.addInt( tableDiv, rbResultPtr->errorEventStats.getSampleCount() );
01661     
01662     tableRow = maker.addNode("tr", table, rowAttr_);
01663     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01664     maker.addText(tableDiv, "Faulty Event Count");
01665     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01666     maker.addInt( tableDiv, rbResultPtr->faultyEventStats.getSampleCount() );
01667     
01668     tableRow = maker.addNode("tr", table, rowAttr_);
01669     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01670     maker.addText(tableDiv, "Data Discard Count");
01671     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01672     maker.addInt( tableDiv, rbResultPtr->dataDiscardStats.getSampleCount() );
01673     
01674     tableRow = maker.addNode("tr", table, rowAttr_);
01675     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01676     maker.addText(tableDiv, "DQM Event Count");
01677     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01678     maker.addInt( tableDiv, rbResultPtr->dqmEventStats.getSampleCount() );
01679     
01680     tableRow = maker.addNode("tr", table, rowAttr_);
01681     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01682     maker.addText(tableDiv, "Faulty DQM Event Count");
01683     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01684     maker.addInt( tableDiv, rbResultPtr->faultyDQMEventStats.getSampleCount() );
01685     
01686     tableRow = maker.addNode("tr", table, rowAttr_);
01687     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01688     maker.addText(tableDiv, "DQM Discard Count");
01689     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01690     maker.addInt( tableDiv, rbResultPtr->dqmDiscardStats.getSampleCount() );
01691     
01692     tableRow = maker.addNode("tr", table, rowAttr_);
01693     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01694     maker.addText(tableDiv, "Ignored Discards Count");
01695     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01696     maker.addInt( tableDiv, rbResultPtr->skippedDiscardStats.getSampleCount() );
01697     
01698     tableRow = maker.addNode("tr", table, rowAttr_);
01699     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01700     maker.addText(tableDiv, "Last Event Number Received");
01701     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01702     maker.addInt( tableDiv, rbResultPtr->lastEventNumber );
01703     
01704     tableRow = maker.addNode("tr", table, rowAttr_);
01705     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01706     maker.addText(tableDiv, "Last Run Number Received");
01707     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01708     maker.addInt( tableDiv, rbResultPtr->lastRunNumber );
01709     
01710     tableRow = maker.addNode("tr", table, rowAttr_);
01711     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01712     tmpDuration = rbResultPtr->eventStats.recentDuration.total_seconds();
01713     tmpText =  "Recent (" + boost::lexical_cast<std::string>(tmpDuration) +
01714       " sec) Event Rate (Hz)";
01715     maker.addText(tableDiv, tmpText);
01716     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01717     maker.addDouble( tableDiv, rbResultPtr->eventStats.recentSampleRate );
01718     
01719     tableRow = maker.addNode("tr", table, rowAttr_);
01720     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01721     tmpDuration = rbResultPtr->eventStats.fullDuration.total_seconds();
01722     tmpText =  "Full (" + boost::lexical_cast<std::string>(tmpDuration) +
01723       " sec) Event Rate (Hz)";
01724     maker.addText(tableDiv, tmpText);
01725     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01726     maker.addDouble( tableDiv, rbResultPtr->eventStats.fullSampleRate );
01727   }
01728   
01729   
01730   void SMWebPageHelper::addFilterUnitList
01731   (
01732     XHTMLMaker& maker,
01733     XHTMLMaker::Node *parent,
01734     long long uniqueRBID,
01735     DataSenderMonitorCollection const& dsmc
01736   ) const
01737   {
01738     DataSenderMonitorCollection::FilterUnitResultsList fuResultsList =
01739       dsmc.getFilterUnitResultsForRB(uniqueRBID);
01740     
01741     XHTMLMaker::AttrMap colspanAttr;
01742     colspanAttr[ "colspan" ] = "13";
01743     
01744     XHTMLMaker::AttrMap tableSuspiciousValueAttr = tableValueAttr_;
01745     tableSuspiciousValueAttr[ "style" ] = "background-color: yellow;";
01746     
01747     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01748     
01749     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01750     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01751     maker.addText(tableDiv, "Filter Units");
01752     
01753     // Header
01754     tableRow = maker.addNode("tr", table, specialRowAttr_);
01755     tableDiv = maker.addNode("th", tableRow);
01756     maker.addText(tableDiv, "Process ID");
01757     tableDiv = maker.addNode("th", tableRow);
01758     maker.addText(tableDiv, "# of INIT messages");
01759     tableDiv = maker.addNode("th", tableRow);
01760     maker.addText(tableDiv, "# of events");
01761     tableDiv = maker.addNode("th", tableRow);
01762     maker.addText(tableDiv, "# of error events");
01763     tableDiv = maker.addNode("th", tableRow);
01764     maker.addText(tableDiv, "# of faulty events");
01765     tableDiv = maker.addNode("th", tableRow);
01766     maker.addText(tableDiv, "# of outstanding data discards");
01767     tableDiv = maker.addNode("th", tableRow);
01768     maker.addText(tableDiv, "# of DQM events");
01769     tableDiv = maker.addNode("th", tableRow);
01770     maker.addText(tableDiv, "# of faulty DQM events");
01771     tableDiv = maker.addNode("th", tableRow);
01772     maker.addText(tableDiv, "# of outstanding DQM discards");
01773     tableDiv = maker.addNode("th", tableRow);
01774     maker.addText(tableDiv, "# of ignored discards");
01775     tableDiv = maker.addNode("th", tableRow);
01776     maker.addText(tableDiv, "Recent event rate (Hz)");
01777     tableDiv = maker.addNode("th", tableRow);
01778     maker.addText(tableDiv, "Last event number received");
01779     tableDiv = maker.addNode("th", tableRow);
01780     maker.addText(tableDiv, "Last run number received");
01781     
01782     if (fuResultsList.empty())
01783     {
01784       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01785       messageAttr[ "align" ] = "center";
01786       
01787       tableRow = maker.addNode("tr", table, rowAttr_);
01788       tableDiv = maker.addNode("td", tableRow, messageAttr);
01789       maker.addText(tableDiv, "No filter units have registered yet.");
01790       return;
01791     }
01792     else
01793     {
01794       for (unsigned int idx = 0; idx < fuResultsList.size(); ++idx)
01795       {
01796         tableRow = maker.addNode("tr", table, rowAttr_);
01797         
01798         tableDiv = maker.addNode("td", tableRow);
01799         maker.addInt( tableDiv, fuResultsList[idx]->key.fuProcessId );
01800         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01801         maker.addInt( tableDiv, fuResultsList[idx]->initMsgCount );
01802         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01803         maker.addInt( tableDiv, fuResultsList[idx]->shortIntervalEventStats.getSampleCount() );
01804         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01805         maker.addInt( tableDiv, fuResultsList[idx]->errorEventStats.getSampleCount() );
01806         
01807         if (fuResultsList[idx]->faultyEventStats.getSampleCount() != 0)
01808         {
01809           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01810         }
01811         else
01812         {
01813           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01814         }
01815         maker.addInt( tableDiv, fuResultsList[idx]->faultyEventStats.getSampleCount() );
01816         
01817         if (fuResultsList[idx]->outstandingDataDiscardCount != 0)
01818         {
01819           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01820         }
01821         else
01822         {
01823           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01824         }
01825         maker.addInt( tableDiv, fuResultsList[idx]->outstandingDataDiscardCount );
01826         
01827         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01828         maker.addInt( tableDiv, fuResultsList[idx]->dqmEventStats.getSampleCount() );
01829         
01830         if (fuResultsList[idx]->faultyDQMEventStats.getSampleCount() != 0)
01831         {
01832           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01833         }
01834         else
01835         {
01836           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01837         }
01838         maker.addInt( tableDiv, fuResultsList[idx]->faultyDQMEventStats.getSampleCount() );
01839         
01840         if (fuResultsList[idx]->outstandingDQMDiscardCount != 0)
01841         {
01842           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01843         }
01844         else
01845         {
01846           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01847         }
01848         maker.addInt( tableDiv, fuResultsList[idx]->outstandingDQMDiscardCount );
01849         
01850         const int skippedDiscards = fuResultsList[idx]->skippedDiscardStats.getSampleCount();
01851         if (skippedDiscards != 0)
01852         {
01853           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01854         }
01855         else
01856         {
01857           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01858         }
01859         maker.addInt( tableDiv, skippedDiscards );
01860         
01861         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01862         maker.addDouble( tableDiv, fuResultsList[idx]->shortIntervalEventStats.
01863           getSampleRate(MonitoredQuantity::RECENT) );
01864         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01865         maker.addInt( tableDiv, fuResultsList[idx]->lastEventNumber );
01866         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01867         maker.addInt( tableDiv, fuResultsList[idx]->lastRunNumber );
01868       }
01869     }
01870   }
01871  
01872 } // namespace stor
01873  
01874