|
15 | 15 | #include <vector> |
16 | 16 | #include "MonLogger.h" |
17 | 17 | #include "VariantVisitorRate.h" |
| 18 | +#include "VariantVisitorAdd.h" |
18 | 19 |
|
19 | 20 | namespace o2 |
20 | 21 | { |
21 | 22 | /// ALICE O2 Monitoring system |
22 | 23 | namespace monitoring |
23 | 24 | { |
24 | 25 |
|
25 | | -DerivedMetrics::DerivedMetrics(const unsigned int cacheSize) : mMaxVectorSize(cacheSize) |
| 26 | +Metric DerivedMetrics::rate(Metric& metric) |
26 | 27 | { |
27 | | -} |
28 | | - |
29 | | -void DerivedMetrics::registerMetric(std::string name, DerivedMetricMode mode) |
30 | | -{ |
31 | | - mRegistered.emplace(std::pair<std::string, DerivedMetricMode>(name, mode)); |
32 | | - MonLogger::Get() << "Monitoring : Metric " << name << " added to derived metrics" |
33 | | - << MonLogger::End(); |
34 | | -} |
35 | | - |
36 | | -bool DerivedMetrics::isRegistered(std::string name) |
37 | | -{ |
38 | | - auto search = mRegistered.find(name); |
39 | | - return (search != mRegistered.end()); |
40 | | -} |
| 28 | + // disallow string |
| 29 | + std::string name = metric.getName(); |
| 30 | + if (metric.getType() == MetricType::STRING) { |
| 31 | + throw MonitoringInternalException("DerivedMetrics/ProcessMetric", "Not able to process string values"); |
| 32 | + } |
41 | 33 |
|
42 | | -Metric DerivedMetrics::calculateRate(std::string name) |
43 | | -{ |
44 | | - auto search = mCache.find(name); |
45 | | - int size = search->second.size(); |
46 | | - if (search == mCache.end() || size < 2) { |
47 | | - throw MonitoringInternalException("DerivedMetrics/Calculate rate", "Not enough values"); |
| 34 | + // search for previous value |
| 35 | + auto search = mStorage.find(name); |
| 36 | + if (search == mStorage.end()) { |
| 37 | + mStorage.insert(std::make_pair(name, metric)); |
| 38 | + return Metric{(double) 0.0, name + "Rate"}; |
48 | 39 | } |
49 | 40 |
|
50 | 41 | auto timestampDifference = std::chrono::duration_cast<std::chrono::milliseconds>( |
51 | | - search->second.at(size - 1).getTimestamp() |
52 | | - - search->second.at(size - 2).getTimestamp() |
| 42 | + metric.getTimestamp() |
| 43 | + - search->second.getTimestamp() |
53 | 44 | ); |
54 | | - boost::variant< int, std::string, double, uint64_t > current = search->second.at(size - 1).getValue(); |
55 | | - boost::variant< int, std::string, double, uint64_t > previous = search->second.at(size - 2).getValue(); |
56 | 45 | int timestampCount = timestampDifference.count(); |
57 | | - |
58 | 46 | // disallow dividing by 0 |
59 | 47 | if (timestampCount == 0) { |
60 | 48 | throw MonitoringInternalException("DerivedMetrics/Calculate rate", "Division by 0"); |
61 | 49 | } |
62 | 50 |
|
| 51 | + auto current = metric.getValue(); |
| 52 | + auto previous = search->second.getValue(); |
63 | 53 | auto rate = boost::apply_visitor(VariantVisitorRate(timestampCount), current, previous); |
64 | | - return Metric{rate, name + "Rate"}; |
65 | | -} |
66 | 54 |
|
67 | | -Metric DerivedMetrics::calculateAverage(std::string name) |
68 | | -{ |
69 | | - double total = 0; |
70 | | - for (auto& m : mCache.at(name)) { |
71 | | - total += boost::lexical_cast<double>(m.getValue()); |
72 | | - } |
73 | | - double average = total / mCache.at(name).size(); |
74 | | - return Metric{average, name + "Average"}; |
| 55 | + // swap metrics |
| 56 | + mStorage.erase(name); |
| 57 | + mStorage.insert(std::make_pair(name, metric)); |
| 58 | + |
| 59 | + return Metric{rate, name + "Rate"}; |
75 | 60 | } |
76 | 61 |
|
77 | | -Metric DerivedMetrics::processMetric(Metric& metric) |
78 | | -{ |
| 62 | +Metric DerivedMetrics::increment(Metric& metric) { |
79 | 63 | std::string name = metric.getName(); |
80 | | - if (metric.getType() == MetricType::STRING) { |
81 | | - throw MonitoringInternalException("DerivedMetrics/ProcessMetric", "Not able to process string values"); |
82 | | - } |
83 | | - auto search = mCache.find(name); |
84 | | - // create vector if this is first metric of this kind |
85 | | - if (search == mCache.end()) { |
86 | | - mCache.emplace(std::make_pair(name, std::vector<Metric>())); |
87 | | - } |
88 | | - // remove first value if vector too large |
89 | | - if (mCache.at(name).size() > mMaxVectorSize) { |
90 | | - mCache.at(name).erase( mCache.at(name).begin() ); |
91 | | - } |
92 | | - mCache[name].push_back(metric); |
93 | | - |
94 | | - auto derived = mRegistered.find(name); |
95 | | - if (derived->second == DerivedMetricMode::RATE) { |
96 | | - return calculateRate(name); |
97 | | - } |
98 | | - else if (derived->second == DerivedMetricMode::AVERAGE) { |
99 | | - return calculateAverage(name); |
100 | | - } else { |
101 | | - throw MonitoringInternalException("DerivedMetrics/ProcessMetric", "Processing mode not supported"); |
| 64 | + auto search = mStorage.find(name); |
| 65 | + if (search != mStorage.end()) { |
| 66 | + auto currentValue = metric.getValue(); |
| 67 | + auto storedValue = search->second.getValue(); |
| 68 | + auto value = boost::apply_visitor(VariantVisitorAdd(), currentValue, storedValue); |
| 69 | + mStorage.erase(search); |
| 70 | + Metric result = Metric{value, name}; |
| 71 | + mStorage.insert(std::make_pair(name, result)); |
| 72 | + return result; |
102 | 73 | } |
| 74 | + mStorage.insert(std::make_pair(name, metric)); |
| 75 | + return metric; |
103 | 76 | } |
104 | 77 |
|
105 | 78 | } // namespace monitoring |
|
0 commit comments