Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:13:54

0001 #include <ctime>
0002 #include <iostream>
0003 
0004 #include <fmt/printf.h>
0005 
0006 #include <boost/algorithm/string.hpp>
0007 #include <boost/algorithm/string/predicate.hpp>
0008 
0009 #include "DQMMonitoringService.h"
0010 
0011 /*
0012  * This service is very similar to the FastMonitoringService in the HLT,
0013  * except that it is used for monitoring online DQM applications
0014  */
0015 
0016 namespace dqmservices {
0017 
0018   DQMMonitoringService::DQMMonitoringService(const edm::ParameterSet& pset, edm::ActivityRegistry& ar) {
0019     const char* x = std::getenv("DQM2_SOCKET");
0020     if (x) {
0021       std::cerr << "Monitoring pipe: " << x << std::endl;
0022       mstream_.connect(boost::asio::local::stream_protocol::endpoint(x));
0023     } else {
0024       std::cerr << "Monitoring file not found, disabling." << std::endl;
0025     }
0026 
0027     // init counters
0028     nevents_ = 0;
0029 
0030     last_lumi_ = 0;
0031     last_lumi_nevents_ = 0;
0032     last_lumi_time_ = std::chrono::high_resolution_clock::now();
0033 
0034     run_ = 0;
0035     lumi_ = 0;
0036 
0037     ar.watchPreGlobalBeginLumi(this, &DQMMonitoringService::evLumi);
0038     ar.watchPreSourceEvent(this, &DQMMonitoringService::evEvent);
0039   }
0040 
0041   DQMMonitoringService::~DQMMonitoringService() {}
0042 
0043   void DQMMonitoringService::outputLumiUpdate() {
0044     using std::chrono::duration_cast;
0045     using std::chrono::milliseconds;
0046 
0047     auto now = std::chrono::high_resolution_clock::now();
0048 
0049     ptree doc;
0050 
0051     // these might be different than the numbers we want to report
0052     // rate/stats per lumi are calculated from last_*_ fields
0053     doc.put("cmssw_run", run_);
0054     doc.put("cmssw_lumi", lumi_);
0055     doc.put("events_total", nevents_);
0056 
0057     // do statistics for the last (elapsed) ls
0058     auto lumi_millis = duration_cast<milliseconds>(now - last_lumi_time_).count();
0059     auto lumi_events = nevents_ - last_lumi_nevents_;
0060     auto lumi_last = last_lumi_;
0061 
0062     if ((lumi_last > 0) && (lumi_millis > 0)) {
0063       doc.put("lumi_number", lumi_last);
0064       doc.put("lumi_events", lumi_events);
0065       doc.put("lumi_duration_ms", lumi_millis);
0066 
0067       float rate = ((float)lumi_events * 1000) / lumi_millis;
0068       doc.put("events_rate", rate);
0069 
0070       // also save the history entry
0071       ptree plumi;
0072       plumi.put("n", lumi_last);
0073       plumi.put("nevents", lumi_events);
0074       plumi.put("nmillis", lumi_millis);
0075       plumi.put("rate", rate);
0076 
0077       std::time_t hkey = std::time(nullptr);
0078       doc.add_child(fmt::sprintf("extra.lumi_stats.%d", hkey), plumi);
0079     }
0080 
0081     outputUpdate(doc);
0082   }
0083 
0084   void DQMMonitoringService::evLumi(GlobalContext const& iContext) {
0085     using std::chrono::duration_cast;
0086     using std::chrono::milliseconds;
0087 
0088     // these might be different than the numbers we want to report
0089     // rate/stats per lumi are calculated from last_*_ fields
0090     run_ = iContext.luminosityBlockID().run();
0091     lumi_ = iContext.luminosityBlockID().luminosityBlock();
0092 
0093     outputLumiUpdate();
0094 
0095     last_lumi_time_ = std::chrono::high_resolution_clock::now();
0096     last_lumi_nevents_ = nevents_;
0097     last_lumi_ = lumi_;
0098   }
0099 
0100   void DQMMonitoringService::evEvent(StreamID const& iContext) {
0101     nevents_ += 1;
0102     tryUpdate();
0103   }
0104 
0105   void DQMMonitoringService::outputUpdate(ptree& doc) {
0106     using std::chrono::duration_cast;
0107     using std::chrono::milliseconds;
0108 
0109     if (!mstream_)
0110       return;
0111 
0112     try {
0113       last_update_time_ = std::chrono::high_resolution_clock::now();
0114       doc.put("update_timestamp", std::time(nullptr));
0115 
0116       write_json(mstream_, doc, false);
0117       mstream_.flush();
0118     } catch (...) {
0119       // pass
0120     }
0121   }
0122 
0123   void DQMMonitoringService::keepAlive() {
0124     if (!mstream_)
0125       return;
0126 
0127     mstream_ << "\n";
0128     mstream_.flush();
0129 
0130     tryUpdate();
0131   }
0132 
0133   void DQMMonitoringService::tryUpdate() {
0134     using std::chrono::duration_cast;
0135     using std::chrono::milliseconds;
0136 
0137     if (!mstream_)
0138       return;
0139 
0140     // sometimes we don't see any transition for a very long time
0141     // but we still want updates
0142     // luckily, keepAlive is called rather often by the input source
0143     auto now = std::chrono::high_resolution_clock::now();
0144     auto millis = duration_cast<milliseconds>(now - last_update_time_).count();
0145     if (millis >= (25 * 1000)) {
0146       outputLumiUpdate();
0147     }
0148   }
0149 
0150 }  // namespace dqmservices
0151 
0152 #include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
0153 
0154 using dqmservices::DQMMonitoringService;
0155 DEFINE_FWK_SERVICE(DQMMonitoringService);