25#include <unordered_set>
58 char const* cur = s.data();
59 char const* next = s.data();
63 char const* lastSpace =
nullptr;
64 char const* previousLastSpace =
nullptr;
67 auto previousState =
state;
70 switch (previousState) {
72 if (strncmp(cur,
"[METRIC] ", 9) == 0) {
75 match.beginKey = cur + 9;
79 next = strpbrk(cur,
",/\n");
80 if (next ==
nullptr || *next ==
'\n' || ((cur == next) && (
match.endKey -
match.beginKey == 0))) {
81 }
else if (*next ==
'/') {
89 }
else if (*next ==
',') {
95 match.firstIndex = strtol(cur, &err, 10);
99 }
else if (*next ==
',') {
110 match.firstIndex = -1;
111 match.endKey = next + 1;
116 match.lastIndex = strtol(cur, &err, 10);
119 }
else if (*next ==
',') {
127 }
else if (*next ==
' ') {
136 match.beginStringValue = next + 1;
137 match.endStringValue = next + 1;
141 if (strncmp(
match.beginKey,
"data_relayer/", 13) == 0 &&
match.beginKey[13] !=
'w' &&
match.beginKey[13] !=
'h') {
147 match.intValue = strtol(cur, &err, 10);
150 }
else if (*next ==
' ') {
157 match.uint64Value = strtoull(cur, &err, 10);
160 }
else if (*next ==
' ') {
167 match.floatValue = strtof(cur, &err);
170 }
else if (*next ==
' ') {
177 next = (
char*)memchr(cur,
' ', s.data() + s.size() - cur);
178 if (next ==
nullptr) {
179 auto timestamp = strtoull(cur, &err, 10);
180 if (*err !=
'\n' && *err !=
'\0') {
184 match.endStringValue = previousLastSpace;
185 next = previousLastSpace;
189 match.endStringValue = lastSpace;
190 match.timestamp = timestamp;
196 }
else if (*next ==
' ') {
197 previousLastSpace = lastSpace;
204 match.timestamp = strtoull(cur, &err, 10);
207 }
else if (*next ==
' ') {
209 }
else if (next == s.data() + s.size() || *next ==
'\n') {
227static auto updatePrefix = [](std::string_view prefix,
DeviceMetricsInfo& info,
bool hasPrefix, std::vector<MetricPrefixIndex>::iterator pi) ->
void {
231 metricPrefix.
size = prefix.size();
232 memcpy(metricPrefix.
prefix, prefix.data(), prefix.size());
233 metricPrefix.
prefix[prefix.size()] =
'\0';
236 metricPrefixIdx.
index = info.metricPrefixes.size();
237 info.metricPrefixes.push_back(metricPrefix);
239 auto sortedInsert = std::distance(info.metricLabelsPrefixesSortedIdx.begin(), pi);
240 info.metricLabelsPrefixesSortedIdx.insert(info.metricLabelsPrefixesSortedIdx.begin() + sortedInsert, metricPrefixIdx);
242 auto previousEnd = 0;
243 if (sortedInsert != 0) {
244 previousEnd = info.metricPrefixes[info.metricLabelsPrefixesSortedIdx[sortedInsert - 1].index].end;
246 info.metricPrefixes[info.metricLabelsPrefixesSortedIdx[sortedInsert].index].begin = previousEnd;
247 info.metricPrefixes[info.metricLabelsPrefixesSortedIdx[sortedInsert].index].end = previousEnd + 1;
248 for (
size_t i = sortedInsert + 1;
i < info.metricLabelsPrefixesSortedIdx.size();
i++) {
249 info.metricPrefixes[info.metricLabelsPrefixesSortedIdx[
i].index].begin++;
250 info.metricPrefixes[info.metricLabelsPrefixesSortedIdx[
i].index].end++;
253 info.metricPrefixes[pi->index].end++;
254 auto insertLocation = std::distance(info.metricLabelsPrefixesSortedIdx.begin(), pi);
255 for (
size_t i = insertLocation + 1;
i < info.metricLabelsPrefixesSortedIdx.size();
i++) {
256 info.metricPrefixes[info.metricLabelsPrefixesSortedIdx[
i].index].begin++;
257 info.metricPrefixes[info.metricLabelsPrefixesSortedIdx[
i].index].end++;
262static constexpr int DPL_MAX_METRICS_PER_DEVICE = 1024 * 128;
264static auto initMetric = [](DeviceMetricsInfo& info) ->
void {
266 info.max.push_back(std::numeric_limits<float>::lowest());
267 info.min.push_back(std::numeric_limits<float>::max());
268 info.average.push_back(0);
269 info.maxDomain.push_back(std::numeric_limits<size_t>::lowest());
270 info.minDomain.push_back(std::numeric_limits<size_t>::max());
271 info.changed.push_back(
false);
272 if (info.metricLabels.size() > DPL_MAX_METRICS_PER_DEVICE) {
273 for (
size_t i = 0;
i < info.metricLabels.size();
i++) {
274 std::cout << info.metricLabels[
i].label << std::endl;
276 throw runtime_error_f(
"Too many metrics for a given device. Max is DPL_MAX_METRICS_PER_DEVICE=%d.", DPL_MAX_METRICS_PER_DEVICE);
328 throw std::runtime_error(
"Unknown metric type");
339 auto slash =
key.find_first_of(
"/");
340 if (slash == std::string_view::npos) {
343 auto prefix = std::string_view(
key.data(), slash);
347 return std::string_view(prefixes[
a.index].prefix, prefixes[
a.index].size) <
b;
361 return std::string_view(labels[
a.index].label +
offset, labels[
a.index].size -
offset) < std::string_view(
b.data() +
offset,
b.size() -
offset);
363 auto mi = std::lower_bound(rb, re,
key, cmpFn);
376 metricLabel.
size = strlen(metricLabel.
label);
384 auto metricIndex = info.
metrics.size();
392 updatePrefix(prefix, info, hasPrefix, pi);
393 info.
metrics.emplace_back(metricInfo);
403 size_t metricIndex = -1;
406 switch (
match.type) {
414 memcpy(stringValue.
data,
match.beginStringValue, lastChar);
415 stringValue.
data[lastChar] =
'\0';
425 auto slash =
key.find_first_of(
"/");
426 if (slash == std::string_view::npos) {
429 auto prefix = std::string_view(
key.data(), slash);
433 return std::string_view(prefixes[
a.index].prefix, prefixes[
a.index].size) <
b;
450 auto mi = std::lower_bound(rb, re,
key, cmpFn);
465 memcpy(metricLabel.
label,
match.beginKey, lastChar);
466 metricLabel.
label[lastChar] =
'\0';
467 metricLabel.
size = lastChar;
473 updatePrefix(prefix, info, hasPrefix, pi);
476 metricIndex = info.
metrics.size();
477 assert(metricInfo.storeIdx != -1);
478 assert(metricLabel.
label[0] !=
'\0');
479 if (newMetricsCallback !=
nullptr) {
480 newMetricsCallback(metricLabel.
label, metricInfo,
match.intValue, metricIndex);
482 info.
metrics.push_back(metricInfo);
484 metricIndex = mi->index;
486 assert(metricIndex != -1);
491 auto sizeOfCollection = 0;
492 switch (metricInfo.
type) {
527 info.
max[metricIndex] = std::max(info.
max[metricIndex],
match.floatValue);
528 info.
min[metricIndex] = std::min(info.
min[metricIndex],
match.floatValue);
529 auto onlineAverage = [](
float nextValue,
float previousAverage,
float previousCount) {
530 return previousAverage + (nextValue - previousAverage) / (previousCount + 1);
534 metricInfo.
pos = (metricInfo.
pos + 1) % sizeOfCollection;
537 info.
changed[metricIndex] =
true;
548 if (metricName.size() ==
name.size() && metricName[metricName.size() - 1] ==
name[
name.size() - 1] && metricName ==
name) {
bool match(const std::vector< std::string > &queries, const char *pattern)
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLint GLint GLsizei GLint GLenum GLenum type
GLboolean GLboolean GLboolean GLboolean a
Defining PrimaryVertex explicitly as messageable.
std::array< size_t, metricStorageSize< T >()> TimestampsStorage
std::array< T, metricStorageSize< T >()> MetricsStorage
RuntimeErrorRef runtime_error_f(const char *,...)
static bool parseMetric(std::string_view const s, ParsedMetricMatch &results)
Helper function to parse a metric string.
static bool processMetric(ParsedMetricMatch &results, DeviceMetricsInfo &info, NewMetricCallback newMetricCallback=nullptr)
static size_t bookMetricInfo(DeviceMetricsInfo &metrics, char const *name, MetricType type)
static size_t metricIdxByName(std::string_view const name, const DeviceMetricsInfo &info)
std::function< void(std::string const &, MetricInfo const &, int value, size_t metricIndex)> NewMetricCallback
std::vector< size_t > maxDomain
std::vector< MetricsStorage< float > > floatMetrics
std::vector< float > average
std::vector< MetricsStorage< StringMetric > > stringMetrics
std::vector< std::array< size_t, metricStorageSize< int8_t >()> > enumTimestamps
std::vector< MetricsStorage< uint64_t > > uint64Metrics
std::vector< MetricsStorage< int > > intMetrics
std::vector< MetricPrefix > metricPrefixes
std::vector< std::array< size_t, metricStorageSize< float >()> > floatTimestamps
std::vector< MetricLabel > metricLabels
std::vector< std::array< size_t, metricStorageSize< uint64_t >()> > uint64Timestamps
std::vector< std::array< size_t, metricStorageSize< StringMetric >()> > stringTimestamps
std::vector< size_t > minDomain
std::vector< bool > changed
std::vector< MetricPrefixIndex > metricLabelsPrefixesSortedIdx
std::vector< MetricLabelIndex > metricLabelsAlphabeticallySortedIdx
std::vector< MetricInfo > metrics
std::vector< MetricsStorage< int8_t > > enumMetrics
std::vector< std::array< size_t, metricStorageSize< int >()> > intTimestamps
char label[MAX_METRIC_LABEL_SIZE]
static constexpr size_t MAX_METRIC_LABEL_SIZE
char prefix[MAX_METRIC_PREFIX_SIZE]
Temporary struct to hold a metric after it has been parsed.
static constexpr ptrdiff_t MAX_SIZE