7 #ifndef __METRIC_INTERFACE__
8 #define __METRIC_INTERFACE__
12 #include <unordered_map>
13 #include "fhiclcpp/ParameterSet.h"
14 #include "fhiclcpp/types/Atom.h"
15 #include "fhiclcpp/types/ConfigurationTable.h"
16 #include "fhiclcpp/types/Sequence.h"
18 #include "artdaq-utilities/Plugins/MetricData.hh"
19 #include "cetlib/compiler_macros.h"
21 #define FALLTHROUGH while (0)
38 fhicl::Atom<std::string>
metricPluginType{fhicl::Name{
"metricPluginType"}, fhicl::Comment{
"The name of the metric plugin to load (may have additional configuration parameters"}};
40 fhicl::Atom<size_t>
level{fhicl::Name{
"level"}, fhicl::Comment{
"The verbosity level threshold for this plugin. sendMetric calls with verbosity level greater than this will not be sent to the plugin. OPTIONAL"}, 0};
42 fhicl::Sequence<size_t>
metric_levels{fhicl::Name{
"metric_levels"}, fhicl::Comment{
"A list of levels that should be enabled for this plugin. OPTIONAL"}, std::vector<size_t>()};
44 fhicl::Atom<std::string>
level_string{fhicl::Name{
"level_string"}, fhicl::Comment{
"A string containing a comma-separated list of levels to enable. Ranges are supported. Example: \"1,2,4-10,11\" OPTIONAL"},
""};
46 fhicl::Atom<double>
reporting_interval{fhicl::Name{
"reporting_interval"}, fhicl::Comment{
"How often recorded metrics are sent to the underlying metric storage"}, 15.0};
59 explicit MetricPlugin(fhicl::ParameterSet
const& ps, std::string
const& app_name)
65 if (
pset.has_key(
"level"))
67 for (
size_t ii = 0; ii <=
pset.get<
size_t>(
"level"); ++ii)
72 if (
pset.has_key(
"metric_levels"))
74 auto levels =
pset.get<std::vector<size_t>>(
"metric_levels");
75 for (
auto& l : levels)
80 if (
pset.has_key(
"level_string"))
82 auto string =
pset.get<std::string>(
"level_string");
83 std::stringstream ss(
string);
85 while (std::getline(ss, token,
','))
87 auto it = token.find(
"-");
88 if (it == 0 || it == token.size() - 1)
continue;
90 if (it != std::string::npos)
92 auto minStr = token.substr(0, it);
93 auto maxStr = token.substr(it + 1);
94 auto min = std::stoi(minStr);
95 auto max = std::stoi(maxStr);
97 if (min > max) std::swap(min, max);
98 if (min > 63) min = 63;
99 if (max > 63) max = 63;
101 for (
int ii = min; ii <= max; ++ii)
108 auto level = std::stoi(token);
115 throw cet::exception(
"Configuration Error") <<
"No levels were enabled for this plugin! Please specify at least one of the following Parameters: \"level\", \"metric_levels\", or \"level_string\"!";
145 virtual void sendMetric_(
const std::string& name,
const std::string& value,
const std::string& unit) = 0;
155 virtual void sendMetric_(
const std::string& name,
const int& value,
const std::string& unit) = 0;
165 virtual void sendMetric_(
const std::string& name,
const double& value,
const std::string& unit) = 0;
175 virtual void sendMetric_(
const std::string& name,
const float& value,
const std::string& unit) = 0;
185 virtual void sendMetric_(
const std::string& name,
const long unsigned int& value,
const std::string& unit) = 0;
215 sendMetric_(data->Name, data->StringValue, data->Unit);
219 if (!metricRegistry_.count(data->Name))
221 metricRegistry_[data->Name] = *data;
223 metricData_[data->Name].push_back(*data);
237 std::chrono::steady_clock::time_point interval_end = std::chrono::steady_clock::now())
239 for (
auto metric : metricData_)
241 auto* metricName = &metric.first;
242 if (readyToSend_(*metricName) || forceSend)
244 if (metricData_[*metricName].size() == 0 && metricRegistry_.count(*metricName))
246 sendZero_(metricRegistry_[*metricName]);
248 else if (metricData_[*metricName].size() > 0)
250 MetricData& data = metricData_[*metricName].front();
251 auto it = ++(metricData_[*metricName].begin());
252 while (it != metricData_[*metricName].end())
255 it = metricData_[*metricName].erase(it);
258 std::bitset<32> modeSet(static_cast<uint32_t>(data.
Mode));
259 bool useSuffix =
true;
260 if (modeSet.count() <= 1) useSuffix =
false;
272 double average = 0.0;
294 double duration = std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
295 interval_end - interval_start_[*metricName])
301 rate = data.
Value.
d / duration;
304 rate = data.
Value.
f / duration;
307 rate = data.
Value.
i / duration;
310 rate = data.
Value.
u / duration;
326 metricData_[*metricName].clear();
328 interval_start_[*metricName] = interval_end;
346 for (
auto metric : metricRegistry_)
348 sendZero_(metric.second);
361 if (level > 63) level = 63;
362 if (level < 0)
return true;
374 std::unordered_map<std::string, std::list<MetricData>> metricData_;
375 std::unordered_map<std::string, MetricData> metricRegistry_;
376 std::unordered_map<std::string, std::chrono::steady_clock::time_point> lastSendTime_;
377 std::unordered_map<std::string, std::chrono::steady_clock::time_point> interval_start_;
379 bool readyToSend_(std::string name)
381 auto now = std::chrono::steady_clock::now();
382 if (std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(now - lastSendTime_[name]).count() >=
385 lastSendTime_[name] = now;
394 std::bitset<32> modeSet(static_cast<uint32_t>(data.
Mode));
395 bool useSuffix =
true;
396 if (modeSet.count() <= 1) useSuffix =
false;
443 void sendMetric_(std::string name, MetricData::MetricDataValue data, std::string unit,
MetricType type)
466 #endif //End ifndef __METRIC_INTERFACE__
bool IsLevelEnabled(int level)
Determine if the given level is enabled for this MetricPlugin instance.
virtual void startMetrics_()=0
Perform any start-up actions necessary for the metric plugin.
The MetricPlugin class defines the interface that MetricManager uses to send metric data to the vario...
void startMetrics()
Perform startup actions. Simply calls the virtual startMetrics_ function.
size_t DataPointCount
Number of data points accumulated in this MetricData
Report the sum of all values. Use for counters to report accurate results.
fhicl::ParameterSet pset
The ParameterSet used to configure the MetricPlugin.
fhicl::Atom< std::string > metricPluginType
The name of the metric plugin to load (may have additional configuration parameters.
virtual void sendMetric_(const std::string &name, const std::string &value, const std::string &unit)=0
Send a metric to the underlying metric storage (file, Graphite, Ganglia, etc.)
std::string Unit
Units of the metric
float f
Value of the metric, if it is a MetricType::FloatMetric.
Metric is a std::string (not in union)
std::string Name
Name of the metric
fhicl::Atom< double > reporting_interval
"reporting_interval" (Default: 15.0): The interval, in seconds, which the metric plugin will accumula...
MetricMode Mode
Accumulation mode of the metric
bool Add(MetricData other)
Add two MetricData instances together
MetricType
This enumeration is used to identify the type of the metric instance (which value should be extraced ...
MetricDataValue Max
Maximum recorded vaule of this MetricData.
void stopMetrics()
Perform shutdown actions. Zeroes out all accumulators, and sends zeros for each metric. Calls stopMetrics_() for any plugin-defined shutdown actions.
Reports the minimum value recorded.
std::string app_name_
Name of the application which is sending metrics to this plugin.
Metric is a long unsigned int.
void sendMetrics(bool forceSend=false, std::chrono::steady_clock::time_point interval_end=std::chrono::steady_clock::now())
For each known metric, determine whether the reporting interval has elapsed, and if so...
MetricPlugin(fhicl::ParameterSet const &ps, std::string const &app_name)
MetricPlugin Constructor.
Report only the last value recorded. Useful for event counters, run numbers, etc. ...
Repots the maximum value recorded.
std::bitset< 64 > level_mask_
Bitset indicating for each possible metric level, whether this plugin will receive those metrics...
virtual std::string getLibName() const
Return the name of the current MetricPlugin instance.
MetricDataValue Value
Accumulated value of this MetricData
virtual void stopMetrics_()=0
Perform any shutdown actions necessary for the metric plugin.
int i
Value of the metric, if it is a MetricType::IntMetric.
MetricType Type
Type of the metric
fhicl::Atom< std::string > level_string
"level_string" (OPTIONAL): A string containing a comma-separated list of levels to enable...
long unsigned int u
Value of the metric, if it is a MetricType::UnsignedMetric.
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation (if desired)
This union holds the values for all other metric types
MetricDataValue Last
Last value of this MetricData.
fhicl::Atom< size_t > level
"level" (OPTIONAL): The verbosity level threshold for this plugin. sendMetric calls with verbosity le...
double accumulationTime_
The amount of time to average metric values; except for accumulate=false metrics, will be the interva...
Small structure used to hold a metric data point before sending to the metric plugins ...
The Config struct defines the accepted configuration parameters for this class.
Report the average of all values. Use for rates to report accurate results.
MetricDataValue Min
Minimum recorded value of this MetricData.
fhicl::Sequence< size_t > metric_levels
"metric_levels" (OPTIONAL): A list of levels that should be enabled for this plugin.
void addMetricData(std::unique_ptr< MetricData > const &data)
Send a metric value to the MetricPlugin.
virtual ~MetricPlugin()=default
Default virtual Desctructor.
double d
Value of the metric, if it is a MetricType::DoubleMetric.
bool inhibit_
Flag to indicate that the MetricPlugin is being stopped, and any metric back-ends which do not have a...