8 #ifndef __METRIC_INTERFACE__
9 #define __METRIC_INTERFACE__
13 #include <unordered_map>
14 #include "fhiclcpp/ParameterSet.h"
15 #include "fhiclcpp/types/Atom.h"
16 #if MESSAGEFACILITY_HEX_VERSION >= 0x20103
17 # include "fhiclcpp/types/ConfigurationTable.h"
20 #include "artdaq-utilities/Plugins/MetricData.hh"
21 #include "cetlib/compiler_macros.h"
23 #define FALLTHROUGH while(0)
41 fhicl::Atom<std::string>
metricPluginType{ fhicl::Name{
"metricPluginType"}, fhicl::Comment{
"The name of the metric plugin to load (may have additional configuration parameters"} };
43 fhicl::Atom<int>
level{ fhicl::Name{
"level"}, fhicl::Comment{
"The verbosity level threshold for this plugin. Metrics with verbosity level greater than this will not be sent to the plugin"}, 0 };
45 fhicl::Atom<double>
reporting_interval{ fhicl::Name{
"reporting_interval"}, fhicl::Comment{
"How often recorded metrics are sent to the underlying metric storage"}, 15.0 };
47 #if MESSAGEFACILITY_HEX_VERSION >= 0x20103
48 using Parameters = fhicl::WrappedTable<Config>;
65 explicit MetricPlugin(fhicl::ParameterSet
const& ps, std::string
const& app_name) :
pset(ps)
87 virtual std::string
getLibName()
const {
return "ERROR"; }
97 virtual void sendMetric_(
const std::string& name,
const std::string& value,
const std::string& unit) = 0;
107 virtual void sendMetric_(
const std::string& name,
const int& value,
const std::string& unit) = 0;
117 virtual void sendMetric_(
const std::string& name,
const double& value,
const std::string& unit) = 0;
127 virtual void sendMetric_(
const std::string& name,
const float& value,
const std::string& unit) = 0;
137 virtual void sendMetric_(
const std::string& name,
const long unsigned int& value,
const std::string& unit) = 0;
171 if (!metricRegistry_.count(data.
Name))
173 metricRegistry_[data.
Name] = data;
175 metricData_[data.
Name].push_back(data);
185 void sendMetrics(
bool forceSend =
false, std::chrono::steady_clock::time_point interval_end = std::chrono::steady_clock::now())
187 for (
auto metric : metricData_)
189 auto metricName = metric.first;
190 if (readyToSend_(metricName) || forceSend)
192 if (metricData_[metricName].size() == 0 && metricRegistry_.count(metricName))
194 sendZero_(metricRegistry_[metricName]);
196 else if (metricData_[metricName].size() > 0)
198 auto metricMode = metricData_[metricName].back().Mode;
199 auto metricUnits = metricData_[metricName].back().Unit;
200 auto metricType = metricData_[metricName].back().Type;
204 if (metricData_[metricName].size() > 1)
206 metricData_[metricName].erase(metricData_[metricName].begin(), std::prev(metricData_[metricName].end()));
217 for (
auto& mv : metricData_[metricName]) { ds += mv.DoubleValue; }
220 case MetricMode::Average: ds /=
static_cast<double>(metricData_[metricName].size());
break;
221 case MetricMode::Rate: ds /= std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count();
break;
222 case MetricMode::AccumulateAndRate:
sendMetric_(metricName +
" - Rate", ds / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count(), metricUnits +
"/s");
break;
233 for (
auto& mv : metricData_[metricName]) { fs += mv.FloatValue; }
238 ds = fs /
static_cast<double>(metricData_[metricName].size());
242 ds = fs / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count();
246 sendMetric_(metricName +
" - Rate", fs / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count(), metricUnits +
"/s");
259 for (
auto& mv : metricData_[metricName]) { is += mv.IntValue; }
264 ds = is /
static_cast<double>(metricData_[metricName].size());
268 ds = is / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count();
272 sendMetric_(metricName +
" - Rate", is / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count(), metricUnits +
"/s");
285 for (
auto& mv : metricData_[metricName]) { us += mv.UnsignedValue; }
290 ds = us /
static_cast<double>(metricData_[metricName].size());
294 ds = us / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count();
298 sendMetric_(metricName +
" - Rate", us / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(interval_end - interval_start_[metricName]).count(), metricUnits +
"/s");
310 metricData_[metricName].clear();
313 interval_start_[metricName] = interval_end;
331 for (
auto metric : metricRegistry_)
333 sendZero_(metric.second);
358 std::unordered_map<std::string, std::list<MetricData>> metricData_;
359 std::unordered_map<std::string, MetricData> metricRegistry_;
360 std::unordered_map<std::string, std::chrono::steady_clock::time_point> lastSendTime_;
361 std::unordered_map<std::string, std::chrono::steady_clock::time_point> interval_start_;
363 bool readyToSend_(std::string name)
365 auto now = std::chrono::steady_clock::now();
366 if (std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(now - lastSendTime_[name]).count() >=
accumulationTime_)
368 lastSendTime_[name] = now;
406 sendMetric_(data.Name, data.DoubleValue, data.Unit);
409 sendMetric_(data.Name, data.FloatValue, data.Unit);
415 sendMetric_(data.Name, data.UnsignedValue, data.Unit);
424 #endif //End ifndef __METRIC_INTERFACE__
virtual void startMetrics_()=0
Perform any start-up actions necessary for the metric plugin.
std::string StringValue
Value of the metric, if it is a MetricType::StringMetric
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.
Report the average of all values. Use for rates 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
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...
Reports the sum of all values, divided by the length of the time interval they were accumulated over...
MetricMode Mode
Accumulation mode of the metric
void addMetricData(MetricData data)
Send a metric value to the MetricPlugin.
void stopMetrics()
Perform shutdown actions. Zeroes out all accumulators, and sends zeros for each metric. Calls stopMetrics_() for any plugin-defined shutdown actions.
fhicl::Atom< int > level
"level" (Default: 0): The verbosity level of the metric plugin. Higher number = fewer metrics sent to...
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...
int getRunLevel() const
Get the threshold for sending metrics to the underlying storage.
MetricPlugin(fhicl::ParameterSet const &ps, std::string const &app_name)
MetricPlugin Constructor.
virtual std::string getLibName() const
Return the name of the current MetricPlugin instance.
virtual void stopMetrics_()=0
Perform any shutdown actions necessary for the metric plugin.
Sends both the Accumulate mode and Rate mode metric. (Rate mode metric will append "/s" to metric uni...
MetricType Type
Type of the metric
Report the sum of all values. Use for counters to report accurate results.
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 only the last value recorded. Useful for event counters, run numbers, etc. ...
virtual ~MetricPlugin()=default
Default virtual Desctructor.
void setRunLevel(int level)
Set the threshold for sending metrics to the underlying storage.
bool inhibit_
Whether to inhibit all metric sending.
int runLevel_
The threshold for sending metrics to the underlying storage. Metrics with level <= to runLevel_ will ...