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"
17 #include "artdaq-utilities/Plugins/MetricData.hh"
18 #include "cetlib/compiler_macros.h"
20 #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<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 };
42 fhicl::Atom<double>
reporting_interval{ fhicl::Name{
"reporting_interval"}, fhicl::Comment{
"How often recorded metrics are sent to the underlying metric storage"}, 15.0 };
61 explicit MetricPlugin(fhicl::ParameterSet
const& ps, std::string
const& app_name) :
pset(ps)
83 virtual std::string
getLibName()
const {
return "ERROR"; }
94 virtual void sendMetric_(
const std::string& name,
const std::string& value,
const std::string& unit) = 0;
104 virtual void sendMetric_(
const std::string& name,
const int& value,
const std::string& unit) = 0;
114 virtual void sendMetric_(
const std::string& name,
const double& value,
const std::string& unit) = 0;
124 virtual void sendMetric_(
const std::string& name,
const float& value,
const std::string& unit) = 0;
134 virtual void sendMetric_(
const std::string& name,
const long unsigned int& value,
const std::string& unit) = 0;
164 sendMetric_(data->Name, data->StringValue, data->Unit);
168 if (!metricRegistry_.count(data->Name))
170 metricRegistry_[data->Name] = *data;
172 metricData_[data->Name].push_back(*data);
186 std::chrono::steady_clock::time_point interval_end = std::chrono::steady_clock::now()) {
193 for (
auto metric : metricData_) {
194 auto *metricName = &metric.first;
196 if (readyToSend_(*metricName) || forceSend) {
197 if (metricData_[*metricName].size() == 0 && metricRegistry_.count(*metricName)) {
198 sendZero_(metricRegistry_[*metricName]);
199 }
else if (metricData_[*metricName].size() > 0) {
200 auto metricMode = &metricData_[*metricName].back().Mode;
201 auto metricUnits = &metricData_[*metricName].back().Unit;
202 auto metricType = &metricData_[*metricName].back().Type;
205 if (metricData_[*metricName].size() > 1) {
206 metricData_[*metricName].erase(metricData_[*metricName].begin(),
207 std::prev(metricData_[*metricName].end()));
211 switch (*metricType) {
214 for (
auto& mv : metricData_[*metricName]) {
215 ds += mv.DoubleValue;
216 count += mv.DataPointCount;
218 switch (*metricMode) {
220 ds /=
static_cast<double>(count);
223 ds /= std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
224 interval_end - interval_start_[*metricName])
229 ds / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
230 interval_end - interval_start_[*metricName])
232 *metricUnits +
"/s");
241 for (
auto& mv : metricData_[*metricName]) {
243 count += mv.DataPointCount;
246 switch (*metricMode) {
248 ds = fs /
static_cast<double>(count);
252 ds = fs / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
253 interval_end - interval_start_[*metricName])
259 fs / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
260 interval_end - interval_start_[*metricName])
262 *metricUnits +
"/s");
272 for (
auto& mv : metricData_[*metricName]) {
274 count += mv.DataPointCount;
277 switch (*metricMode) {
279 ds = is /
static_cast<double>(count);
283 ds = is / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
284 interval_end - interval_start_[*metricName])
290 is / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
291 interval_end - interval_start_[*metricName])
293 *metricUnits +
"/s");
303 for (
auto& mv : metricData_[*metricName]) {
304 us += mv.UnsignedValue;
305 count += mv.DataPointCount;
308 switch (*metricMode) {
310 ds = us /
static_cast<double>(count);
314 ds = us / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
315 interval_end - interval_start_[*metricName])
321 us / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
322 interval_end - interval_start_[*metricName])
324 *metricUnits +
"/s");
335 metricData_[*metricName].clear();
338 interval_start_[*metricName] = interval_end;
355 for (
auto metric : metricRegistry_) {
356 sendZero_(metric.second);
378 fhicl::ParameterSet
pset;
386 std::unordered_map<std::string, std::list<MetricData>> metricData_;
387 std::unordered_map<std::string, MetricData> metricRegistry_;
388 std::unordered_map<std::string, std::chrono::steady_clock::time_point> lastSendTime_;
389 std::unordered_map<std::string, std::chrono::steady_clock::time_point> interval_start_;
391 bool readyToSend_(std::string name) {
392 auto now = std::chrono::steady_clock::now();
393 if (std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(now - lastSendTime_[name]).count() >=
395 lastSendTime_[name] = now;
428 sendMetric_(data.Name, data.DoubleValue, data.Unit);
431 sendMetric_(data.Name, data.FloatValue, data.Unit);
437 sendMetric_(data.Name, data.UnsignedValue, data.Unit);
446 #endif //End ifndef __METRIC_INTERFACE__
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.
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
"metricPluginType": The name of the metric plugin to load (may have additional configuration paramete...
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 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
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation (if desired)
Report the sum of all values. Use for counters to report accurate results.
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. ...
void addMetricData(std::unique_ptr< MetricData > const &data)
Send a metric value to the MetricPlugin.
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.