aboutsummaryrefslogtreecommitdiffstats
path: root/metrics
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-11-26 14:23:28 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-11-26 14:23:28 +0000
commitba800af4e06a51b9ddca0d5b5368cb27afd0dd0c (patch)
treea4f1767188c4edabd929be66e9a14967315ab7a1 /metrics
parent055e3a8a117bf454f8e930573f324ccab0b5247c (diff)
GC unused html metrics reporting.
Diffstat (limited to 'metrics')
-rw-r--r--metrics/src/tests/metricmanagertest.cpp65
-rw-r--r--metrics/src/vespa/metrics/CMakeLists.txt1
-rw-r--r--metrics/src/vespa/metrics/printutils.cpp278
-rw-r--r--metrics/src/vespa/metrics/printutils.h214
-rw-r--r--metrics/src/vespa/metrics/state_api_adapter.h2
5 files changed, 1 insertions, 559 deletions
diff --git a/metrics/src/tests/metricmanagertest.cpp b/metrics/src/tests/metricmanagertest.cpp
index 47515d1bc4c..6ebea283e93 100644
--- a/metrics/src/tests/metricmanagertest.cpp
+++ b/metrics/src/tests/metricmanagertest.cpp
@@ -2,7 +2,7 @@
#include <vespa/metrics/jsonwriter.h>
#include <vespa/metrics/metrics.h>
-#include <vespa/metrics/printutils.h>
+#include <vespa/metrics/metricmanager.h>
#include <vespa/metrics/state_api_adapter.h>
#include <vespa/metrics/textwriter.h>
#include <vespa/metrics/xmlwriter.h>
@@ -565,69 +565,6 @@ TEST_F(MetricManagerTest, test_snapshots)
ASSERT_VALUES(mm, 0 * 60, "0,0,0,0,0,0,0,0,0,0,0");
}
-TEST_F(MetricManagerTest, test_print_utils)
-{
- FastOS_ThreadPool pool(256 * 1024);
- FakeTimer* timer = new FakeTimer(1000);
- std::unique_ptr<MetricManager::Timer> timerImpl(timer);
- MetricManager mm(std::move(timerImpl));
- TestMetricSet mySet;
- {
- MetricLockGuard lockGuard(mm.getMetricLock());
- mm.registerMetric(lockGuard, mySet.set);
- }
- // Adding metrics to have some values in them
- mySet.val6.addValue(2);
- mySet.val9.val1.addValue(4);
- mySet.val10.count.inc();
- mySet.val10.a.val1.addValue(7);
- mySet.val10.a.val2.addValue(2);
- mySet.val10.b.val1.addValue(1);
- // Initialize metric manager to get snapshots created.
- mm.init("raw:"
- "consumer[2]\n"
- "consumer[0].name snapper\n"
- "consumer[0].tags[1]\n"
- "consumer[0].tags[0] snaptest\n"
- "consumer[1].name log\n"
- "consumer[1].tags[1]\n"
- "consumer[1].tags[0] snaptest\n",
- pool);
- using namespace printutils;
- MetricLockGuard lockGuard(mm.getMetricLock());
- MetricSource source(mm.getActiveMetrics(lockGuard),
- "temp.multisub");
- ASSERT_TRUE(source.getMetric("count") != nullptr);
- ASSERT_TRUE(source.getMetric("a.val1") != nullptr);
- ASSERT_TRUE(source.getMetric("a.valsum") != nullptr);
- ASSERT_TRUE(source.getMetric("sum.val1") != nullptr);
- ASSERT_TRUE(source.getMetric("sum.valsum") != nullptr);
-
- std::vector<Metric::String> metrics(
- source.getPathsMatchingPrefix("a.val"));
- std::vector<Metric::String> expected;
- expected.push_back("val1");
- expected.push_back("val2");
- expected.push_back("valsum");
- EXPECT_EQ(expected, metrics);
-
- HttpTable table("mytable", "stuff");
- table.colNames.push_back("values");
- table.rowNames.push_back("valsum");
- table[0][0] = getValueString(
- getLongMetric("a.val1.value", source)
- + getLongMetric("a.val2.value", source));
- std::ostringstream ost;
- table.print(ost);
- EXPECT_EQ(std::string(
- "<h3>mytable</h3>\n"
- "<table border=\"1\">\n"
- "<tr><th>stuff</th><th>values</th></tr>\n"
- "<tr><td>valsum</td><td align=\"right\">9</td></tr>\n"
- "</table>\n"
- ), ost.str());
-}
-
TEST_F(MetricManagerTest, test_xml_output)
{
FastOS_ThreadPool pool(256 * 1024);
diff --git a/metrics/src/vespa/metrics/CMakeLists.txt b/metrics/src/vespa/metrics/CMakeLists.txt
index 0d7eeba3601..9ac0140c52b 100644
--- a/metrics/src/vespa/metrics/CMakeLists.txt
+++ b/metrics/src/vespa/metrics/CMakeLists.txt
@@ -12,7 +12,6 @@ vespa_add_library(metrics
metricsnapshot.cpp
metrictimer.cpp
metricvalueset.cpp
- printutils.cpp
name_repo.cpp
state_api_adapter.cpp
summetric.cpp
diff --git a/metrics/src/vespa/metrics/printutils.cpp b/metrics/src/vespa/metrics/printutils.cpp
deleted file mode 100644
index 974a4523366..00000000000
--- a/metrics/src/vespa/metrics/printutils.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include "printutils.h"
-#include <vespa/vespalib/util/stringfmt.h>
-
-namespace metrics {
-namespace printutils {
-
-typedef std::pair<int64_t, bool> LongValue;
-typedef std::pair<double, bool> DoubleValue;
-
-MetricSource::MetricSource(const MetricSnapshot& s,
- const String& metricsPrefix,
- std::map<String, Metric::SP>* metricsAccessed)
- : _snapshot(s),
- _metricsPrefix(metricsPrefix),
- _metricsAccessedOwner(),
- _metricsAccessed(metricsAccessed == 0 ? _metricsAccessedOwner
- : *metricsAccessed)
-{
-}
-
-MetricSource::~MetricSource() {}
-
-Metric::String
-MetricSource::createAbsoluteMetricName(const String& name) const {
- String prefix = _metricsPrefix;
- String addition = name;
- while (addition.find("../") == 0) {
- String::size_type pos1 = prefix.rfind('.');
- if (pos1 == String::npos)
- throw vespalib::IllegalArgumentException(
- "Cannot go back anymore in path " + prefix,
- VESPA_STRLOC);
- prefix = prefix.substr(0, pos1);
- addition = addition.substr(3);
- }
- return (prefix.empty() ? addition : prefix + "." + addition);
-}
-
-MetricSource::SourceMetricVisitor::SourceMetricVisitor(const String& path, bool prefixMatch)
- : _stringPath(path),
- _path(vespalib::StringTokenizer(path, ".").getTokens()),
- _pathIndex(-1),
- _resultMetric(),
- _prefixMatch(prefixMatch),
- _prefixMatches()
-{
-}
-
-MetricSource::SourceMetricVisitor::~SourceMetricVisitor() { }
-
-void
-MetricSource::SourceMetricVisitor::checkForPrefixMatch(const Metric& metric) {
- if (metric.getName().size() >= _path[_pathIndex].size()) {
- if (metric.getName().find(_path[_pathIndex]) == 0) {
- _prefixMatches.push_back(metric.getName());
- }
- }
-}
-
-bool
-MetricSource::SourceMetricVisitor::visitMetricSet(const MetricSet& set, bool) {
- if (_pathIndex == -1) {
- _pathIndex = 0;
- return true;
- }
- if (_prefixMatch
- && static_cast<size_t>(_pathIndex + 1) == _path.size())
- {
- for (const Metric * entry : set.getRegisteredMetrics()) {
- checkForPrefixMatch(*entry);
- }
- return false;
- }
- if (set.getName() != _path[_pathIndex]) return false;
- if (static_cast<size_t>(++_pathIndex) >= _path.size()) {
- throw vespalib::IllegalArgumentException(
- "Path " + _stringPath + " points to a metric set. "
- "Only primitive metrics can be retrieved.",
- VESPA_STRLOC);
- }
- return true;
-}
-bool
-MetricSource::SourceMetricVisitor::visitMetric(const Metric& metric, bool) {
- if (_prefixMatch) {
- checkForPrefixMatch(metric);
- }
- if (_path[_pathIndex] != metric.getName()) {
- return true;
- }
- if (_prefixMatch) {
- throw vespalib::IllegalArgumentException(
- "Cannot find existing entries with prefix "
- + _stringPath + " since element " + metric.getName()
- + " is not a metric set", VESPA_STRLOC);
- }
- if (static_cast<size_t>(_pathIndex + 1) < _path.size()) {
- throw vespalib::IllegalArgumentException(
- "Path " + _stringPath + " cannot exist since element "
- + _path[_pathIndex] + " is not a metric set: "
- + metric.toString(),
- VESPA_STRLOC);
- }
- std::vector<Metric::UP> ownerList;
- _resultMetric.reset(metric.clone(ownerList, Metric::INACTIVE, 0));
- if (!ownerList.empty()) {
- throw vespalib::IllegalArgumentException(
- "Metric " + metric.getName() + " added entries to "
- "owners list when cloning. This should not happen "
- "for primitive metrics.", VESPA_STRLOC);
- }
- return false;
-}
-
-const Metric*
-MetricSource::getMetric(const String& name) {
- String path = createAbsoluteMetricName(name);
- std::map<String, Metric::SP>::const_iterator it(
- _metricsAccessed.find(path));
- if (it != _metricsAccessed.end()) {
- return it->second.get();
- }
- SourceMetricVisitor visitor(path, false);
- _snapshot.getMetrics().visit(visitor);
- if (visitor._resultMetric.get() == 0) {
- throw vespalib::IllegalArgumentException(
- "Metric " + path + " was not found.", VESPA_STRLOC);
- }
- Metric::SP metric(visitor._resultMetric.release());
- _metricsAccessed[path] = metric;
- return metric.get();
-}
-
-std::vector<Metric::String>
-MetricSource::getPathsMatchingPrefix(const String& prefix) const
-{
- String path = createAbsoluteMetricName(prefix);
- SourceMetricVisitor visitor(path, true);
- _snapshot.getMetrics().visit(visitor);
- return visitor._prefixMatches;
-}
-
-// Addition functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-LongValue operator+(LongValue addend1, LongValue addend2)
-{
- return LongValue(addend1.first + addend2.first,
- addend1.second && addend2.second);
-}
-
-// Subtraction functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-LongValue operator-(LongValue minuend, LongValue subtrahend)
-{
- return LongValue(minuend.first - subtrahend.first,
- minuend.second && subtrahend.second);
-}
-
-// Multiplication functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-
-LongValue operator*(LongValue factor1, LongValue factor2)
-{
- return std::pair<int64_t, bool>(factor1.first * factor2.first,
- factor1.second && factor2.second);
-}
-
-// Division functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-
-LongValue operator/(LongValue dividend, LongValue divisor)
-{
- if (dividend.first == 0) return LongValue(
- 0, dividend.second && divisor.second);
- if (divisor.first == 0) return LongValue(
- std::numeric_limits<int64_t>().max(),
- dividend.second && divisor.second);
- return LongValue(dividend.first / divisor.first,
- dividend.second && divisor.second);
-}
-
-/** Get metric with given name from source. Set bool true if existing. */
-LongValue getLongMetric(const std::string& name, MetricSource& source)
-{
- std::string::size_type pos = name.rfind('.');
- const Metric* metric = (pos == std::string::npos
- ? 0 : source.getMetric(name.substr(0, pos)));
- try{
- return LongValue(metric == 0
- ? 0 : metric->getLongValue(name.substr(pos+1)), metric != 0);
- } catch (vespalib::IllegalArgumentException& e) {
- return LongValue(0, false);
- }
-}
-
-/** Get metric with given name from source. Set bool true if existing. */
-DoubleValue getDoubleMetric(const std::string& name, MetricSource& source)
-{
- std::string::size_type pos = name.rfind('.');
- const Metric* metric = (pos == std::string::npos
- ? 0 : source.getMetric(name.substr(0, pos)));
- try{
- return DoubleValue(metric == 0
- ? 0.0 : metric->getDoubleValue(name.substr(pos+1)), metric != 0);
- } catch (vespalib::IllegalArgumentException& e) {
- return DoubleValue(0, false);
- }
-}
-
-std::string getValueString(LongValue value, const char* format)
-{
- if (!value.second) return "na";
- std::vector<char> buffer(30);
- snprintf(&buffer[0], 30, format, value.first);
- return std::string(&buffer[0]);
-}
-
-std::string getValueString(DoubleValue value, const char* format)
-{
- if (!value.second) return "na";
- std::vector<char> buffer(30);
- snprintf(&buffer[0], 30, format, value.first);
- return std::string(&buffer[0]);
-}
-
-HttpTable::HttpTable(const std::string& title_, const std::string& topLeftText_)
- : title(title_), topLeftText(topLeftText_)
-{}
-HttpTable::~HttpTable() { }
-
-HttpTable::Row&
-HttpTable::operator[](uint32_t i) {
- if (i >= cells.size()) cells.resize(i + 1);
- return cells[i];
-}
-
-void
-HttpTable::fillInEmptyHoles() {
- if (rowNames.size() < cells.size()) rowNames.resize(cells.size());
- if (rowNames.size() > cells.size()) cells.resize(rowNames.size());
- for (uint32_t i=0; i<cells.size(); ++i) {
- if (colNames.size() < cells[i].cells.size())
- colNames.resize(cells[i].cells.size());
- if (colNames.size() > cells[i].cells.size())
- cells[i].cells.resize(colNames.size());
- }
-}
-
-void
-HttpTable::print(std::ostream& out) {
- out << "<h3>" << title << "</h3>\n";
- out << "<table border=\"1\">\n";
- fillInEmptyHoles();
- for (uint32_t i=0; i<=rowNames.size(); ++i) {
- if (i == 0) {
- out << "<tr><th>" << topLeftText << "</th>";
- for (uint32_t j=0; j<colNames.size(); ++j) {
- out << "<th>" << colNames[j] << "</th>";
- }
- out << "</tr>\n";
- } else {
- out << "<tr><td>" << rowNames[i - 1] << "</td>";
- for (uint32_t j=0; j<colNames.size(); ++j) {
- out << "<td align=\"right\">"
- << (cells[i - 1][j].set ? cells[i - 1][j].value : "-")
- << "</td>";
- }
- out << "</tr>\n";
- }
- }
- out << "</table>\n";
-}
-
-} // printutils
-} // metrics
-
diff --git a/metrics/src/vespa/metrics/printutils.h b/metrics/src/vespa/metrics/printutils.h
deleted file mode 100644
index a580ad809be..00000000000
--- a/metrics/src/vespa/metrics/printutils.h
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-/**
- * This file contains utility functions to help print out metric snapshots in
- * a user friendly way. It defines value types, functions for retrieving and
- * doing algorithmics with the values, and printing them in an HTML table.
- *
- * This is used by storage to print HTML metrics report for its status page.
- */
-
-#pragma once
-
-#include "metricmanager.h"
-#include <vespa/vespalib/text/stringtokenizer.h>
-#include <vespa/vespalib/util/exceptions.h>
-
-namespace metrics {
-namespace printutils {
-
-typedef std::pair<int64_t, bool> LongValue;
-typedef std::pair<double, bool> DoubleValue;
-
-struct MetricSource {
- typedef Metric::String String;
-
- const MetricSnapshot& _snapshot;
- String _metricsPrefix;
- // If no map is supplied, this map will own the data in the metrics
- // accessed map.
- std::map<String, Metric::SP> _metricsAccessedOwner;
- std::map<String, Metric::SP>& _metricsAccessed;
-
- MetricSource(const MetricSnapshot& s,
- const String& metricsPrefix,
- std::map<String, Metric::SP>* metricsAccessed = 0);
- ~MetricSource();
- String createAbsoluteMetricName(const String& name) const;
-
- struct SourceMetricVisitor : public metrics::MetricVisitor {
- String _stringPath;
- vespalib::StringTokenizer::TokenList _path;
- int32_t _pathIndex;
- Metric::UP _resultMetric;
- bool _prefixMatch;
- std::vector<String> _prefixMatches;
-
- SourceMetricVisitor(const String& path, bool prefixMatch);
- ~SourceMetricVisitor();
-
- void checkForPrefixMatch(const Metric& metric);
-
- bool visitMetricSet(const MetricSet& set, bool) override;
- void doneVisitingMetricSet(const MetricSet&) override { --_pathIndex; }
- bool visitMetric(const Metric& metric, bool) override;
- };
-
- const Metric* getMetric(const String& name);
-
- std::vector<String>
- getPathsMatchingPrefix(const String& prefix) const;
-};
-
-// Addition functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-LongValue operator+(LongValue addend1, LongValue addend2);
-
-template<typename ValueType1, typename ValueType2>
-DoubleValue operator+(std::pair<ValueType1, bool> addend1,
- std::pair<ValueType2, bool> addend2)
-{
- return DoubleValue(addend1.first + addend2.first,
- addend1.second && addend2.second);
-}
-
-// Subtraction functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-LongValue operator-(LongValue minuend, LongValue subtrahend);
-
-template<typename ValueType1, typename ValueType2>
-DoubleValue operator-(std::pair<ValueType1, bool> minuend,
- std::pair<ValueType2, bool> subtrahend)
-{
- return DoubleValue(minuend.first - subtrahend.first,
- minuend.second && subtrahend.second);
-}
-
-// Multiplication functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-
-LongValue operator*(LongValue factor1, LongValue factor2);
-
-template<typename ValueType1, typename ValueType2>
-DoubleValue operator*(std::pair<ValueType1, bool> factor1,
- std::pair<ValueType2, bool> factor2)
-{
- return std::pair<double, bool>(factor1.first * factor2.first,
- factor1.second && factor2.second);
-}
-
-// Division functions. Ensure that if floating point value is used,
-// result ends up as floating point too.
-
-LongValue operator/(LongValue dividend, LongValue divisor);
-
-template<typename ValueType1, typename ValueType2>
-DoubleValue operator/(std::pair<ValueType1, bool> dividend,
- std::pair<ValueType2, bool> divisor)
-{
- // In case divisor is integer, we will core if we attempt to divide
- // with it.
- if (dividend.first == 0) return DoubleValue(
- 0, dividend.second && divisor.second);
- if (divisor.first == 0) return DoubleValue(
- std::numeric_limits<double>().infinity(),
- dividend.second && divisor.second);
- return DoubleValue(
- dividend.first / static_cast<double>(divisor.first),
- dividend.second && divisor.second);
-}
-
-// Min/Max functions
-template<typename ValueType>
-std::pair<ValueType, bool> getMin(std::pair<ValueType, bool> val1,
- std::pair<ValueType, bool> val2)
-{
- if (!val1.second) return val2;
- if (!val2.second) return val1;
- return std::pair<ValueType, bool>(std::min(val1.first, val2.first), true);
-}
-
-template<typename ValueType>
-std::pair<ValueType, bool> getMax(std::pair<ValueType, bool> val1,
- std::pair<ValueType, bool> val2)
-{
- if (!val1.second) return val2;
- if (!val2.second) return val1;
- return std::pair<ValueType, bool>(std::max(val1.first, val2.first), true);
-}
-
-// Wrapper types for primitives. Would be nice to allow primitives directly, but
-// using a wrapper we can get by with less operator overloads above.
-
-template<typename ValueType>
-struct VW : public std::pair<ValueType, bool> {
- VW(ValueType val) : std::pair<ValueType, bool>(val, true) {}
-};
-
-typedef VW<int64_t> LVW;
-typedef VW<double> DVW;
-
-
-LongValue getLongMetric(const std::string& name, MetricSource& source);
-DoubleValue getDoubleMetric(const std::string& name, MetricSource& source);
-std::string getValueString(LongValue value, const char* format = "%'lld");
-std::string getValueString(DoubleValue value, const char* format = "%'f");
-
-template<typename ValueType>
-std::string getByteValueString(std::pair<ValueType, bool> val)
-{
- static const int64_t k = (1ul << 10);
- static const int64_t m = (1ul << 20);
- static const int64_t g = (1ul << 30);
-
- if (!val.second) return "na";
- std::pair<int64_t, bool> value(
- static_cast<int64_t>(val.first), val.second);
- if (value.first < 64 * k) {
- return getValueString(value, "%'llu B");
- }
- if (value.first < 64 * m) {
- value.first /= k;
- return getValueString(value, "%'llu kB");
- }
- if (value.first < 64 * g) {
- value.first /= m;
- return getValueString(value, "%'llu MB");
- }
- value.first /= g;
- return getValueString(value, "%'llu GB");
-}
-
-struct HttpTable {
- std::string title;
- std::string topLeftText;
- std::vector<std::string> colNames;
- std::vector<std::string> rowNames;
- struct Cell {
- bool set;
- std::string value;
-
- Cell() : set(false), value() {}
-
- void operator=(const std::string& val) { value = val; set = true; }
- };
- struct Row {
- std::vector<Cell> cells;
- Cell& operator[](uint32_t i) {
- if (i >= cells.size()) cells.resize(i + 1);
- return cells[i];
- }
- };
- std::vector<Row> cells;
-
- HttpTable(const std::string& title_, const std::string& topLeftText_);
- ~HttpTable();
-
- Row& operator[](uint32_t i);
- void fillInEmptyHoles();
- void print(std::ostream& out);
-};
-
-} // printutils
-} // metrics
-
diff --git a/metrics/src/vespa/metrics/state_api_adapter.h b/metrics/src/vespa/metrics/state_api_adapter.h
index ccf7e73471e..4e152e3ab13 100644
--- a/metrics/src/vespa/metrics/state_api_adapter.h
+++ b/metrics/src/vespa/metrics/state_api_adapter.h
@@ -25,6 +25,4 @@ public:
vespalib::string getTotalMetrics(const vespalib::string &consumer) override;
};
-
} // namespace metrics
-