CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/HLTrigger/special/src/HLTLogMonitorFilter.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    HLTLogMonitorFilter
00004 // Class:      HLTLogMonitorFilter
00005 // 
00013 //
00014 // Original Author:  Andrea Bocci
00015 //         Created:  Thu Nov  5 15:16:46 CET 2009
00016 // $Id: HLTLogMonitorFilter.cc,v 1.8 2009/11/18 15:23:20 fwyzard Exp $
00017 //
00018 
00019 
00020 // system include files
00021 #include <stdint.h>
00022 #include <map>
00023 
00024 // user include files
00025 #include "FWCore/Framework/interface/Frameworkfwd.h"
00026 #include "FWCore/Framework/interface/Event.h"
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028 #include "DataFormats/Provenance/interface/EventID.h"
00029 #include "HLTrigger/HLTcore/interface/HLTFilter.h"
00030 
00031 //
00032 // class declaration
00033 //
00034 
00035 class HLTLogMonitorFilter : public HLTFilter {
00036 public:
00037     explicit HLTLogMonitorFilter(const edm::ParameterSet &);
00038     ~HLTLogMonitorFilter();
00039 
00040 private:
00041     // ---------- private data types --------------------
00042 
00043     struct CategoryEntry {
00044       uint32_t threshold;       // configurable threshold, after which messages in this Category start to be logarithmically prescaled
00045       uint32_t prescale;        // current prescale for this Category
00046       uint64_t counter;         // number of events that fired this Category
00047       uint64_t accepted;        // number of events acepted for this Category
00048       bool     done;            // track if this Category has already been seen in the current event
00049 
00050       CategoryEntry(uint32_t t = 0) :
00051         threshold(t),           // default-constructed entries have the threshold set to 0, which means the associated Category is disabled
00052         prescale(1),
00053         counter(0),
00054         accepted(0),
00055         done(false)
00056       { }
00057 
00058       bool accept() {
00059         if (not done) {
00060           done = true;
00061           ++counter;
00062         }
00063 
00064         // fail if the prescaler is disabled (threshold == 0), or if the counter is not a multiple of the prescale
00065         if ((threshold == 0) or (counter % prescale))
00066           return false;
00067 
00068         // quasi-logarithmic increase in the prescale factor (should be safe even if threshold is 1)
00069         if (counter == prescale * threshold)
00070           prescale *= threshold;
00071 
00072         ++accepted;
00073         return true;
00074       }
00075 
00076     };
00077 
00078     typedef std::map<std::string, CategoryEntry> CategoryMap;
00079 
00080     // ---------- private methods -----------------------
00081 
00083     virtual bool filter(edm::Event&, const edm::EventSetup &);
00084 
00086     virtual void beginJob(void);
00087 
00089     virtual void endJob(void);
00090 
00092     bool knownCategory(const std::string & category);
00093 
00095     CategoryEntry & addCategory(const std::string & category, uint32_t threshold);
00096 
00098     CategoryEntry & getCategory(const std::string & category);
00099 
00101     void summary(void);
00102 
00103 
00104     // ---------- member data ---------------------------
00105     uint32_t    m_prescale;    // default threshold, after which messages in each Category start to be logarithmically prescaled
00106     CategoryMap m_data;        // map each category name to its prescale data
00107 };
00108 
00109 
00110 // system include files
00111 #include <sstream>
00112 #include <iomanip>
00113 #include <memory>
00114 #include <boost/foreach.hpp>
00115 #include <boost/range.hpp>
00116 #include <boost/algorithm/string.hpp>
00117 
00118 // user include files
00119 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00120 #include "FWCore/MessageLogger/interface/MessageSender.h"
00121 
00122 //
00123 // constructors and destructor
00124 //
00125 HLTLogMonitorFilter::HLTLogMonitorFilter(const edm::ParameterSet & config) :
00126   m_prescale(),
00127   m_data()
00128 {
00129   m_prescale = config.getParameter<uint32_t>("default_threshold");
00130 
00131   typedef std::vector<edm::ParameterSet> VPSet; 
00132   const VPSet & categories = config.getParameter<VPSet>("categories");
00133   for (VPSet::const_iterator category = categories.begin(); category != categories.end(); ++category) {
00134     const std::string & name = category->getParameter<std::string>("name");
00135     uint32_t threshold       = category->getParameter<uint32_t>("threshold");
00136     addCategory(name, threshold);
00137   }
00138 
00139   produces<std::vector<edm::ErrorSummaryEntry> >();
00140 }
00141 
00142 HLTLogMonitorFilter::~HLTLogMonitorFilter()
00143 {
00144 }
00145 
00146 
00147 //
00148 // member functions
00149 //
00150 
00151 // ------------ method called on each new Event  ------------
00152 bool HLTLogMonitorFilter::filter(edm::Event & event, const edm::EventSetup & setup) {
00153   // no LogErrors or LogWarnings, skip processing and reject the event
00154   if (not edm::MessageSender::freshError)
00155     return false;
00156 
00157   // clear "done" flag in all Categories
00158   BOOST_FOREACH(CategoryMap::value_type & entry, m_data)
00159     entry.second.done = false;
00160 
00161   // look at the LogErrors and LogWarnings, and accept the event if at least one is under threshold or matches the prescale
00162   bool accept = false;
00163   std::string category;
00164 
00165   typedef std::map<edm::ErrorSummaryMapKey, unsigned int> ErrorSummaryMap;
00166   BOOST_FOREACH(const ErrorSummaryMap::value_type & entry, edm::MessageSender::errorSummaryMap) {
00167     // split the message category
00168     typedef boost::split_iterator<std::string::const_iterator> splitter;
00169     for (splitter i = boost::make_split_iterator(entry.first.category, boost::first_finder("|", boost::is_equal()));
00170          i != splitter();
00171          ++i)
00172     {
00173       // extract the substring corresponding to the split_iterator
00174       // FIXME: this can be avoided if the m_data map is keyed on boost::sub_range<std::string>
00175       category.assign(i->begin(), i->end());
00176 
00177       // access the message category, or create a new one as needed, and check the prescale
00178       if (getCategory(category).accept())
00179         accept = true;
00180     }
00181   }
00182 
00183   // harvest the errors, but only if the filter will accept the event
00184   std::auto_ptr<std::vector<edm::ErrorSummaryEntry> > errors(new std::vector<edm::ErrorSummaryEntry>());
00185   if (accept) {
00186     errors->reserve( edm::MessageSender::errorSummaryMap.size() );
00187     BOOST_FOREACH(const ErrorSummaryMap::value_type & entry, edm::MessageSender::errorSummaryMap) {
00188       errors->push_back(entry.first);        // sets category, module and severity
00189       errors->back().count = entry.second;   // count is 0 in key; set it to correct value (see FWCore/MessageLogger/src/LoggedErrorsSummary.cc)
00190     }
00191   }
00192   event.put(errors);
00193 
00194   // clear the errorSummaryMap
00195   edm::MessageSender::errorSummaryMap.clear();
00196   edm::MessageSender::freshError = false;
00197 
00198   return accept;
00199 }
00200 
00201 // ------------ method called at the end of the Job ---------
00202 void HLTLogMonitorFilter::beginJob(void) {
00203   edm::MessageSender::errorSummaryIsBeingKept = true;
00204 }
00205 // ------------ method called at the end of the Job ---------
00206 void HLTLogMonitorFilter::endJob(void) {
00207   edm::MessageSender::errorSummaryIsBeingKept = false;
00208   summary();
00209 }
00210 
00212 bool HLTLogMonitorFilter::knownCategory(const std::string & category) {
00213   return (m_data.find( category ) != m_data.end());
00214 }
00215 
00217 HLTLogMonitorFilter::CategoryEntry & HLTLogMonitorFilter::addCategory(const std::string & category, uint32_t threshold) {
00218   // check after inserting, as either the new CategoryEntry is needed, or an error condition is raised
00219   std::pair<CategoryMap::iterator, bool> result = m_data.insert( std::make_pair(category, CategoryEntry(threshold)) );
00220   if (not result.second)
00221     throw cms::Exception("Configuration") << "Duplicate entry for category " << category;
00222   return result.first->second;
00223 }
00224 
00226 HLTLogMonitorFilter::CategoryEntry & HLTLogMonitorFilter::getCategory(const std::string & category) {
00227   // check before inserting, to avoid the construction of a CategoryEntry object
00228   CategoryMap::iterator i = m_data.find(category);
00229   if (i != m_data.end())
00230     return i->second;
00231   else
00232     return m_data.insert( std::make_pair(category, CategoryEntry(m_prescale)) ).first->second;
00233 }
00234 
00236 void HLTLogMonitorFilter::summary(void) {
00237   std::stringstream out;
00238   out << "Log-Report ---------- HLTLogMonitorFilter Summary ------------\n"
00239       << "Log-Report  Threshold   Prescale     Issued   Accepted   Rejected Category\n";
00240   BOOST_FOREACH(const CategoryMap::value_type & entry, m_data) {
00241     out << "Log-Report "
00242         << std::right
00243         << std::setw(10) << entry.second.threshold << ' '
00244         << std::setw(10) << entry.second.prescale  << ' '
00245         << std::setw(10) << entry.second.counter   << ' '
00246         << std::setw(10) << entry.second.accepted  << ' '
00247         << std::setw(10) << (entry.second.counter - entry.second.accepted) << ' '
00248         << std::left     << entry.first            << '\n';
00249   }
00250   edm::LogVerbatim("Report") << out.str();
00251 }
00252 
00253 // define as a framework plug-in
00254 #include "FWCore/Framework/interface/MakerMacros.h"
00255 DEFINE_FWK_MODULE(HLTLogMonitorFilter);