00001 #include "canvas/Utilities/Exception.h"
00002 #include "art/Framework/Art/artapp.h"
00003
00004 #include "artdaq-core/Core/SimpleQueueReader.hh"
00005 #include "artdaq-core/Utilities/ExceptionHandler.hh"
00006
00007 #include "artdaq/Application/EventBuilderCore.hh"
00008 #include "artdaq/TransferPlugins/TransferInterface.hh"
00009 #include "artdaq/DAQdata/Globals.hh"
00010 #include "artdaq/DAQrate/EventStore.hh"
00011 #define TRACE_NAME "EventBuilderCore"
00012
00013 #include <iomanip>
00014
00015 const std::string artdaq::EventBuilderCore::INPUT_FRAGMENTS_STAT_KEY("EventBuilderCoreInputFragments");
00016 const std::string artdaq::EventBuilderCore::INPUT_WAIT_STAT_KEY("EventBuilderCoreInputWaitTime");
00017 const std::string artdaq::EventBuilderCore::STORE_EVENT_WAIT_STAT_KEY("EventBuilderCoreStoreEventWaitTime");
00018
00019 artdaq::EventBuilderCore::EventBuilderCore(int rank, std::string name)
00020 : name_(name)
00021 , art_initialized_(false)
00022 , stop_requested_(false)
00023 , pause_requested_(false)
00024 , run_is_paused_(false)
00025 , processing_fragments_(false)
00026 {
00027 TLOG_DEBUG(name_) << "Constructor" << TLOG_ENDL;
00028 statsHelper_.addMonitoredQuantityName(INPUT_FRAGMENTS_STAT_KEY);
00029 statsHelper_.addMonitoredQuantityName(INPUT_WAIT_STAT_KEY);
00030 statsHelper_.addMonitoredQuantityName(STORE_EVENT_WAIT_STAT_KEY);
00031 my_rank = rank;
00032 metricMan = &metricMan_;
00033 }
00034
00035 artdaq::EventBuilderCore::~EventBuilderCore()
00036 {
00037 TLOG_DEBUG(name_) << "Destructor" << TLOG_ENDL;
00038 }
00039
00040 void artdaq::EventBuilderCore::initializeEventStore(fhicl::ParameterSet pset)
00041 {
00042 if (use_art_)
00043 {
00044 artdaq::EventStore::ART_CFGSTRING_FCN* reader = &artapp_string_config;
00045 TRACE(36, "Creating EventStore and Starting art thread");
00046 event_store_ptr_.reset(new artdaq::EventStore(pset, expected_fragments_per_event_, 1,
00047 init_string_, reader));
00048 TRACE(36, "Done Creating EventStore");
00049 art_initialized_ = true;
00050 }
00051 else
00052 {
00053 const char* dummyArgs[1]{ "SimpleQueueReader" };
00054 artdaq::EventStore::ART_CMDLINE_FCN* reader = &artdaq::simpleQueueReaderApp;
00055 event_store_ptr_.reset(new artdaq::EventStore(pset, expected_fragments_per_event_, 1,
00056 1, const_cast<char**>(dummyArgs), reader));
00057 }
00058 }
00059
00060 bool artdaq::EventBuilderCore::initialize(fhicl::ParameterSet const& pset)
00061 {
00062 init_string_ = pset.to_string();
00063 TLOG_DEBUG(name_) << "initialize method called with DAQ "
00064 << "ParameterSet = \"" << init_string_ << "\"." << TLOG_ENDL;
00065
00066
00067 fhicl::ParameterSet daq_pset;
00068 try
00069 {
00070 daq_pset = pset.get<fhicl::ParameterSet>("daq");
00071 }
00072 catch (...)
00073 {
00074 TLOG_ERROR(name_)
00075 << "Unable to find the DAQ parameters in the initialization "
00076 << "ParameterSet: \"" + pset.to_string() + "\"." << TLOG_ENDL;
00077 return false;
00078 }
00079 fhicl::ParameterSet evb_pset;
00080 try
00081 {
00082 evb_pset = daq_pset.get<fhicl::ParameterSet>("event_builder");
00083 data_pset_ = evb_pset;
00084 }
00085 catch (...)
00086 {
00087 TLOG_ERROR(name_)
00088 << "Unable to find the event_builder parameters in the DAQ "
00089 << "initialization ParameterSet: \"" + daq_pset.to_string() + "\"." << TLOG_ENDL;
00090 return false;
00091 }
00092 try
00093 {
00094 expected_fragments_per_event_ =
00095 evb_pset.get<size_t>("expected_fragments_per_event");
00096 }
00097 catch (...)
00098 {
00099 TLOG_ERROR(name_)
00100 << "The expected_fragments_per_event parameter was not specified "
00101 << "in the event_builder initialization PSet: \"" << pset.to_string()
00102 << "\"." << TLOG_ENDL;
00103 return false;
00104 }
00105
00106
00107 try { use_art_ = evb_pset.get<bool>("use_art"); }
00108 catch (...)
00109 {
00110 TLOG_ERROR(name_)
00111 << "The use_art parameter was not specified "
00112 << "in the event_builder initialization PSet: \""
00113 << evb_pset.to_string() << "\"." << TLOG_ENDL;
00114 return false;
00115 }
00116 inrun_recv_timeout_usec_ = evb_pset.get<size_t>("inrun_recv_timeout_usec", 100000);
00117 endrun_recv_timeout_usec_ = evb_pset.get<size_t>("endrun_recv_timeout_usec", 20000000);
00118 pause_recv_timeout_usec_ = evb_pset.get<size_t>("pause_recv_timeout_usec", 3000000);
00119 verbose_ = evb_pset.get<bool>("verbose", false);
00120
00121
00122 statsHelper_.createCollectors(evb_pset, 100, 20.0, 60.0, INPUT_FRAGMENTS_STAT_KEY);
00123
00124
00125 std::string metricsReportingInstanceName = "EventBuilder." +
00126 boost::lexical_cast<std::string>(my_rank);
00127 fhicl::ParameterSet metric_pset;
00128 try
00129 {
00130 metric_pset = daq_pset.get<fhicl::ParameterSet>("metrics");
00131 }
00132 catch (...) {}
00133
00134 if (metric_pset.is_empty())
00135 {
00136 TLOG_INFO(name_) << "No metric plugins appear to be defined" << TLOG_ENDL;
00137 }
00138 try
00139 {
00140 metricMan_.initialize(metric_pset, metricsReportingInstanceName);
00141 }
00142 catch (...)
00143 {
00144 ExceptionHandler(ExceptionHandlerRethrow::no,
00145 "Error loading metrics in EventBuilderCore::initialize()");
00146 }
00147
00148
00149
00150
00151
00152
00153
00154 if (art_initialized_ == false)
00155 {
00156 this->initializeEventStore(evb_pset);
00157 fhicl::ParameterSet tmp = pset;
00158 tmp.erase("daq");
00159 previous_pset_ = tmp;
00160 }
00161 else
00162 {
00163 fhicl::ParameterSet tmp = pset;
00164 tmp.erase("daq");
00165 if (tmp != previous_pset_)
00166 {
00167 TLOG_ERROR(name_)
00168 << "The art configuration can not be altered after art "
00169 << "has been configured." << TLOG_ENDL;
00170 return false;
00171 }
00172 }
00173
00174 return true;
00175 }
00176
00177 bool artdaq::EventBuilderCore::start(art::RunID id)
00178 {
00179 stop_requested_.store(false);
00180 pause_requested_.store(false);
00181 run_is_paused_.store(false);
00182 run_id_ = id;
00183 eod_fragments_received_ = 0;
00184 fragment_count_in_run_ = 0;
00185 statsHelper_.resetStatistics();
00186 flush_mutex_.lock();
00187 metricMan_.do_start();
00188 event_store_ptr_->startRun(id.run());
00189
00190 logMessage_("Started run " + boost::lexical_cast<std::string>(run_id_.run()));
00191 return true;
00192 }
00193
00194 bool artdaq::EventBuilderCore::stop()
00195 {
00196 logMessage_("Stopping run " + boost::lexical_cast<std::string>(run_id_.run()) +
00197 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00198 bool endSucceeded;
00199 int attemptsToEnd;
00200
00201
00202
00203
00204
00205 stop_requested_.store(true);
00206
00207 flush_mutex_.lock();
00208 if (!run_is_paused_.load())
00209 {
00210 endSucceeded = false;
00211 attemptsToEnd = 1;
00212 endSucceeded = event_store_ptr_->endSubrun();
00213 while (!endSucceeded && attemptsToEnd < 3)
00214 {
00215 ++attemptsToEnd;
00216 TLOG_DEBUG(name_) << "Retrying EventStore::endSubrun()" << TLOG_ENDL;
00217 endSucceeded = event_store_ptr_->endSubrun();
00218 }
00219 if (!endSucceeded)
00220 {
00221 TLOG_ERROR(name_)
00222 << "EventStore::endSubrun in stop method failed after three tries." << TLOG_ENDL;
00223 }
00224 }
00225
00226 endSucceeded = false;
00227 attemptsToEnd = 1;
00228 endSucceeded = event_store_ptr_->endRun();
00229 while (!endSucceeded && attemptsToEnd < 3)
00230 {
00231 ++attemptsToEnd;
00232 TLOG_DEBUG(name_) << "Retrying EventStore::endRun()" << TLOG_ENDL;
00233 endSucceeded = event_store_ptr_->endRun();
00234 }
00235 if (!endSucceeded)
00236 {
00237 TLOG_ERROR(name_)
00238 << "EventStore::endRun in stop method failed after three tries." << TLOG_ENDL;
00239 }
00240
00241 flush_mutex_.unlock();
00242 run_is_paused_.store(false);
00243 return true;
00244 }
00245
00246 bool artdaq::EventBuilderCore::pause()
00247 {
00248 logMessage_("Pausing run " + boost::lexical_cast<std::string>(run_id_.run()) +
00249 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00250 pause_requested_.store(true);
00251 flush_mutex_.lock();
00252
00253 bool endSucceeded = false;
00254 int attemptsToEnd = 1;
00255 endSucceeded = event_store_ptr_->endSubrun();
00256 while (!endSucceeded && attemptsToEnd < 3)
00257 {
00258 ++attemptsToEnd;
00259 TLOG_DEBUG(name_) << "Retrying EventStore::endSubrun()" << TLOG_ENDL;
00260 endSucceeded = event_store_ptr_->endSubrun();
00261 }
00262 if (!endSucceeded)
00263 {
00264 TLOG_ERROR(name_)
00265 << "EventStore::endSubrun in pause method failed after three tries." << TLOG_ENDL;
00266 }
00267
00268 flush_mutex_.unlock();
00269 run_is_paused_.store(true);
00270 return true;
00271 }
00272
00273 bool artdaq::EventBuilderCore::resume()
00274 {
00275 logMessage_("Resuming run " + boost::lexical_cast<std::string>(run_id_.run()));
00276 eod_fragments_received_ = 0;
00277 pause_requested_.store(false);
00278 flush_mutex_.lock();
00279 metricMan_.do_start();
00280 event_store_ptr_->startSubrun();
00281 run_is_paused_.store(false);
00282 return true;
00283 }
00284
00285 bool artdaq::EventBuilderCore::shutdown()
00286 {
00287
00288
00289
00290
00291 int readerReturnValue;
00292 bool endSucceeded = false;
00293 int attemptsToEnd = 1;
00294 TRACE(4, "EventBuilderCore::shutdown: Calling EventStore::endOfData");
00295 endSucceeded = event_store_ptr_->endOfData(readerReturnValue);
00296 while (!endSucceeded && attemptsToEnd < 3)
00297 {
00298 ++attemptsToEnd;
00299 TRACE(4, "EventBuilderCore::shutdown: Retrying endOfData call");
00300 TLOG_DEBUG(name_) << "Retrying EventStore::endOfData()" << TLOG_ENDL;
00301 endSucceeded = event_store_ptr_->endOfData(readerReturnValue);
00302 }
00303 TRACE(4, "EventBuilderCore::shutdown: Shutting down MetricManager");
00304 metricMan_.shutdown();
00305 TRACE(4, "EventBuilderCore::shutdown: Complete");
00306 return endSucceeded;
00307 }
00308
00309 bool artdaq::EventBuilderCore::soft_initialize(fhicl::ParameterSet const& pset)
00310 {
00311 TLOG_DEBUG(name_) << "soft_initialize method called with DAQ "
00312 << "ParameterSet = \"" << pset.to_string()
00313 << "\"." << TLOG_ENDL;
00314 return true;
00315 }
00316
00317 bool artdaq::EventBuilderCore::reinitialize(fhicl::ParameterSet const& pset)
00318 {
00319 TLOG_DEBUG(name_) << "reinitialize method called with DAQ "
00320 << "ParameterSet = \"" << pset.to_string()
00321 << "\"." << TLOG_ENDL;
00322 event_store_ptr_.reset(nullptr);
00323 art_initialized_ = false;
00324 return initialize(pset);
00325 }
00326
00327 size_t artdaq::EventBuilderCore::process_fragments()
00328 {
00329 processing_fragments_.store(true);
00330 bool process_fragments = true;
00331 int senderSlot;
00332 detail::FragCounter fragments_received;
00333 detail::FragCounter fragments_sent;
00334
00335 receiver_ptr_.reset(new artdaq::DataReceiverManager(data_pset_));
00336 receiver_ptr_->start_threads();
00337
00338
00339
00340 TLOG_DEBUG(name_) << "Waiting for first fragment." << TLOG_ENDL;
00341 artdaq::MonitoredQuantityStats::TIME_POINT_T startTime;
00342 while (process_fragments)
00343 {
00344 size_t recvTimeout = inrun_recv_timeout_usec_;
00345 if (stop_requested_.load()) { recvTimeout = endrun_recv_timeout_usec_; }
00346 else if (pause_requested_.load()) { recvTimeout = pause_recv_timeout_usec_; }
00347 startTime = artdaq::MonitoredQuantity::getCurrentTime();
00348 artdaq::FragmentPtr pfragment = receiver_ptr_->recvFragment(senderSlot, recvTimeout);
00349 statsHelper_.addSample(INPUT_WAIT_STAT_KEY,
00350 (artdaq::MonitoredQuantity::getCurrentTime() - startTime));
00351 if (senderSlot == artdaq::TransferInterface::RECV_TIMEOUT)
00352 {
00353 if (stop_requested_.load() &&
00354 recvTimeout == endrun_recv_timeout_usec_)
00355 {
00356 TLOG_WARNING(name_)
00357 << "Timeout occurred in attempt to receive data, but as a stop has been requested, will forcibly end the run." << TLOG_ENDL;
00358 event_store_ptr_->flushData();
00359 flush_mutex_.unlock();
00360 process_fragments = false;
00361 }
00362 else if (pause_requested_.load() &&
00363 recvTimeout == pause_recv_timeout_usec_)
00364 {
00365 TLOG_WARNING(name_)
00366 << "Timeout occurred in attempt to receive data, but as a pause has been requested, will forcibly pause the run." << TLOG_ENDL;
00367 event_store_ptr_->flushData();
00368 flush_mutex_.unlock();
00369 process_fragments = false;
00370 }
00371 continue;
00372 }
00373 else if (!pfragment)
00374 {
00375 TLOG_ERROR(name_) << "Received invalid fragment from " << senderSlot << ". This is usually the case when a timeout has occurred, but sender was not set to RECV_TIMEOUT as expected." << TLOG_ENDL;
00376 continue;
00377 }
00378 if (!receiver_ptr_->enabled_sources().count(senderSlot))
00379 {
00380 TLOG_ERROR(name_)
00381 << "Invalid senderSlot received from recvFragment: "
00382 << senderSlot << TLOG_ENDL;
00383 continue;
00384 }
00385 fragments_received.incSlot(senderSlot);
00386 if (artdaq::Fragment::isSystemFragmentType(pfragment->type()))
00387 {
00388 TLOG_DEBUG(name_)
00389 << "Sender slot = " << senderSlot
00390 << ", fragment type = " << ((int)pfragment->type())
00391 << ", sequence ID = " << pfragment->sequenceID() << TLOG_ENDL;
00392 }
00393
00394 ++fragment_count_in_run_;
00395 TRACE(18, "process_fragments %lu=fragment_count_in_run_ %lu=pfragment->size()"
00396 , fragment_count_in_run_, pfragment->size());
00397 statsHelper_.addSample(INPUT_FRAGMENTS_STAT_KEY, pfragment->size());
00398 if (statsHelper_.readyToReport(fragment_count_in_run_))
00399 {
00400 std::string statString = buildStatisticsString_();
00401 logMessage_(statString);
00402 logMessage_("Received fragment " +
00403 boost::lexical_cast<std::string>(fragment_count_in_run_) +
00404 " with sequence ID " +
00405 boost::lexical_cast<std::string>(pfragment->sequenceID()) +
00406 " (run " +
00407 boost::lexical_cast<std::string>(run_id_.run()) +
00408 ", subrun " +
00409 boost::lexical_cast<std::string>(event_store_ptr_->subrunID()) +
00410 ").");
00411 }
00412 if (statsHelper_.statsRollingWindowHasMoved())
00413 {
00414 sendMetrics_();
00415 event_store_ptr_->sendMetrics();
00416 }
00417
00418 startTime = artdaq::MonitoredQuantity::getCurrentTime();
00419 if (pfragment->type() != artdaq::Fragment::EndOfDataFragmentType)
00420 {
00421 artdaq::FragmentPtr rejectedFragment;
00422 auto seqId = pfragment->sequenceID();
00423 auto fragId = pfragment->fragmentID();
00424 bool try_again = true;
00425 while (try_again)
00426 {
00427 auto ret = event_store_ptr_->insert(std::move(pfragment), rejectedFragment);
00428 if (ret == EventStore::EventStoreInsertResult::SUCCESS)
00429 {
00430 receiver_ptr_->unsuppressAll();
00431 try_again = false;
00432 }
00433 else if (ret == EventStore::EventStoreInsertResult::SUCCESS_STOREFULL)
00434 {
00435 try_again = false;
00436 }
00437 else if (stop_requested_.load())
00438 {
00439 try_again = false;
00440 flush_mutex_.unlock();
00441 process_fragments = false;
00442 receiver_ptr_->reject_fragment(senderSlot, std::move(rejectedFragment));
00443 TLOG_WARNING(name_)
00444 << "Unable to process fragment " << fragId
00445 << " in event " << seqId
00446 << " because of back-pressure - forcibly ending the run." << TLOG_ENDL;
00447 }
00448 else if (pause_requested_.load())
00449 {
00450 try_again = false;
00451 flush_mutex_.unlock();
00452 process_fragments = false;
00453 receiver_ptr_->reject_fragment(senderSlot, std::move(rejectedFragment));
00454 TLOG_WARNING(name_)
00455 << "Unable to process fragment " << fragId
00456 << " in event " << seqId
00457 << " because of back-pressure - forcibly pausing the run." << TLOG_ENDL;
00458 }
00459 else if (ret == EventStore::EventStoreInsertResult::REJECT_QUEUEFULL)
00460 {
00461 pfragment = std::move(rejectedFragment);
00462 TLOG_WARNING(name_)
00463 << "Unable to process fragment " << fragId
00464 << " in event " << seqId
00465 << " because of back-pressure from art - retrying..." << TLOG_ENDL;
00466 }
00467 else
00468 {
00469 try_again = false;
00470 receiver_ptr_->reject_fragment(senderSlot, std::move(rejectedFragment));
00471 TLOG_WARNING(name_)
00472 << "Unable to process fragment " << fragId
00473 << " in event " << seqId
00474 << " because the EventStore has reached the maximum number of incomplete events." << std::endl
00475 << " Will retry when the EventStore is ready for new events." << TLOG_ENDL;
00476 }
00477 }
00478 }
00479 else
00480 {
00481 eod_fragments_received_++;
00482 event_store_ptr_->setRequestMode(detail::RequestMessageMode::EndOfRun);
00483
00484
00485
00486 fragments_sent.setSlot(senderSlot, *pfragment->dataBegin() + 1);
00487 }
00488 statsHelper_.addSample(STORE_EVENT_WAIT_STAT_KEY,
00489 artdaq::MonitoredQuantity::getCurrentTime() - startTime);
00490
00491
00492
00493
00494
00495 if (eod_fragments_received_ == receiver_ptr_->enabled_sources().size())
00496 {
00497 bool fragmentsOutstanding = false;
00498 for (auto& i : receiver_ptr_->enabled_sources())
00499 {
00500 if (fragments_received[i] != fragments_sent[i])
00501 {
00502 fragmentsOutstanding = true;
00503 break;
00504 }
00505 }
00506
00507 if (!fragmentsOutstanding)
00508 {
00509 event_store_ptr_->flushData();
00510 flush_mutex_.unlock();
00511 process_fragments = false;
00512 }
00513 else
00514 {
00515 TLOG_WARNING(name_) << "All EndOfData fragments received but more data expected" << TLOG_ENDL;
00516 }
00517 }
00518 }
00519
00520
00521
00522
00523 metricMan_.do_stop();
00524
00525 receiver_ptr_.reset(nullptr);
00526 processing_fragments_.store(false);
00527 return 0;
00528 }
00529
00530 std::string artdaq::EventBuilderCore::report(std::string const& which) const
00531 {
00532 if (which == "incomplete_event_count")
00533 {
00534 if (event_store_ptr_ != nullptr)
00535 {
00536 return boost::lexical_cast<std::string>(event_store_ptr_->incompleteEventCount());
00537 }
00538 else
00539 {
00540 return "-1";
00541 }
00542 }
00543 if (which == "event_count")
00544 {
00545 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().
00546 getMonitoredQuantity(STORE_EVENT_WAIT_STAT_KEY);
00547 if (mqPtr.get() != 0)
00548 {
00549 return boost::lexical_cast<std::string>(mqPtr->getFullSampleCount());
00550 }
00551 else
00552 {
00553 return "-1";
00554 }
00555 }
00556
00557 if (which == "run_duration")
00558 {
00559
00560 double duration = 0;
00561 if (processing_fragments_.load())
00562 {
00563 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().
00564 getMonitoredQuantity(STORE_EVENT_WAIT_STAT_KEY);
00565 if (mqPtr.get() != 0)
00566 {
00567 duration = mqPtr->getFullDuration();
00568 }
00569 }
00570 std::ostringstream oss;
00571 oss << std::fixed << std::setprecision(1) << duration;
00572 return oss.str();
00573 }
00574
00575
00576
00577
00578
00579
00580 std::string tmpString = name_ + " run number = ";
00581 tmpString.append(boost::lexical_cast<std::string>(run_id_.run()));
00582 tmpString.append(". Command \"" + which + "\" is not currently supported.");
00583 return tmpString;
00584 }
00585
00586
00587 std::string artdaq::EventBuilderCore::buildStatisticsString_()
00588 {
00589 std::ostringstream oss;
00590 double eventCount = 1.0;
00591 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().
00592 getMonitoredQuantity(INPUT_FRAGMENTS_STAT_KEY);
00593 if (mqPtr.get() != 0)
00594 {
00595
00596 artdaq::MonitoredQuantityStats stats;
00597 mqPtr->getStats(stats);
00598 oss << "Input statistics: "
00599 << stats.recentSampleCount << " fragments received at "
00600 << stats.recentSampleRate << " fragments/sec, data rate = "
00601 << (stats.recentValueRate * sizeof(artdaq::RawDataType)
00602 / 1024.0 / 1024.0) << " MB/sec, monitor window = "
00603 << stats.recentDuration << " sec, min::max fragment size = "
00604 << (stats.recentValueMin * sizeof(artdaq::RawDataType)
00605 / 1024.0 / 1024.0)
00606 << "::"
00607 << (stats.recentValueMax * sizeof(artdaq::RawDataType)
00608 / 1024.0 / 1024.0)
00609 << " MB" << std::endl;
00610 eventCount = std::max(double(stats.recentSampleCount), 1.0);
00611 oss << "Average times per fragment: ";
00612 if (stats.recentSampleRate > 0.0)
00613 {
00614 oss << " elapsed time = "
00615 << (1.0 / stats.recentSampleRate) << " sec";
00616 }
00617 }
00618
00619
00620
00621
00622
00623
00624
00625 mqPtr = artdaq::StatisticsCollection::getInstance().
00626 getMonitoredQuantity(INPUT_WAIT_STAT_KEY);
00627 if (mqPtr.get() != 0)
00628 {
00629 oss << ", input wait time = "
00630 << (mqPtr->getRecentValueSum() / eventCount) << " sec";
00631 }
00632
00633 mqPtr = artdaq::StatisticsCollection::getInstance().
00634 getMonitoredQuantity(STORE_EVENT_WAIT_STAT_KEY);
00635 if (mqPtr.get() != 0)
00636 {
00637 oss << ", event store wait time = "
00638 << (mqPtr->getRecentValueSum() / eventCount) << " sec";
00639 }
00640
00641 return oss.str();
00642 }
00643
00644 void artdaq::EventBuilderCore::sendMetrics_()
00645 {
00646
00647 double fragmentCount = 1.0;
00648 artdaq::MonitoredQuantityPtr mqPtr = artdaq::StatisticsCollection::getInstance().
00649 getMonitoredQuantity(INPUT_FRAGMENTS_STAT_KEY);
00650 if (mqPtr.get() != 0)
00651 {
00652 artdaq::MonitoredQuantityStats stats;
00653 mqPtr->getStats(stats);
00654 fragmentCount = std::max(double(stats.recentSampleCount), 1.0);
00655 metricMan_.sendMetric("Fragment Count",
00656 static_cast<unsigned long>(stats.fullSampleCount),
00657 "fragments", 1);
00658 metricMan_.sendMetric("Fragment Rate",
00659 stats.recentSampleRate, "fragments/sec", 1);
00660 metricMan_.sendMetric("Average Fragment Size",
00661 (stats.recentValueAverage * sizeof(artdaq::RawDataType)
00662 ), "bytes/fragment", 2);
00663 metricMan_.sendMetric("Data Rate",
00664 (stats.recentValueRate * sizeof(artdaq::RawDataType)
00665 ), "bytes/sec", 2);
00666 }
00667
00668
00669
00670
00671
00672
00673
00674 mqPtr = artdaq::StatisticsCollection::getInstance().
00675 getMonitoredQuantity(INPUT_WAIT_STAT_KEY);
00676 if (mqPtr.get() != 0)
00677 {
00678 metricMan_.sendMetric("Average Input Wait Time",
00679 (mqPtr->getRecentValueSum() / fragmentCount),
00680 "seconds/fragment", 3);
00681 }
00682
00683 mqPtr = artdaq::StatisticsCollection::getInstance().
00684 getMonitoredQuantity(STORE_EVENT_WAIT_STAT_KEY);
00685 if (mqPtr.get() != 0)
00686 {
00687 metricMan_.sendMetric("Avg Event Store Wait Time",
00688 (mqPtr->getRecentValueSum() / fragmentCount),
00689 "seconds/fragment", 3);
00690 }
00691 }
00692
00693 void artdaq::EventBuilderCore::logMessage_(std::string const& text)
00694 {
00695 if (verbose_)
00696 {
00697 TLOG_INFO(name_) << text << TLOG_ENDL;
00698 }
00699 else
00700 {
00701 TLOG_DEBUG(name_) << text << TLOG_ENDL;
00702 }
00703 }