CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/EventFilter/StorageManager/src/SMWebPageHelper.cc

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