artdaq_utilities  1.08.05
MetricManager.hh
1 #ifndef artdaq_DAQrate_MetricManager_hh
2 #define artdaq_DAQrate_MetricManager_hh
3 
4 // MetricManager class definition file
5 // Author: Eric Flumerfelt
6 // Last Modified: 11/14/2014
7 //
8 // MetricManager loads a user-specified set of plugins, sends them their configuration,
9 // and sends them data as it is recieved. It also maintains the state of the plugins
10 // relative to the application state.
11 
12 #include "artdaq-utilities/Plugins/MetricData.hh"
13 #include "artdaq-utilities/Plugins/MetricPlugin.hh"
14 #include "artdaq-utilities/Plugins/SystemMetricCollector.hh"
15 
16 namespace fhicl {
17 class ParameterSet;
18 }
19 
20 #include "fhiclcpp/types/Atom.h"
21 #include "fhiclcpp/types/Comment.h"
22 #include "fhiclcpp/types/ConfigurationTable.h"
23 #include "fhiclcpp/types/Name.h"
24 #include "fhiclcpp/types/OptionalTable.h"
25 
26 #include <atomic>
27 #include <boost/thread.hpp>
28 #include <condition_variable>
29 #include <queue>
30 #include <sstream>
31 
32 namespace artdaq {
33 class MetricManager;
34 }
35 
42 {
43 public:
47  struct Config
48  {
51  fhicl::Atom<size_t> metric_queue_size{
52  fhicl::Name{"metric_queue_size"},
53  fhicl::Comment{"The maximum number of metric entries which can be stored in the metric queue."}, 1000};
56  fhicl::Atom<size_t> metric_queue_notify_size{
57  fhicl::Name{"metric_queue_notify_size"},
58  fhicl::Comment{
59  "The number of metric entries in the list which will cause reports of the queue size to be printed."},
60  10};
63  fhicl::Atom<int> metric_send_maximum_delay_ms{
64  fhicl::Name{"metric_send_maximum_delay_ms"},
65  fhicl::Comment{"The maximum amount of time between metric send calls (will send 0s for metrics which have not "
66  "reported in this interval)"},
67  15000};
69  fhicl::Atom<bool> send_system_metrics{fhicl::Name{"send_system_metrics"}, fhicl::Comment{"Whether to collect and send system metrics such as CPU usage, Memory usage and network activity."}, false};
71  fhicl::Atom<bool> send_process_metrics{fhicl::Name{"send_process_metrics"}, fhicl::Comment{"Whether to collect and send process CPU usage and Memory usage"}, false};
73  fhicl::OptionalTable<artdaq::MetricPlugin::Config> metricConfig{fhicl::Name{"metricConfig"}};
74  };
76  using Parameters = fhicl::WrappedTable<Config>;
77 
81  MetricManager();
82 
86  MetricManager(MetricManager const&) = delete;
87 
93  virtual ~MetricManager() noexcept;
94 
99  MetricManager& operator=(MetricManager const&) = delete;
100 
104  MetricManager(MetricManager&&) = delete;
109  MetricManager& operator=(MetricManager&&) = delete;
110 
124  void initialize(fhicl::ParameterSet const& pset, std::string const& prefix = "");
125 
129  void do_start();
130 
134  void do_stop();
135 
139  void do_pause();
140 
144  void do_resume();
145 
153  void reinitialize(fhicl::ParameterSet const& pset, std::string const& prefix = "");
154 
158  void shutdown();
159 
173  void sendMetric(std::string const& name, std::string const& value, std::string const& unit, int level,
174  MetricMode mode, std::string const& metricPrefix = "", bool useNameOverride = false);
175 
189  void sendMetric(std::string const& name, int const& value, std::string const& unit, int level, MetricMode mode,
190  std::string const& metricPrefix = "", bool useNameOverride = false);
191 
205  void sendMetric(std::string const& name, double const& value, std::string const& unit, int level, MetricMode mode,
206  std::string const& metricPrefix = "", bool useNameOverride = false);
207 
221  void sendMetric(std::string const& name, float const& value, std::string const& unit, int level, MetricMode mode,
222  std::string const& metricPrefix = "", bool useNameOverride = false);
223 
237  void sendMetric(std::string const& name, uint64_t const& value, std::string const& unit, int level,
238  MetricMode mode, std::string const& metricPrefix = "", bool useNameOverride = false);
239 
244  void setPrefix(std::string const& prefix) { prefix_ = prefix; }
245 
250  bool Initialized() { return initialized_; }
251 
256  bool Running() { return running_; }
257 
262  bool Active() { return active_; }
263 
268  bool metricQueueEmpty();
269 
274  bool metricManagerBusy();
275 
281  size_t metricQueueSize(std::string const& name = "");
282 
283 private:
284  void sendMetricLoop_();
285 
286  void startMetricLoop_();
287 
288  std::vector<std::unique_ptr<artdaq::MetricPlugin>> metric_plugins_;
289  boost::thread metric_sending_thread_;
290  std::mutex metric_mutex_;
291  std::condition_variable metric_cv_;
292  int metric_send_interval_ms_{15000};
293  int metric_holdoff_us_{1000};
294  std::chrono::steady_clock::time_point last_metric_received_;
295  std::unique_ptr<SystemMetricCollector> system_metric_collector_;
296 
297  std::atomic<bool> initialized_;
298  std::atomic<bool> running_;
299  std::atomic<bool> active_;
300  std::atomic<bool> busy_;
301  std::string prefix_;
302 
303  std::unordered_map<std::string, std::unique_ptr<MetricData>> metric_cache_;
304  std::mutex metric_cache_mutex_;
305  std::atomic<size_t> missed_metric_calls_;
306  std::atomic<size_t> metric_calls_;
307  size_t metric_cache_max_size_{1000};
308  size_t metric_cache_notify_size_{10};
309 
310  std::chrono::steady_clock::time_point last_failure_;
311 };
312 
313 #endif /* artdaq_DAQrate_MetricManager_hh */
fhicl::Atom< int > metric_send_maximum_delay_ms
void shutdown()
Call the destructors for all configured MetricPlugin instances.
void initialize(fhicl::ParameterSet const &pset, std::string const &prefix="")
Initialize the MetricPlugin instances.
bool Initialized()
Returns whether the MetricManager has been initialized (configured)
void sendMetric(std::string const &name, std::string const &value, std::string const &unit, int level, MetricMode mode, std::string const &metricPrefix="", bool useNameOverride=false)
Send a metric with the given parameters to any MetricPlugins with a threshold level &gt;= to level...
bool metricManagerBusy()
Determine whether the MetricManager or any of its plugins are currently processing metrics...
size_t metricQueueSize(std::string const &name="")
Return the size of the named metric queue
void reinitialize(fhicl::ParameterSet const &pset, std::string const &prefix="")
Reinitialize all MetricPlugin Instances.
MetricManager()
Construct an instance of the MetricManager class.
void do_start()
Perform startup actions for each configured MetricPlugin.
fhicl::Atom< size_t > metric_queue_notify_size
bool Running()
Returns whether the MetricManager is running (accepting metric calls)
void do_stop()
Stop sending metrics to the MetricPlugin instances.
virtual ~MetricManager() noexcept
MetricManager destructor.
void setPrefix(std::string const &prefix)
Sets the prefix prepended to all metrics without useNameOverride set.
The MetricManager class handles loading metric plugins and asynchronously sending metric data to them...
The Config struct defines the accepted configuration parameters for this class.
MetricMode
The Mode of the metric indicates how multiple metric values should be combined within a reporting int...
Definition: MetricData.hh:27
fhicl::OptionalTable< artdaq::MetricPlugin::Config > metricConfig
Example MetricPlugin Configuration.
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation (if desired)
bool Active()
Returns whether any Metric Plugins are defined and configured
fhicl::Atom< bool > send_system_metrics
&quot;send_system_metrics&quot;: (Default: false): Whether to collect and send system metrics such as CPU usage...
void do_resume()
Resume metric sending. Currently a No-Op.
bool metricQueueEmpty()
Returns whether the metric queue is completely empty
void do_pause()
Pause metric sending. Currently a No-Op.
fhicl::Atom< size_t > metric_queue_size
fhicl::Atom< bool > send_process_metrics
&quot;send_process_metrics&quot; (Default: false): Whether to collect and send process CPU usage and Memory usa...