diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-11-26 14:23:28 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2020-11-26 14:23:28 +0000 |
commit | ba800af4e06a51b9ddca0d5b5368cb27afd0dd0c (patch) | |
tree | a4f1767188c4edabd929be66e9a14967315ab7a1 /metrics | |
parent | 055e3a8a117bf454f8e930573f324ccab0b5247c (diff) |
GC unused html metrics reporting.
Diffstat (limited to 'metrics')
-rw-r--r-- | metrics/src/tests/metricmanagertest.cpp | 65 | ||||
-rw-r--r-- | metrics/src/vespa/metrics/CMakeLists.txt | 1 | ||||
-rw-r--r-- | metrics/src/vespa/metrics/printutils.cpp | 278 | ||||
-rw-r--r-- | metrics/src/vespa/metrics/printutils.h | 214 | ||||
-rw-r--r-- | metrics/src/vespa/metrics/state_api_adapter.h | 2 |
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 - |