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 };
44 using Parameters = fhicl::WrappedTable<Config>;
60 explicit MetricPlugin(fhicl::ParameterSet
const& ps, std::string
const& app_name) :
pset(ps)
71 virtual ~MetricPlugin() =
default;
82 virtual std::string getLibName()
const {
return "ERROR"; }
93 virtual void sendMetric_(
const std::string& name,
const std::string& value,
const std::string& unit) = 0;
103 virtual void sendMetric_(
const std::string& name,
const int& value,
const std::string& unit) = 0;
113 virtual void sendMetric_(
const std::string& name,
const double& value,
const std::string& unit) = 0;
123 virtual void sendMetric_(
const std::string& name,
const float& value,
const std::string& unit) = 0;
133 virtual void sendMetric_(
const std::string& name,
const long unsigned int& value,
const std::string& unit) = 0;
140 virtual void startMetrics_() = 0;
147 virtual void stopMetrics_() = 0;
159 void addMetricData(std::unique_ptr<MetricData>
const& data)
163 sendMetric_(data->Name, data->StringValue, data->Unit);
167 if (!metricRegistry_.count(data->Name))
169 metricRegistry_[data->Name] = *data;
171 metricData_[data->Name].push_back(*data);
184 void sendMetrics(
bool forceSend =
false,
185 std::chrono::steady_clock::time_point interval_end = std::chrono::steady_clock::now()) {
192 for (
auto metric : metricData_) {
193 auto *metricName = &metric.first;
195 if (readyToSend_(*metricName) || forceSend) {
196 if (metricData_[*metricName].size() == 0 && metricRegistry_.count(*metricName)) {
197 sendZero_(metricRegistry_[*metricName]);
198 }
else if (metricData_[*metricName].size() > 0) {
199 auto metricMode = &metricData_[*metricName].back().Mode;
200 auto metricUnits = &metricData_[*metricName].back().Unit;
201 auto metricType = &metricData_[*metricName].back().Type;
204 if (metricData_[*metricName].size() > 1) {
205 metricData_[*metricName].erase(metricData_[*metricName].begin(),
206 std::prev(metricData_[*metricName].end()));
208 sendMetric_(metricData_[*metricName].back());
210 switch (*metricType) {
213 for (
auto& mv : metricData_[*metricName]) {
214 ds += mv.DoubleValue;
215 count += mv.DataPointCount;
217 switch (*metricMode) {
219 ds /=
static_cast<double>(count);
222 ds /= std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
223 interval_end - interval_start_[*metricName])
227 sendMetric_(*metricName +
" - Rate",
228 ds / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
229 interval_end - interval_start_[*metricName])
231 *metricUnits +
"/s");
236 sendMetric_(*metricName, ds, *metricUnits);
240 for (
auto& mv : metricData_[*metricName]) {
242 count += mv.DataPointCount;
245 switch (*metricMode) {
247 ds = fs /
static_cast<double>(count);
248 sendMetric_(*metricName, ds, *metricUnits);
251 ds = fs / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
252 interval_end - interval_start_[*metricName])
254 sendMetric_(*metricName, ds, *metricUnits);
257 sendMetric_(*metricName +
" - Rate",
258 fs / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
259 interval_end - interval_start_[*metricName])
261 *metricUnits +
"/s");
265 sendMetric_(*metricName, fs, *metricUnits);
271 for (
auto& mv : metricData_[*metricName]) {
273 count += mv.DataPointCount;
276 switch (*metricMode) {
278 ds = is /
static_cast<double>(count);
279 sendMetric_(*metricName, ds, *metricUnits);
282 ds = is / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
283 interval_end - interval_start_[*metricName])
285 sendMetric_(*metricName, ds, *metricUnits);
288 sendMetric_(*metricName +
" - Rate",
289 is / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
290 interval_end - interval_start_[*metricName])
292 *metricUnits +
"/s");
296 sendMetric_(*metricName, is, *metricUnits);
302 for (
auto& mv : metricData_[*metricName]) {
303 us += mv.UnsignedValue;
304 count += mv.DataPointCount;
307 switch (*metricMode) {
309 ds = us /
static_cast<double>(count);
310 sendMetric_(*metricName, ds, *metricUnits);
313 ds = us / std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(
314 interval_end - interval_start_[*metricName])
316 sendMetric_(*metricName, ds, *metricUnits);
319 sendMetric_(*metricName +
" - Rate",
320 us / std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(
321 interval_end - interval_start_[*metricName])
323 *metricUnits +
"/s");
327 sendMetric_(*metricName, us, *metricUnits);
334 metricData_[*metricName].clear();
337 interval_start_[*metricName] = interval_end;
345 void startMetrics() { startMetrics_(); }
354 for (
auto metric : metricRegistry_) {
355 sendZero_(metric.second);
366 void setRunLevel(
int level) {
runLevel_ = level; }
372 int getRunLevel()
const {
return runLevel_; }
376 fhicl::ParameterSet
pset;
384 std::unordered_map<std::string, std::list<MetricData>> metricData_;
385 std::unordered_map<std::string, MetricData> metricRegistry_;
386 std::unordered_map<std::string, std::chrono::steady_clock::time_point> lastSendTime_;
387 std::unordered_map<std::string, std::chrono::steady_clock::time_point> interval_start_;
389 bool readyToSend_(std::string name) {
390 auto now = std::chrono::steady_clock::now();
391 if (std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(now - lastSendTime_[name]).count() >=
393 lastSendTime_[name] = now;
403 sendMetric_(data.
Name, static_cast<double>(0.0), data.
Unit);
406 sendMetric_(data.
Name, static_cast<float>(0.0), data.
Unit);
409 sendMetric_(data.
Name, static_cast<int>(0), data.
Unit);
412 sendMetric_(data.
Name, static_cast<unsigned long>(0), data.
Unit);
419 sendMetric_(data.
Name +
" - Rate", static_cast<double>(0.0), data.
Unit +
"/s");
423 void sendMetric_(MetricData data) {
426 sendMetric_(data.Name, data.DoubleValue, data.Unit);
429 sendMetric_(data.Name, data.FloatValue, data.Unit);
432 sendMetric_(data.Name, data.IntValue, data.Unit);
435 sendMetric_(data.Name, data.UnsignedValue, data.Unit);
444 #endif //End ifndef __METRIC_INTERFACE__
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.
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
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.
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.
Small structure used to hold a metric data point before sending to the metric plugins ...
Report only the last value recorded. Useful for event counters, run numbers, etc. ...
bool inhibit_
Whether to inhibit all metric sending.