CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 // $Id: SMWebPageHelper.cc,v 1.3 2011/04/14 12:52:48 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: V07-04-00 $", this, &stor::SMWebPageHelper::addDOMforHyperLinks),
00043   sharedResources_(sharedResources),
00044   consumerWebPageHelper_(appDesc, "$Name: V07-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" ] = "5";
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     
01045     // File list
01046     if (fileRecords.empty())
01047     {
01048       tableRow = maker.addNode("tr", table, rowAttr_);
01049       tableDiv = maker.addNode("td", tableRow, colspanAttr);
01050       maker.addText(tableDiv, "no files available yet");
01051       return;
01052     }
01053     
01054     for (
01055       FilesMonitorCollection::FileRecordList::const_reverse_iterator 
01056         it = fileRecords.rbegin(), itEnd = fileRecords.rend();
01057       it != itEnd;
01058       ++it
01059     )
01060     {
01061       tableRow = maker.addNode("tr", table, rowAttr_);
01062       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01063       maker.addInt( tableDiv, (*it)->entryCounter );
01064       tableDiv = maker.addNode("td", tableRow);
01065       maker.addText(tableDiv, (*it)->completeFileName());
01066       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01067       maker.addInt( tableDiv, (*it)->eventCount );
01068       tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01069       maker.addInt( tableDiv, (*it)->fileSize );
01070       tableDiv = maker.addNode("td", tableRow, tableLabelAttr);
01071       maker.addText(tableDiv, (*it)->closingReason());
01072     }
01073   }
01074   
01075   
01076   void SMWebPageHelper::addDOMforThroughputStatistics
01077   (
01078     XHTMLMaker& maker,
01079     XHTMLMaker::Node *parent,
01080     ThroughputMonitorCollection const& tmc
01081   ) const
01082   {
01083     XHTMLMaker::AttrMap colspanAttr;
01084     colspanAttr[ "colspan" ] = "21";
01085     
01086     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01087     
01088     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01089     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01090     maker.addText(tableDiv, "Throughput Statistics");
01091     
01092     // Header
01093     tableRow = maker.addNode("tr", table, specialRowAttr_);
01094     tableDiv = maker.addNode("th", tableRow);
01095     maker.addText(tableDiv, "Time (UTC)");
01096     tableDiv = maker.addNode("th", tableRow);
01097     maker.addText(tableDiv, "Memory pool usage (bytes)");
01098     tableDiv = maker.addNode("th", tableRow);
01099     maker.addText(tableDiv, "Instantaneous Number of Fragments in Fragment Queue");
01100     tableDiv = maker.addNode("th", tableRow);
01101     maker.addText(tableDiv, "Memory used in Fragment Queue (MB)");
01102     tableDiv = maker.addNode("th", tableRow);
01103     maker.addText(tableDiv, "Number of Fragments Popped from Fragment Queue (Hz)");
01104     tableDiv = maker.addNode("th", tableRow);
01105     maker.addText(tableDiv, "Data Rate Popped from Fragment Queue (MB/sec)");
01106     tableDiv = maker.addNode("th", tableRow);
01107     maker.addText(tableDiv, "Fragment Processor Thread Busy Percentage");
01108     tableDiv = maker.addNode("th", tableRow);
01109     maker.addText(tableDiv, "Instantaneous Number of Events in Fragment Store");
01110     tableDiv = maker.addNode("th", tableRow);
01111     maker.addText(tableDiv, "Memory used in Fragment Store (MB)");
01112     tableDiv = maker.addNode("th", tableRow);
01113     maker.addText(tableDiv, "Instantaneous Number of Events in Stream Queue");
01114     tableDiv = maker.addNode("th", tableRow);
01115     maker.addText(tableDiv, "Memory used in Stream Queue (MB)");
01116     tableDiv = maker.addNode("th", tableRow);
01117     maker.addText(tableDiv, "Number of Events Popped from Stream Queue (Hz)");
01118     tableDiv = maker.addNode("th", tableRow);
01119     maker.addText(tableDiv, "Data Rate Popped from Stream Queue (MB/sec)");
01120     tableDiv = maker.addNode("th", tableRow);
01121     maker.addText(tableDiv, "Disk Writer Thread Busy Percentage");
01122     tableDiv = maker.addNode("th", tableRow);
01123     maker.addText(tableDiv, "Number of Events Written to Disk (Hz)");
01124     tableDiv = maker.addNode("th", tableRow);
01125     maker.addText(tableDiv, "Data  Rate to Disk (MB/sec)");
01126     tableDiv = maker.addNode("th", tableRow);
01127     maker.addText(tableDiv, "Instantaneous Number of DQMEvents in DQMEvent Queue");
01128     tableDiv = maker.addNode("th", tableRow);
01129     maker.addText(tableDiv, "Memory used in DQMEvent Queue (MB)");
01130     tableDiv = maker.addNode("th", tableRow);
01131     maker.addText(tableDiv, "Number of DQMEvents Popped from DQMEvent Queue (Hz)");
01132     tableDiv = maker.addNode("th", tableRow);
01133     maker.addText(tableDiv, "Data Rate Popped from DQMEvent Queue (MB/sec)");
01134     tableDiv = maker.addNode("th", tableRow);
01135     maker.addText(tableDiv, "DQMEvent Processor Thread Busy Percentage");
01136     
01137     ThroughputMonitorCollection::Stats stats;
01138     tmc.getStats(stats);
01139     
01140     addRowForThroughputStatistics(maker, table, stats.average, true);
01141     
01142     for (ThroughputMonitorCollection::Stats::Snapshots::const_iterator
01143            it = stats.snapshots.begin(),
01144            itEnd = stats.snapshots.end();
01145          it != itEnd;
01146          ++it)
01147     {
01148       addRowForThroughputStatistics(maker, table, (*it));
01149     }
01150     
01151     addRowForThroughputStatistics(maker, table, stats.average, true);
01152   }
01153   
01154   
01155   void SMWebPageHelper::addRowForThroughputStatistics
01156   (
01157     XHTMLMaker& maker,
01158     XHTMLMaker::Node* table,
01159     const ThroughputMonitorCollection::Stats::Snapshot& snapshot,
01160     const bool isAverage
01161   ) const
01162   {
01163     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01164     XHTMLMaker::Node* tableDiv;
01165     XHTMLMaker::AttrMap tableValueAttr = tableValueAttr_;
01166     
01167     if (isAverage)
01168     {
01169       tableValueAttr[ "style" ] = "background-color: yellow;";
01170       tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01171       std::ostringstream avg;
01172       avg << "<" << snapshot.duration.total_seconds() << "s>";
01173       maker.addText(tableDiv, avg.str());
01174     }
01175     else
01176     {
01177       tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01178       maker.addText( tableDiv, utils::timeStampUTC(snapshot.absoluteTime) );
01179     }
01180     
01181     // memory pool usage
01182     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01183     maker.addDouble( tableDiv, snapshot.poolUsage, 0 );
01184     
01185     // number of fragments in fragment queue
01186     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01187     maker.addDouble( tableDiv, snapshot.entriesInFragmentQueue, 0 );
01188     
01189     // memory used in fragment queue
01190     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01191     maker.addDouble( tableDiv, snapshot.memoryUsedInFragmentQueue, 1 );
01192     
01193     // number of fragments popped from fragment queue
01194     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01195     maker.addDouble( tableDiv, snapshot.fragmentQueueRate, 0 );
01196     
01197     // data rate popped from fragment queue
01198     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01199     maker.addDouble( tableDiv, snapshot.fragmentQueueBandwidth, 1 );
01200     
01201     // fragment processor thread busy percentage
01202     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01203     maker.addDouble( tableDiv, snapshot.fragmentProcessorBusy, 1 );
01204     
01205     // number of events in fragment store
01206     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01207     maker.addDouble( tableDiv, snapshot.fragmentStoreSize, 0 );
01208     
01209     // memory used in fragment store
01210     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01211     maker.addDouble( tableDiv, snapshot.fragmentStoreMemoryUsed, 1 );
01212     
01213     // number of events in stream queue
01214     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01215     maker.addDouble( tableDiv, snapshot.entriesInStreamQueue, 0 );
01216     
01217     // memory used in stream queue
01218     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01219     maker.addDouble( tableDiv, snapshot.memoryUsedInStreamQueue, 1 );
01220     
01221     // number of events popped from stream queue
01222     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01223     maker.addDouble( tableDiv, snapshot.streamQueueRate, 0 );
01224     
01225     // data rate popped from stream queue
01226     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01227     maker.addDouble( tableDiv, snapshot.streamQueueBandwidth, 1 );
01228   
01229     // disk writer thread busy percentage
01230     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01231     maker.addDouble( tableDiv, snapshot.diskWriterBusy, 1 );
01232   
01233     // number of events written to disk
01234     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01235     maker.addDouble( tableDiv, snapshot.writtenEventsRate, 0 );
01236     
01237     // date rate written to disk
01238     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01239     maker.addDouble( tableDiv, snapshot.writtenEventsBandwidth, 1 );
01240     
01241     // number of dqm events in DQMEvent queue
01242     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01243     maker.addDouble( tableDiv, snapshot.entriesInDQMQueue, 0 );
01244     
01245     // memory used in DQMEvent queue
01246     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01247     maker.addDouble( tableDiv, snapshot.memoryUsedInDQMQueue, 1 );
01248     
01249     // number of dqm events popped from DQMEvent queue
01250     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01251     maker.addDouble( tableDiv, snapshot.dqmQueueRate, 0 );
01252     
01253     // data rate popped from DQMEvent queue
01254     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01255     maker.addDouble( tableDiv, snapshot.dqmQueueBandwidth, 1 );
01256     
01257     // DQMEvent processor thread busy percentage
01258     tableDiv = maker.addNode("td", tableRow, tableValueAttr);
01259     maker.addDouble( tableDiv, snapshot.dqmEventProcessorBusy, 1 );
01260   }
01261   
01262   
01263   void SMWebPageHelper::addOutputModuleTables
01264   (
01265     XHTMLMaker& maker,
01266     XHTMLMaker::Node *parent,
01267     DataSenderMonitorCollection const& dsmc
01268   ) const
01269   {
01270     DataSenderMonitorCollection::OutputModuleResultsList resultsList =
01271       dsmc.getTopLevelOutputModuleResults();
01272     
01273     addOutputModuleSummary(maker, parent, resultsList);
01274     addOutputModuleStatistics(maker, parent, resultsList);
01275   }
01276   
01277   
01278   void SMWebPageHelper::addOutputModuleStatistics
01279   (
01280     XHTMLMaker& maker,
01281     XHTMLMaker::Node *parent,
01282     long long uniqueRBID,
01283     DataSenderMonitorCollection const& dsmc
01284   ) const
01285   {
01286     DataSenderMonitorCollection::OutputModuleResultsList resultsList =
01287       dsmc.getOutputModuleResultsForRB(uniqueRBID);
01288     
01289     addOutputModuleStatistics(maker, parent, resultsList);
01290   }
01291   
01292   
01293   void SMWebPageHelper::addOutputModuleStatistics
01294   (
01295     XHTMLMaker& maker,
01296     XHTMLMaker::Node *parent,
01297     DataSenderMonitorCollection::OutputModuleResultsList const& resultsList
01298   ) const
01299   {
01300     XHTMLMaker::AttrMap colspanAttr;
01301     colspanAttr[ "colspan" ] = "7";
01302     
01303     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01304     
01305     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01306     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01307     maker.addText(tableDiv, "Received Data Statistics (by output module)");
01308     
01309     // Header
01310     tableRow = maker.addNode("tr", table, specialRowAttr_);
01311     tableDiv = maker.addNode("th", tableRow);
01312     maker.addText(tableDiv, "Output Module");
01313     tableDiv = maker.addNode("th", tableRow);
01314     maker.addText(tableDiv, "Events");
01315     tableDiv = maker.addNode("th", tableRow);
01316     maker.addText(tableDiv, "Size (MB)");
01317     tableDiv = maker.addNode("th", tableRow);
01318     maker.addText(tableDiv, "Size/Evt (KB)");
01319     tableDiv = maker.addNode("th", tableRow);
01320     maker.addText(tableDiv, "RMS (KB)");
01321     tableDiv = maker.addNode("th", tableRow);
01322     maker.addText(tableDiv, "Min (KB)");
01323     tableDiv = maker.addNode("th", tableRow);
01324     maker.addText(tableDiv, "Max (KB)");
01325     
01326     if (resultsList.empty())
01327     {
01328       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01329       messageAttr[ "align" ] = "center";
01330       
01331       tableRow = maker.addNode("tr", table, rowAttr_);
01332       tableDiv = maker.addNode("td", tableRow, messageAttr);
01333       maker.addText(tableDiv, "No output modules are available yet.");
01334       return;
01335     }
01336     else
01337     {
01338       for (unsigned int idx = 0; idx < resultsList.size(); ++idx)
01339       {
01340         std::string outputModuleLabel = resultsList[idx]->name;
01341         
01342         tableRow = maker.addNode("tr", table, rowAttr_);
01343         tableDiv = maker.addNode("td", tableRow);
01344         maker.addText(tableDiv, outputModuleLabel);
01345         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01346         maker.addInt( tableDiv, resultsList[idx]->eventStats.getSampleCount() );
01347         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01348         maker.addDouble( tableDiv,
01349           resultsList[idx]->eventStats.getValueSum()/(double)0x100000 );
01350         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01351         maker.addDouble( tableDiv,
01352           resultsList[idx]->eventStats.getValueAverage()/(double)0x400 );
01353         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01354         maker.addDouble( tableDiv,
01355           resultsList[idx]->eventStats.getValueRMS()/(double)0x400 );
01356         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01357         maker.addDouble( tableDiv,
01358           resultsList[idx]->eventStats.getValueMin()/(double)0x400 );
01359         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01360         maker.addDouble( tableDiv,
01361           resultsList[idx]->eventStats.getValueMax()/(double)0x400 );
01362       }
01363     }
01364   }
01365   
01366   
01367   void SMWebPageHelper::addOutputModuleSummary
01368   (
01369     XHTMLMaker& maker,
01370     XHTMLMaker::Node *parent,
01371     DataSenderMonitorCollection::OutputModuleResultsList const& resultsList
01372   ) const
01373   {
01374     XHTMLMaker::AttrMap colspanAttr;
01375     colspanAttr[ "colspan" ] = "3";
01376     
01377     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01378     
01379     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01380     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01381     maker.addText(tableDiv, "Output Module Summary");
01382     
01383     // Header
01384     tableRow = maker.addNode("tr", table, specialRowAttr_);
01385     tableDiv = maker.addNode("th", tableRow);
01386     maker.addText(tableDiv, "Name");
01387     tableDiv = maker.addNode("th", tableRow);
01388     maker.addText(tableDiv, "ID");
01389     tableDiv = maker.addNode("th", tableRow);
01390     maker.addText(tableDiv, "Header Size (bytes)");
01391     
01392     if (resultsList.empty())
01393     {
01394       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01395       messageAttr[ "align" ] = "center";
01396       
01397       tableRow = maker.addNode("tr", table, rowAttr_);
01398       tableDiv = maker.addNode("td", tableRow, messageAttr);
01399       maker.addText(tableDiv, "No output modules are available yet.");
01400       return;
01401     }
01402     else
01403     {
01404       for (unsigned int idx = 0; idx < resultsList.size(); ++idx)
01405       {
01406         tableRow = maker.addNode("tr", table, rowAttr_);
01407         tableDiv = maker.addNode("td", tableRow);
01408         maker.addText(tableDiv, resultsList[idx]->name);
01409         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01410         maker.addInt( tableDiv, resultsList[idx]->id );
01411         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01412         maker.addInt( tableDiv, resultsList[idx]->initMsgSize );
01413       }
01414     }
01415   }
01416   
01417   
01418   void SMWebPageHelper::addResourceBrokerList
01419   (
01420     XHTMLMaker& maker,
01421     XHTMLMaker::Node *parent,
01422     DataSenderMonitorCollection const& dsmc
01423   ) const
01424   {
01425     DataSenderMonitorCollection::ResourceBrokerResultsList rbResultsList =
01426       dsmc.getAllResourceBrokerResults();
01427     std::sort(rbResultsList.begin(), rbResultsList.end(), compareRBResultPtrValues);
01428     
01429     XHTMLMaker::AttrMap colspanAttr;
01430     colspanAttr[ "colspan" ] = "15";
01431     
01432     XHTMLMaker::AttrMap tableSuspiciousValueAttr = tableValueAttr_;
01433     tableSuspiciousValueAttr[ "style" ] = "background-color: yellow;";
01434     
01435     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01436     
01437     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01438     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01439     maker.addText(tableDiv, "Data Sender Overview");
01440     
01441     // Header
01442     tableRow = maker.addNode("tr", table, specialRowAttr_);
01443     tableDiv = maker.addNode("th", tableRow);
01444     maker.addText(tableDiv, "Resource Broker URL");
01445     tableDiv = maker.addNode("th", tableRow);
01446     maker.addText(tableDiv, "RB instance");
01447     tableDiv = maker.addNode("th", tableRow);
01448     maker.addText(tableDiv, "RB TID");
01449     tableDiv = maker.addNode("th", tableRow);
01450     maker.addText(tableDiv, "# of FUs");
01451     tableDiv = maker.addNode("th", tableRow);
01452     maker.addText(tableDiv, "# of INIT messages");
01453     tableDiv = maker.addNode("th", tableRow);
01454     maker.addText(tableDiv, "# of events");
01455     tableDiv = maker.addNode("th", tableRow);
01456     maker.addText(tableDiv, "# of error events");
01457     tableDiv = maker.addNode("th", tableRow);
01458     maker.addText(tableDiv, "# of faulty events");
01459     tableDiv = maker.addNode("th", tableRow);
01460     maker.addText(tableDiv, "# of outstanding data discards");
01461     tableDiv = maker.addNode("th", tableRow);
01462     maker.addText(tableDiv, "# of DQM events");
01463     tableDiv = maker.addNode("th", tableRow);
01464     maker.addText(tableDiv, "# of faulty DQM events");
01465     tableDiv = maker.addNode("th", tableRow);
01466     maker.addText(tableDiv, "# of outstanding DQM discards");
01467     tableDiv = maker.addNode("th", tableRow);
01468     maker.addText(tableDiv, "# of ignored discards");
01469     tableDiv = maker.addNode("th", tableRow);
01470     maker.addText(tableDiv, "Recent event rate (Hz)");
01471     tableDiv = maker.addNode("th", tableRow);
01472     maker.addText(tableDiv, "Last event number received");
01473     
01474     if (rbResultsList.empty())
01475     {
01476       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01477       messageAttr[ "align" ] = "center";
01478       
01479       tableRow = maker.addNode("tr", table, rowAttr_);
01480       tableDiv = maker.addNode("td", tableRow, messageAttr);
01481       maker.addText(tableDiv, "No data senders have registered yet.");
01482       return;
01483     }
01484     else
01485     {
01486       for (unsigned int idx = 0; idx < rbResultsList.size(); ++idx)
01487       {
01488         tableRow = maker.addNode("tr", table, rowAttr_);
01489         
01490         tableDiv = maker.addNode("td", tableRow);
01491         XHTMLMaker::AttrMap linkAttr;
01492         linkAttr[ "href" ] = baseURL() + "/rbsenderdetail?id=" +
01493           boost::lexical_cast<std::string>(rbResultsList[idx]->uniqueRBID);
01494         XHTMLMaker::Node* link = maker.addNode("a", tableDiv, linkAttr);
01495         maker.addText(link, rbResultsList[idx]->key.hltURL);
01496         
01497         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01498         maker.addInt( tableDiv, rbResultsList[idx]->key.hltInstance );
01499         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01500         maker.addInt( tableDiv, rbResultsList[idx]->key.hltTid );
01501         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01502         maker.addInt( tableDiv, rbResultsList[idx]->filterUnitCount );
01503         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01504         maker.addInt(tableDiv, rbResultsList[idx]->initMsgCount );
01505         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01506         maker.addInt( tableDiv, rbResultsList[idx]->eventStats.getSampleCount() );
01507         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01508         maker.addInt( tableDiv, rbResultsList[idx]->errorEventStats.getSampleCount() );
01509         
01510         if (rbResultsList[idx]->faultyEventStats.getSampleCount() != 0)
01511         {
01512           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01513         }
01514         else
01515         {
01516           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01517         }
01518         maker.addInt( tableDiv, rbResultsList[idx]->faultyEventStats.getSampleCount() );
01519         
01520         if (rbResultsList[idx]->outstandingDataDiscardCount != 0)
01521         {
01522           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01523         }
01524         else
01525         {
01526           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01527         }
01528         maker.addInt( tableDiv, rbResultsList[idx]->outstandingDataDiscardCount );
01529         
01530         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01531         maker.addInt( tableDiv, rbResultsList[idx]->dqmEventStats.getSampleCount() );
01532         
01533         if (rbResultsList[idx]->faultyDQMEventStats.getSampleCount() != 0)
01534         {
01535           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01536         }
01537         else
01538         {
01539           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01540         }
01541         maker.addInt( tableDiv, rbResultsList[idx]->faultyDQMEventStats.getSampleCount() );
01542         
01543         if (rbResultsList[idx]->outstandingDQMDiscardCount != 0)
01544         {
01545           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01546         }
01547         else
01548         {
01549           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01550         }
01551         maker.addInt( tableDiv, rbResultsList[idx]->outstandingDQMDiscardCount );
01552         
01553         const int skippedDiscards = rbResultsList[idx]->skippedDiscardStats.getSampleCount();
01554         if (skippedDiscards != 0)
01555         {
01556           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01557         }
01558         else
01559         {
01560           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01561         }
01562         maker.addInt( tableDiv, skippedDiscards );
01563         
01564         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01565         maker.addDouble( tableDiv, rbResultsList[idx]->eventStats.
01566           getSampleRate(MonitoredQuantity::RECENT) );
01567         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01568         maker.addInt( tableDiv, rbResultsList[idx]->lastEventNumber );
01569       }
01570     }
01571   }
01572   
01573 
01574   void SMWebPageHelper::addResourceBrokerDetails
01575   (
01576     XHTMLMaker& maker,
01577     XHTMLMaker::Node *parent,
01578     long long uniqueRBID,
01579     DataSenderMonitorCollection const& dsmc
01580   ) const
01581   {
01582     DataSenderMonitorCollection::RBResultPtr rbResultPtr =
01583       dsmc.getOneResourceBrokerResult(uniqueRBID);
01584     
01585     if (rbResultPtr.get() == 0)
01586     {
01587       maker.addText(parent, "The requested resource broker page is not currently available.");
01588       return;
01589     }
01590     
01591     int tmpDuration;
01592     std::string tmpText;
01593     
01594     XHTMLMaker::AttrMap colspanAttr;
01595     colspanAttr[ "colspan" ] = "2";
01596     
01597     XHTMLMaker::AttrMap tableAttr = tableAttr_;
01598     tableAttr[ "width" ] = "";
01599     
01600     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr);
01601     
01602     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01603     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01604     maker.addText(tableDiv, "Resource Broker Details");
01605     
01606     // Header
01607     tableRow = maker.addNode("tr", table, specialRowAttr_);
01608     tableDiv = maker.addNode("th", tableRow);
01609     maker.addText(tableDiv, "Parameter");
01610     tableDiv = maker.addNode("th", tableRow);
01611     maker.addText(tableDiv, "Value");
01612     
01613     tableRow = maker.addNode("tr", table, rowAttr_);
01614     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01615     maker.addText(tableDiv, "URL");
01616     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01617     XHTMLMaker::AttrMap linkAttr;
01618     linkAttr[ "href" ] = rbResultPtr->key.hltURL + "/urn:xdaq-application:lid=" +
01619       boost::lexical_cast<std::string>(rbResultPtr->key.hltLocalId);
01620     XHTMLMaker::Node* link = maker.addNode("a", tableDiv, linkAttr);
01621     maker.addText(link, rbResultPtr->key.hltURL);
01622     
01623     tableRow = maker.addNode("tr", table, rowAttr_);
01624     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01625     maker.addText(tableDiv, "Class Name");
01626     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01627     maker.addText(tableDiv, rbResultPtr->key.hltClassName);
01628     
01629     tableRow = maker.addNode("tr", table, rowAttr_);
01630     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01631     maker.addText(tableDiv, "Instance");
01632     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01633     maker.addInt( tableDiv, rbResultPtr->key.hltInstance );
01634     
01635     tableRow = maker.addNode("tr", table, rowAttr_);
01636     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01637     maker.addText(tableDiv, "Local ID");
01638     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01639     maker.addInt( tableDiv, rbResultPtr->key.hltLocalId );
01640     
01641     tableRow = maker.addNode("tr", table, rowAttr_);
01642     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01643     maker.addText(tableDiv, "Tid");
01644     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01645     maker.addInt( tableDiv, rbResultPtr->key.hltTid );
01646     
01647     tableRow = maker.addNode("tr", table, rowAttr_);
01648     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01649     maker.addText(tableDiv, "INIT Message Count");
01650     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01651     maker.addInt( tableDiv, rbResultPtr->initMsgCount );
01652     
01653     tableRow = maker.addNode("tr", table, rowAttr_);
01654     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01655     maker.addText(tableDiv, "Event Count");
01656     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01657     maker.addInt( tableDiv, rbResultPtr->eventStats.getSampleCount() );
01658     
01659     tableRow = maker.addNode("tr", table, rowAttr_);
01660     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01661     maker.addText(tableDiv, "Error Event Count");
01662     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01663     maker.addInt( tableDiv, rbResultPtr->errorEventStats.getSampleCount() );
01664     
01665     tableRow = maker.addNode("tr", table, rowAttr_);
01666     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01667     maker.addText(tableDiv, "Faulty Event Count");
01668     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01669     maker.addInt( tableDiv, rbResultPtr->faultyEventStats.getSampleCount() );
01670     
01671     tableRow = maker.addNode("tr", table, rowAttr_);
01672     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01673     maker.addText(tableDiv, "Data Discard Count");
01674     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01675     maker.addInt( tableDiv, rbResultPtr->dataDiscardStats.getSampleCount() );
01676     
01677     tableRow = maker.addNode("tr", table, rowAttr_);
01678     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01679     maker.addText(tableDiv, "DQM Event Count");
01680     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01681     maker.addInt( tableDiv, rbResultPtr->dqmEventStats.getSampleCount() );
01682     
01683     tableRow = maker.addNode("tr", table, rowAttr_);
01684     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01685     maker.addText(tableDiv, "Faulty DQM Event Count");
01686     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01687     maker.addInt( tableDiv, rbResultPtr->faultyDQMEventStats.getSampleCount() );
01688     
01689     tableRow = maker.addNode("tr", table, rowAttr_);
01690     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01691     maker.addText(tableDiv, "DQM Discard Count");
01692     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01693     maker.addInt( tableDiv, rbResultPtr->dqmDiscardStats.getSampleCount() );
01694     
01695     tableRow = maker.addNode("tr", table, rowAttr_);
01696     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01697     maker.addText(tableDiv, "Ignored Discards Count");
01698     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01699     maker.addInt( tableDiv, rbResultPtr->skippedDiscardStats.getSampleCount() );
01700     
01701     tableRow = maker.addNode("tr", table, rowAttr_);
01702     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01703     maker.addText(tableDiv, "Last Event Number Received");
01704     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01705     maker.addInt( tableDiv, rbResultPtr->lastEventNumber );
01706     
01707     tableRow = maker.addNode("tr", table, rowAttr_);
01708     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01709     maker.addText(tableDiv, "Last Run Number Received");
01710     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01711     maker.addInt( tableDiv, rbResultPtr->lastRunNumber );
01712     
01713     tableRow = maker.addNode("tr", table, rowAttr_);
01714     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01715     tmpDuration = rbResultPtr->eventStats.recentDuration.total_seconds();
01716     tmpText =  "Recent (" + boost::lexical_cast<std::string>(tmpDuration) +
01717       " sec) Event Rate (Hz)";
01718     maker.addText(tableDiv, tmpText);
01719     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01720     maker.addDouble( tableDiv, rbResultPtr->eventStats.recentSampleRate );
01721     
01722     tableRow = maker.addNode("tr", table, rowAttr_);
01723     tableDiv = maker.addNode("td", tableRow, tableLabelAttr_);
01724     tmpDuration = rbResultPtr->eventStats.fullDuration.total_seconds();
01725     tmpText =  "Full (" + boost::lexical_cast<std::string>(tmpDuration) +
01726       " sec) Event Rate (Hz)";
01727     maker.addText(tableDiv, tmpText);
01728     tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01729     maker.addDouble( tableDiv, rbResultPtr->eventStats.fullSampleRate );
01730   }
01731   
01732   
01733   void SMWebPageHelper::addFilterUnitList
01734   (
01735     XHTMLMaker& maker,
01736     XHTMLMaker::Node *parent,
01737     long long uniqueRBID,
01738     DataSenderMonitorCollection const& dsmc
01739   ) const
01740   {
01741     DataSenderMonitorCollection::FilterUnitResultsList fuResultsList =
01742       dsmc.getFilterUnitResultsForRB(uniqueRBID);
01743     
01744     XHTMLMaker::AttrMap colspanAttr;
01745     colspanAttr[ "colspan" ] = "13";
01746     
01747     XHTMLMaker::AttrMap tableSuspiciousValueAttr = tableValueAttr_;
01748     tableSuspiciousValueAttr[ "style" ] = "background-color: yellow;";
01749     
01750     XHTMLMaker::Node* table = maker.addNode("table", parent, tableAttr_);
01751     
01752     XHTMLMaker::Node* tableRow = maker.addNode("tr", table, rowAttr_);
01753     XHTMLMaker::Node* tableDiv = maker.addNode("th", tableRow, colspanAttr);
01754     maker.addText(tableDiv, "Filter Units");
01755     
01756     // Header
01757     tableRow = maker.addNode("tr", table, specialRowAttr_);
01758     tableDiv = maker.addNode("th", tableRow);
01759     maker.addText(tableDiv, "Process ID");
01760     tableDiv = maker.addNode("th", tableRow);
01761     maker.addText(tableDiv, "# of INIT messages");
01762     tableDiv = maker.addNode("th", tableRow);
01763     maker.addText(tableDiv, "# of events");
01764     tableDiv = maker.addNode("th", tableRow);
01765     maker.addText(tableDiv, "# of error events");
01766     tableDiv = maker.addNode("th", tableRow);
01767     maker.addText(tableDiv, "# of faulty events");
01768     tableDiv = maker.addNode("th", tableRow);
01769     maker.addText(tableDiv, "# of outstanding data discards");
01770     tableDiv = maker.addNode("th", tableRow);
01771     maker.addText(tableDiv, "# of DQM events");
01772     tableDiv = maker.addNode("th", tableRow);
01773     maker.addText(tableDiv, "# of faulty DQM events");
01774     tableDiv = maker.addNode("th", tableRow);
01775     maker.addText(tableDiv, "# of outstanding DQM discards");
01776     tableDiv = maker.addNode("th", tableRow);
01777     maker.addText(tableDiv, "# of ignored discards");
01778     tableDiv = maker.addNode("th", tableRow);
01779     maker.addText(tableDiv, "Recent event rate (Hz)");
01780     tableDiv = maker.addNode("th", tableRow);
01781     maker.addText(tableDiv, "Last event number received");
01782     tableDiv = maker.addNode("th", tableRow);
01783     maker.addText(tableDiv, "Last run number received");
01784     
01785     if (fuResultsList.empty())
01786     {
01787       XHTMLMaker::AttrMap messageAttr = colspanAttr;
01788       messageAttr[ "align" ] = "center";
01789       
01790       tableRow = maker.addNode("tr", table, rowAttr_);
01791       tableDiv = maker.addNode("td", tableRow, messageAttr);
01792       maker.addText(tableDiv, "No filter units have registered yet.");
01793       return;
01794     }
01795     else
01796     {
01797       for (unsigned int idx = 0; idx < fuResultsList.size(); ++idx)
01798       {
01799         tableRow = maker.addNode("tr", table, rowAttr_);
01800         
01801         tableDiv = maker.addNode("td", tableRow);
01802         maker.addInt( tableDiv, fuResultsList[idx]->key.fuProcessId );
01803         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01804         maker.addInt( tableDiv, fuResultsList[idx]->initMsgCount );
01805         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01806         maker.addInt( tableDiv, fuResultsList[idx]->shortIntervalEventStats.getSampleCount() );
01807         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01808         maker.addInt( tableDiv, fuResultsList[idx]->errorEventStats.getSampleCount() );
01809         
01810         if (fuResultsList[idx]->faultyEventStats.getSampleCount() != 0)
01811         {
01812           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01813         }
01814         else
01815         {
01816           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01817         }
01818         maker.addInt( tableDiv, fuResultsList[idx]->faultyEventStats.getSampleCount() );
01819         
01820         if (fuResultsList[idx]->outstandingDataDiscardCount != 0)
01821         {
01822           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01823         }
01824         else
01825         {
01826           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01827         }
01828         maker.addInt( tableDiv, fuResultsList[idx]->outstandingDataDiscardCount );
01829         
01830         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01831         maker.addInt( tableDiv, fuResultsList[idx]->dqmEventStats.getSampleCount() );
01832         
01833         if (fuResultsList[idx]->faultyDQMEventStats.getSampleCount() != 0)
01834         {
01835           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01836         }
01837         else
01838         {
01839           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01840         }
01841         maker.addInt( tableDiv, fuResultsList[idx]->faultyDQMEventStats.getSampleCount() );
01842         
01843         if (fuResultsList[idx]->outstandingDQMDiscardCount != 0)
01844         {
01845           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01846         }
01847         else
01848         {
01849           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01850         }
01851         maker.addInt( tableDiv, fuResultsList[idx]->outstandingDQMDiscardCount );
01852         
01853         const int skippedDiscards = fuResultsList[idx]->skippedDiscardStats.getSampleCount();
01854         if (skippedDiscards != 0)
01855         {
01856           tableDiv = maker.addNode("td", tableRow, tableSuspiciousValueAttr);
01857         }
01858         else
01859         {
01860           tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01861         }
01862         maker.addInt( tableDiv, skippedDiscards );
01863         
01864         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01865         maker.addDouble( tableDiv, fuResultsList[idx]->shortIntervalEventStats.
01866           getSampleRate(MonitoredQuantity::RECENT) );
01867         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01868         maker.addInt( tableDiv, fuResultsList[idx]->lastEventNumber );
01869         tableDiv = maker.addNode("td", tableRow, tableValueAttr_);
01870         maker.addInt( tableDiv, fuResultsList[idx]->lastRunNumber );
01871       }
01872     }
01873   }
01874  
01875 } // namespace stor
01876  
01877