This is an automated email from the ASF dual-hosted git repository. zwoop pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new e6182d9ac9 New API Metrics, and start of a libtsapi.so structure (#9988) e6182d9ac9 is described below commit e6182d9ac9c3f611cb33b3ef6dc98327df41c3d6 Author: Leif Hedstrom <zw...@apache.org> AuthorDate: Fri Jul 28 16:48:46 2023 -0600 New API Metrics, and start of a libtsapi.so structure (#9988) * New API Metrics, and start of a libtapi.so structure The new API metrics are backwards compatible with previous APIs, since the old API wraps these new APIs. New plugins / code could chose to use the Metrics.h API directly. Work to be finished here includes 1. Decide what goes into include/api ? Do we have one new include file to #include all the include/api/*.h files? 2. What should be moved to src/api and include/api. Lost in this merge is all the work from Chris McFarlen. Thanks! Co-Author: Chris McFarlen <ch...@mcfarlen.us> * Fixes make check * Fixes type mismatch, shouldn't use apidefs.h symbols * More Makefile fixes * Adds missing include files * Updates the regression tests, adds to Makefile * Fixes install CMake targets * Fix the expensive checks * Fixes for H3 and HPACK * Adds API metrics supports for the RecCore matchers * Trying to fix some build concerns * Removes the -fPIE from hardening * Undo some of the fPIC stuff and deps --- .gitignore | 1 + CMakeLists.txt | 1 + configure.ac | 1 + include/api/Metrics.h | 237 ++++++++++++++++++++++++ include/records/I_RecordsConfig.h | 3 - include/records/P_RecCore.h | 2 +- include/records/P_RecDefs.h | 10 +- iocore/aio/Makefile.am | 1 + iocore/cache/Makefile.am | 1 + iocore/eventsystem/Makefile.am | 1 + iocore/hostdb/Makefile.am | 1 + iocore/net/Makefile.am | 10 +- mgmt/rpc/Makefile.am | 1 + plugins/experimental/remap_stats/remap_stats.cc | 3 - proxy/hdrs/Makefile.am | 2 + proxy/http/Makefile.am | 2 + proxy/http/remap/Makefile.am | 5 + proxy/http/unit_tests/CMakeLists.txt | 1 + proxy/http2/Makefile.am | 2 + proxy/http3/Makefile.am | 1 + proxy/logging/unit-tests/benchmark_LogObject.cc | 2 +- src/Makefile.am | 2 +- src/{traffic_crashlog => api}/CMakeLists.txt | 20 +- src/{ => api}/Makefile.am | 52 +++--- src/api/Metrics.cc | 139 ++++++++++++++ src/api/test_Metrics.cc | 65 +++++++ src/records/Makefile.am | 2 + src/records/RecCore.cc | 73 ++++++-- src/records/RecUtils.cc | 4 +- src/tests/CMakeLists.txt | 2 + src/traffic_crashlog/CMakeLists.txt | 1 + src/traffic_crashlog/Makefile.inc | 1 + src/traffic_layout/CMakeLists.txt | 4 + src/traffic_layout/Makefile.inc | 1 + src/traffic_logcat/Makefile.inc | 1 + src/traffic_logstats/Makefile.inc | 5 +- src/traffic_server/CMakeLists.txt | 1 + src/traffic_server/InkAPI.cc | 86 ++------- src/traffic_server/Makefile.inc | 1 + src/traffic_server/traffic_server.cc | 2 - tools/benchmark/Makefile.am | 1 + 41 files changed, 607 insertions(+), 144 deletions(-) diff --git a/.gitignore b/.gitignore index a4983d434b..c288e1470e 100644 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,7 @@ src/tscore/test_tscore src/tscpp/util/test_tscpputil src/records/test_librecords src/records/test_librecords_on_eventsystem +src/api/test_Metrics lib/perl/lib/Apache/TS.pm iocore/net/test_certlookup diff --git a/CMakeLists.txt b/CMakeLists.txt index d771148036..eda1b79b23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,7 @@ configure_file(include/ts/apidefs.h.in include/ts/apidefs.h) enable_testing() +add_subdirectory(src/api) add_subdirectory(src/tscpp/util) add_subdirectory(src/tscpp/api) add_subdirectory(src/tscore) diff --git a/configure.ac b/configure.ac index 0eb8249053..73d8a2c587 100644 --- a/configure.ac +++ b/configure.ac @@ -2400,6 +2400,7 @@ AC_CONFIG_FILES([ src/tscpp/util/Makefile src/tscore/Makefile src/records/Makefile + src/api/Makefile tools/Makefile tools/trafficserver.pc tools/tsxs diff --git a/include/api/Metrics.h b/include/api/Metrics.h new file mode 100644 index 0000000000..6b79f43eb3 --- /dev/null +++ b/include/api/Metrics.h @@ -0,0 +1,237 @@ +/** @file + + A brief file description + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#pragma once + +#include <array> +#include <unordered_map> +#include <tuple> +#include <mutex> +#include <thread> +#include <atomic> +#include <cstdint> +#include <string> +#include <string_view> + +#include "tscore/ink_assert.h" + +namespace ts +{ +class Metrics +{ +private: + using self_type = Metrics; + using IdType = int32_t; // Could be a tuple, but one way or another, they have to be combined to an int32_t. + using AtomicType = std::atomic<int64_t>; + +public: + static constexpr uint16_t METRICS_MAX_BLOBS = 8192; + static constexpr uint16_t METRICS_MAX_SIZE = 2048; // For a total of 16M metrics + static constexpr IdType NOT_FOUND = std::numeric_limits<IdType>::min(); // <16-bit,16-bit> = <blob-index,offset> + +private: + using NameAndId = std::tuple<std::string, IdType>; + using NameContainer = std::array<NameAndId, METRICS_MAX_SIZE>; + using AtomicContainer = std::array<AtomicType, METRICS_MAX_SIZE>; + using MetricStorage = std::tuple<NameContainer, AtomicContainer>; + using MetricBlobs = std::array<MetricStorage *, METRICS_MAX_BLOBS>; + using LookupTable = std::unordered_map<std::string_view, IdType>; + +public: + Metrics(const self_type &) = delete; + self_type &operator=(const self_type &) = delete; + Metrics &operator=(Metrics &&) = delete; + Metrics(Metrics &&) = delete; + + virtual ~Metrics() = default; + + Metrics() + { + _blobs[0] = new MetricStorage(); + ink_release_assert(_blobs[0]); + ink_release_assert(0 == newMetric("proxy.node.api.metrics.bad_id")); // Reserve slot 0 for errors, this should always be 0 + } + + // Singleton + static Metrics &getInstance(); + + // Yes, we don't return objects here, but rather ID's and atomic's directly. Treat + // the std::atomic<int64_t> as the underlying class for a single metric, and be happy. + IdType newMetric(const std::string_view name); + IdType lookup(const std::string_view name) const; + AtomicType *lookup(IdType id, std::string_view *name = nullptr) const; + + AtomicType & + operator[](IdType id) + { + return *lookup(id); + } + + IdType + operator[](const std::string_view name) const + { + return lookup(name); + } + + int64_t + increment(IdType id, uint64_t val = 1) + { + auto metric = lookup(id); + + return (metric ? metric->fetch_add(val) : NOT_FOUND); + } + + // ToDo: Do we even need these inc/dec functions? + int64_t + decrement(IdType id, uint64_t val = 1) + { + auto metric = lookup(id); + + return (metric ? metric->fetch_sub(val) : NOT_FOUND); + } + + std::string_view name(IdType id) const; + + bool + valid(IdType id) const + { + auto [blob, entry] = _splitID(id); + + return (id >= 0 && ((blob < _cur_blob && entry < METRICS_MAX_SIZE) || (blob == _cur_blob && entry <= _cur_off))); + } + + class iterator + { + public: + using iterator_category = std::input_iterator_tag; + using value_type = std::tuple<std::string_view, int64_t>; + using difference_type = ptrdiff_t; + using pointer = value_type *; + using reference = value_type &; + + iterator(const Metrics &m, IdType pos) : _metrics(m), _it(pos) {} + + iterator & + operator++() + { + next(); + + return *this; + } + + iterator + operator++(int) + { + iterator result = *this; + + next(); + + return result; + } + + value_type + operator*() const + { + std::string_view name; + auto metric = _metrics.lookup(_it, &name); + + return std::make_tuple(name, metric->load()); + } + + bool + operator==(const iterator &o) const + { + return _it == o._it && std::addressof(_metrics) == std::addressof(o._metrics); + } + + bool + operator!=(const iterator &o) const + { + return _it != o._it || std::addressof(_metrics) != std::addressof(o._metrics); + } + + private: + void next(); + + const Metrics &_metrics; + IdType _it; + }; + + iterator + begin() const + { + return iterator(*this, 0); + } + + iterator + end() const + { + _mutex.lock(); + int16_t blob = _cur_blob; + int16_t offset = _cur_off; + _mutex.unlock(); + + return iterator(*this, _makeId(blob, offset)); + } + + iterator + find(const std::string_view name) const + { + auto id = lookup(name); + + if (id == NOT_FOUND) { + return end(); + } else { + return iterator(*this, id); + } + } + +private: + static constexpr std::tuple<uint16_t, uint16_t> + _splitID(IdType value) + { + return std::make_tuple(static_cast<uint16_t>(value >> 16), static_cast<uint16_t>(value & 0xFFFF)); + } + + static constexpr IdType + _makeId(uint16_t blob, uint16_t offset) + { + return (blob << 16 | offset); + } + + static constexpr IdType + _makeId(std::tuple<uint16_t, uint16_t> id) + { + return _makeId(std::get<0>(id), std::get<1>(id)); + } + + void _addBlob(); + + mutable std::mutex _mutex; + LookupTable _lookups; + MetricBlobs _blobs; + uint16_t _cur_blob = 0; + uint16_t _cur_off = 0; +}; // class Metrics + +} // namespace ts diff --git a/include/records/I_RecordsConfig.h b/include/records/I_RecordsConfig.h index 2b16f7c030..df9ea60254 100644 --- a/include/records/I_RecordsConfig.h +++ b/include/records/I_RecordsConfig.h @@ -25,9 +25,6 @@ #include "records/P_RecCore.h" -// This is to manage the librecords table sizes. Not awesome, but better than the earlier recompiling of ATS requirement... -extern int max_records_entries; - enum RecordRequiredType { RR_NULL, // config is _not_ required to be defined in records.yaml RR_REQUIRED // config _is_ required to be defined in record.config diff --git a/include/records/P_RecCore.h b/include/records/P_RecCore.h index 062bdec9df..1818ddd2a6 100644 --- a/include/records/P_RecCore.h +++ b/include/records/P_RecCore.h @@ -37,7 +37,7 @@ #include <swoc/Errata.h> // records, record hash-table, and hash-table rwlock -extern RecRecord *g_records; +extern RecRecord g_records[REC_MAX_RECORDS]; extern std::unordered_map<std::string, RecRecord *> g_records_ht; extern ink_rwlock g_records_rwlock; extern int g_num_records; diff --git a/include/records/P_RecDefs.h b/include/records/P_RecDefs.h index f4da85e75a..6755494a97 100644 --- a/include/records/P_RecDefs.h +++ b/include/records/P_RecDefs.h @@ -27,12 +27,10 @@ #define REC_MESSAGE_ELE_MAGIC 0xF00DF00D -// We need at least this many internal record entries for our configurations and metrics. Any -// additional slots in librecords will be allocated to the plugin metrics. These should be -// updated if we change the internal librecords size significantly. -#define REC_INTERNAL_RECORDS 1100 -#define REC_DEFAULT_API_RECORDS 1400 - +// We need at least this many internal record entries for our configurations and metrics. +// This may need adjustments if we make significant additions to librecords. Note that +// plugins are using their own metrics systems. +#define REC_MAX_RECORDS 1500 #define REC_CONFIG_UPDATE_INTERVAL_MS 3000 #define REC_REMOTE_SYNC_INTERVAL_MS 5000 diff --git a/iocore/aio/Makefile.am b/iocore/aio/Makefile.am index 0f767f235f..f816f97298 100644 --- a/iocore/aio/Makefile.am +++ b/iocore/aio/Makefile.am @@ -56,6 +56,7 @@ test_AIO_LDADD = \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ @SWOC_LIBS@ @HWLOC_LIBS@ @YAMLCPP_LIBS@ @LIBPCRE@ @LIBCAP@ diff --git a/iocore/cache/Makefile.am b/iocore/cache/Makefile.am index c021764d6e..34e65c2bbc 100644 --- a/iocore/cache/Makefile.am +++ b/iocore/cache/Makefile.am @@ -99,6 +99,7 @@ test_LDADD = \ $(top_builddir)/iocore/utils/libinkutils.a \ $(top_builddir)/iocore/aio/libinkaio.a \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/lib/fastlz/libfastlz.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ diff --git a/iocore/eventsystem/Makefile.am b/iocore/eventsystem/Makefile.am index bb7965b167..082aac58fb 100644 --- a/iocore/eventsystem/Makefile.am +++ b/iocore/eventsystem/Makefile.am @@ -97,6 +97,7 @@ test_LD_ADD = \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ @HWLOC_LIBS@ @SWOC_LIBS@ @YAMLCPP_LIBS@ @LIBPCRE@ @LIBCAP@ diff --git a/iocore/hostdb/Makefile.am b/iocore/hostdb/Makefile.am index 6db40ac3de..87333102a7 100644 --- a/iocore/hostdb/Makefile.am +++ b/iocore/hostdb/Makefile.am @@ -67,6 +67,7 @@ test_LD_ADD = \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ @SWOC_LIBS@ @HWLOC_LIBS@ @YAMLCPP_LIBS@ @OPENSSL_LIBS@ @LIBPCRE@ @LIBCAP@ diff --git a/iocore/net/Makefile.am b/iocore/net/Makefile.am index 929dc79a86..b4c0c3895e 100644 --- a/iocore/net/Makefile.am +++ b/iocore/net/Makefile.am @@ -51,12 +51,13 @@ test_certlookup_SOURCES = \ SSLCertLookup.cc test_certlookup_LDADD = \ - @OPENSSL_LIBS@ \ - $(top_builddir)/src/tscore/libtscore.a $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/tscpp/util/libtscpputil.la \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/proxy/ParentSelectionStrategy.o \ @YAMLCPP_LIBS@ \ @SWOC_LIBS@ \ + @OPENSSL_LIBS@ \ @LIBPCRE@ \ @LIBCAP@ @@ -84,7 +85,9 @@ test_UDPNet_LDADD = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/proxy/hdrs/libhdrs.a \ - $(top_builddir)/src/tscore/libtscore.a $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/proxy/ParentSelectionStrategy.o \ @HWLOC_LIBS@ @OPENSSL_LIBS@ @LIBPCRE@ @YAMLCPP_LIBS@ @SWOC_LIBS@ @LIBPCRE@ @LIBCAP@ if ENABLE_QUIC @@ -125,6 +128,7 @@ test_libinknet_LDADD = \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/proxy/hdrs/libhdrs.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ $(top_builddir)/proxy/ParentSelectionStrategy.o \ @HWLOC_LIBS@ @OPENSSL_LIBS@ @LIBPCRE@ @YAMLCPP_LIBS@ @SWOC_LIBS@ @LIBCAP@ diff --git a/mgmt/rpc/Makefile.am b/mgmt/rpc/Makefile.am index 9ad923155e..7fe8c015d2 100644 --- a/mgmt/rpc/Makefile.am +++ b/mgmt/rpc/Makefile.am @@ -106,6 +106,7 @@ test_jsonrpcserver_LDADD = \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ $(top_builddir)/src/tscore/libtscore.a \ @YAMLCPP_LIBS@ @HWLOC_LIBS@ @SWOC_LIBS@ @YAMLCPP_LIBS@ @LIBPCRE@ @LIBCAP@ diff --git a/plugins/experimental/remap_stats/remap_stats.cc b/plugins/experimental/remap_stats/remap_stats.cc index 71e2c628bd..27924404e3 100644 --- a/plugins/experimental/remap_stats/remap_stats.cc +++ b/plugins/experimental/remap_stats/remap_stats.cc @@ -46,9 +46,6 @@ struct config_t { int txn_slot{-1}; }; -// From "core".... sigh, but we need it for now at least. -extern int max_records_entries; - namespace { void diff --git a/proxy/hdrs/Makefile.am b/proxy/hdrs/Makefile.am index 8b9cf9b9b2..70b9c2e118 100644 --- a/proxy/hdrs/Makefile.am +++ b/proxy/hdrs/Makefile.am @@ -89,6 +89,7 @@ test_proxy_hdrs_LDADD = \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/api/libtsapi.la \ @SWOC_LIBS@ @YAMLCPP_LIBS@ @HWLOC_LIBS@ @LIBPCRE@ @OPENSSL_LIBS@ @LIBCAP@ test_hdr_heap_CPPFLAGS = $(AM_CPPFLAGS) \ @@ -104,6 +105,7 @@ test_hdr_heap_LDADD = \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/api/libtsapi.la \ @SWOC_LIBS@ @HWLOC_LIBS@ \ @LIBPCRE@ @OPENSSL_LIBS@ @LIBCAP@ diff --git a/proxy/http/Makefile.am b/proxy/http/Makefile.am index ae6493d87f..1184ff21be 100644 --- a/proxy/http/Makefile.am +++ b/proxy/http/Makefile.am @@ -110,6 +110,7 @@ test_proxy_http_LDADD = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/iocore/utils/libinkutils.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ @SWOC_LIBS@ @HWLOC_LIBS@ \ @LIBCAP@ \ @@ -158,6 +159,7 @@ test_HttpTransact_LDADD = \ $(top_builddir)/iocore/net/libinknet.a \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ -lz -llzma -lcrypto -lresolv -lssl \ @LIBPCRE@ @HWLOC_LIBS@ @SWOC_LIBS@ @YAMLCPP_LIBS@ @LIBCAP@ diff --git a/proxy/http/remap/Makefile.am b/proxy/http/remap/Makefile.am index 3bb9da1ff3..e61c0aeb4d 100644 --- a/proxy/http/remap/Makefile.am +++ b/proxy/http/remap/Makefile.am @@ -68,6 +68,7 @@ libhttp_remap_a_SOURCES = \ COMMON_PLUGINDSO_LDADDS = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ @@ -137,6 +138,7 @@ test_NextHopStrategyFactory_LDADD = \ $(top_builddir)/proxy/hdrs/libhdrs.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/iocore/utils/libinkutils.a \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/proxy/logging/liblogging.a \ @@ -171,6 +173,7 @@ test_NextHopRoundRobin_LDADD = \ $(top_builddir)/proxy/hdrs/libhdrs.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/proxy/logging/liblogging.a \ $(top_builddir)/iocore/utils/libinkutils.a \ $(top_builddir)/src/tscore/libtscore.a \ @@ -205,6 +208,7 @@ test_NextHopConsistentHash_LDADD = \ $(top_builddir)/proxy/hdrs/libhdrs.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/proxy/logging/liblogging.a \ $(top_builddir)/iocore/utils/libinkutils.a \ $(top_builddir)/src/tscore/libtscore.a \ @@ -247,6 +251,7 @@ pkglib_LTLIBRARIES = \ unit-tests/plugin_missing_init.la \ unit-tests/plugin_missing_newinstance.la \ unit-tests/plugin_testing_calls.la + unit_tests_plugin_v1_la_SOURCES = unit-tests/plugin_misc_cb.cc unit_tests_plugin_v1_la_LDFLAGS = $(DSO_LDFLAGS) unit_tests_plugin_v1_la_CPPFLAGS = -DPLUGINDSOVER=1 $(AM_CPPFLAGS) diff --git a/proxy/http/unit_tests/CMakeLists.txt b/proxy/http/unit_tests/CMakeLists.txt index 64cc7d3d1b..1f9ef16c43 100644 --- a/proxy/http/unit_tests/CMakeLists.txt +++ b/proxy/http/unit_tests/CMakeLists.txt @@ -35,6 +35,7 @@ target_link_libraries(test_http PRIVATE catch2::catch2 ts::http + ts::tsapi ts::hdrs # transitive logging # transitive http_remap # transitive diff --git a/proxy/http2/Makefile.am b/proxy/http2/Makefile.am index 02ed791f32..6d385fd82f 100644 --- a/proxy/http2/Makefile.am +++ b/proxy/http2/Makefile.am @@ -72,6 +72,7 @@ test_libhttp2_LDADD = \ Http2Frame.o \ HPACK.o \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/proxy/hdrs/libhdrs.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ @@ -129,6 +130,7 @@ test_HPACK_LDADD = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ @SWOC_LIBS@ @HWLOC_LIBS@ @LIBPCRE@ @OPENSSL_LIBS@ @YAMLCPP_LIBS@ @LIBCAP@ test_HPACK_SOURCES = \ diff --git a/proxy/http3/Makefile.am b/proxy/http3/Makefile.am index 7abeebccf6..34497dd125 100644 --- a/proxy/http3/Makefile.am +++ b/proxy/http3/Makefile.am @@ -72,6 +72,7 @@ test_LDADD = \ $(top_builddir)/iocore/net/TLSKeyLogger.o \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ $(top_builddir)/proxy/hdrs/libhdrs.a \ $(top_builddir)/src/tscore/libtscore.a \ diff --git a/proxy/logging/unit-tests/benchmark_LogObject.cc b/proxy/logging/unit-tests/benchmark_LogObject.cc index 3db7020a07..6735c1b2e2 100644 --- a/proxy/logging/unit-tests/benchmark_LogObject.cc +++ b/proxy/logging/unit-tests/benchmark_LogObject.cc @@ -31,7 +31,7 @@ benchmark_LogObject_CPPFLAGS = \ $(AM_CPPFLAGS) \ -I$(abs_top_srcdir)/tests/include benchmark_LogObject_LDADD = \ - $(top_builddir)/src/tscore/libtscore.la \ + $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/proxy/logging/liblogging.a \ diff --git a/src/Makefile.am b/src/Makefile.am index 8e95c0c4a9..e6aaddec1d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ TESTS = lib_LTLIBRARIES = noinst_PROGRAMS = -SUBDIRS = tscpp/api +SUBDIRS = tscpp/api api if BUILD_WCCP SUBDIRS += wccp diff --git a/src/traffic_crashlog/CMakeLists.txt b/src/api/CMakeLists.txt similarity index 69% copy from src/traffic_crashlog/CMakeLists.txt copy to src/api/CMakeLists.txt index 3f43c20ba6..7d4cbe58eb 100644 --- a/src/traffic_crashlog/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -15,13 +15,17 @@ # ####################### -add_executable(traffic_crashlog procinfo.cc traffic_crashlog.cc) +add_library(tsapi SHARED Metrics.cc) +add_library(ts::tsapi ALIAS tsapi) -target_link_libraries(traffic_crashlog - PRIVATE - ts::inkevent - ts::records - ts::tscore -) +install(TARGETS tsapi) -install(TARGETS traffic_crashlog) + +add_executable(test_Metrics + test_Metrics.cc + ) + +target_link_libraries(test_Metrics PRIVATE tsapi tscore) +target_include_directories(test_Metrics PRIVATE ${CMAKE_SOURCE_DIR}/include ${CATCH_INCLUDE_DIR}) + +add_test(NAME test_Metrics COMMAND $<TARGET_FILE:test_Metrics>) diff --git a/src/Makefile.am b/src/api/Makefile.am similarity index 62% copy from src/Makefile.am copy to src/api/Makefile.am index 8e95c0c4a9..4c1326b6ad 100644 --- a/src/Makefile.am +++ b/src/api/Makefile.am @@ -1,3 +1,4 @@ +# libts Makefile.am # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -17,28 +18,35 @@ include $(top_srcdir)/mk/tidy.mk -bin_PROGRAMS = -check_PROGRAMS = -TESTS = -lib_LTLIBRARIES = -noinst_PROGRAMS = - -SUBDIRS = tscpp/api - -if BUILD_WCCP -SUBDIRS += wccp -include traffic_wccp/Makefile.inc -endif - -include traffic_cache_tool/Makefile.inc -include traffic_via/Makefile.inc -include traffic_top/Makefile.inc -include traffic_server/Makefile.inc -include traffic_logstats/Makefile.inc -include traffic_crashlog/Makefile.inc -include traffic_layout/Makefile.inc -include traffic_logcat/Makefile.inc -include traffic_ctl/Makefile.inc +check_PROGRAMS = test_Metrics + +TESTS = $(check_PROGRAMS) + +lib_LTLIBRARIES = libtsapi.la + +AM_CPPFLAGS += \ + -I$(abs_top_srcdir)/include \ + @SWOC_INCLUDES@ \ + $(TS_INCLUDES) + +libtsapi_la_LDFLAGS = @AM_LDFLAGS@ -version-info @TS_LIBTOOL_VERSION@ @SWOC_LDFLAGS@ + +libtsapi_la_LIBADD = \ + @SWOC_LIBS@ + + +libtsapi_la_SOURCES = \ + Metrics.cc + +test_Metrics_SOURCES = test_Metrics.cc + +test_Metrics_CPPFLAGS = $(AM_CPPFLAGS)\ + -I$(abs_top_srcdir)/lib/catch2 + +test_Metrics_LDADD = \ + $(top_builddir)/src/tscore/libtscore.a \ + libtsapi.la + clang-tidy-local: $(DIST_SOURCES) $(CXX_Clang_Tidy) diff --git a/src/api/Metrics.cc b/src/api/Metrics.cc new file mode 100644 index 0000000000..1d38e04ea2 --- /dev/null +++ b/src/api/Metrics.cc @@ -0,0 +1,139 @@ +/** @file + + The implementations of the Metrics API class. + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#include "api/Metrics.h" + +namespace ts +{ + +// This is the singleton instance of the metrics class. +Metrics & +Metrics::getInstance() +{ + static ts::Metrics _instance; + + return _instance; +} + +void +Metrics::_addBlob() // The mutex must be held before calling this! +{ + auto blob = new Metrics::MetricStorage(); + + ink_assert(blob); + ink_assert(_cur_blob < Metrics::METRICS_MAX_BLOBS); + + _blobs[++_cur_blob] = blob; + _cur_off = 0; +} + +Metrics::IdType +Metrics::newMetric(std::string_view name) +{ + std::lock_guard<std::mutex> lock(_mutex); + auto it = _lookups.find(name); + + if (it != _lookups.end()) { + return it->second; + } + + Metrics::IdType id = _makeId(_cur_blob, _cur_off); + Metrics::MetricStorage *blob = _blobs[_cur_blob]; + Metrics::NameContainer &names = std::get<0>(*blob); + Metrics::AtomicContainer &atomics = std::get<1>(*blob); + + atomics[_cur_off].store(0); + names[_cur_off] = std::make_tuple(std::string(name), id); + _lookups.emplace(std::get<0>(names[_cur_off]), id); + + if (++_cur_off >= Metrics::METRICS_MAX_SIZE) { + _addBlob(); // This resets _cur_off to 0 as well + } + + return id; +} + +Metrics::IdType +Metrics::lookup(const std::string_view name) const +{ + std::lock_guard<std::mutex> lock(_mutex); + auto it = _lookups.find(name); + + if (it != _lookups.end()) { + return it->second; + } + + return NOT_FOUND; +} + +Metrics::AtomicType * +Metrics::lookup(IdType id, std::string_view *name) const +{ + auto [blob_ix, offset] = _splitID(id); + Metrics::MetricStorage *blob = _blobs[blob_ix]; + + // Do a sanity check on the ID, to make sure we don't index outside of the realm of possibility. + if (!blob || (blob_ix == _cur_blob && offset > _cur_off)) { + blob = _blobs[0]; + offset = 0; + } + + if (name) { + *name = std::get<0>(std::get<0>(*blob)[offset]); + } + + return &((std::get<1>(*blob)[offset])); +} + +std::string_view +Metrics::name(Metrics::IdType id) const +{ + auto [blob_ix, offset] = _splitID(id); + Metrics::MetricStorage *blob = _blobs[blob_ix]; + + // Do a sanity check on the ID, to make sure we don't index outside of the realm of possibility. + if (!blob || (blob_ix == _cur_blob && offset > _cur_off)) { + blob = _blobs[0]; + offset = 0; + } + + const std::string &result = std::get<0>(std::get<0>(*blob)[offset]); + + return result; +} + +// Iterator implementation +void +Metrics::iterator::next() +{ + auto [blob, offset] = _metrics._splitID(_it); + + if (++offset == METRICS_MAX_SIZE) { + ++blob; + offset = 0; + } + + _it = _makeId(blob, offset); +} + +} // namespace ts diff --git a/src/api/test_Metrics.cc b/src/api/test_Metrics.cc new file mode 100644 index 0000000000..6556754c84 --- /dev/null +++ b/src/api/test_Metrics.cc @@ -0,0 +1,65 @@ +/** @file + + TextView unit tests. + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +#include "api/Metrics.h" + +TEST_CASE("Metrics", "[libtsapi][Metrics]") +{ + ts::Metrics m; + + SECTION("iterator") + { + auto [name, value] = *m.begin(); + REQUIRE(value == 0); + REQUIRE(name == "proxy.node.api.metrics.bad_id"); + + REQUIRE(m.begin() != m.end()); + REQUIRE(++m.begin() == m.end()); + + auto it = m.begin(); + it++; + REQUIRE(it == m.end()); + } + + SECTION("New metric") + { + auto fooid = m.newMetric("foo"); + + REQUIRE(fooid == 1); + REQUIRE(m.name(fooid) == "foo"); + + REQUIRE(m[fooid].load() == 0); + m.increment(fooid); + REQUIRE(m[fooid].load() == 1); + } + + SECTION("operator[]") + { + m[0].store(42); + + REQUIRE(m[0].load() == 42); + } +} diff --git a/src/records/Makefile.am b/src/records/Makefile.am index c2188a73bd..62325ea907 100644 --- a/src/records/Makefile.am +++ b/src/records/Makefile.am @@ -72,6 +72,7 @@ test_librecords_LDADD = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ @SWOC_LIBS@ @HWLOC_LIBS@ @LIBCAP@ @YAMLCPP_LIBS@ @LIBPCRE@ @OPENSSL_LIBS@ test_librecords_on_eventsystem_CPPFLAGS = $(AM_CPPFLAGS)\ @@ -86,6 +87,7 @@ test_librecords_on_eventsystem_LDADD = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ @HWLOC_LIBS@ @LIBCAP@ @YAMLCPP_LIBS@ @SWOC_LIBS@ @LIBPCRE@ @OPENSSL_LIBS@ clang-tidy-local: $(sort $(DIST_SOURCES)) diff --git a/src/records/RecCore.cc b/src/records/RecCore.cc index 8fa774aadd..54e0b93aa5 100644 --- a/src/records/RecCore.cc +++ b/src/records/RecCore.cc @@ -34,14 +34,11 @@ #include "records/P_RecUtils.h" #include "tscore/I_Layout.h" #include "tscpp/util/ts_errata.h" - -// This is needed to manage the size of the librecords record. It can't be static, because it needs to be modified -// and used (read) from several binaries / modules. -int max_records_entries = REC_INTERNAL_RECORDS + REC_DEFAULT_API_RECORDS; +#include "api/Metrics.h" static bool g_initialized = false; -RecRecord *g_records = nullptr; +RecRecord g_records[REC_MAX_RECORDS]; std::unordered_map<std::string, RecRecord *> g_records_ht; ink_rwlock g_records_rwlock; int g_num_records = 0; @@ -205,9 +202,6 @@ RecCoreInit(Diags *_diags) g_num_records = 0; - // initialize record array for our internal stats (this can be reallocated later) - g_records = static_cast<RecRecord *>(ats_malloc(max_records_entries * sizeof(RecRecord))); - // initialize record rwlock ink_rwlock_init(&g_records_rwlock); @@ -488,23 +482,38 @@ RecGetRecordBool(const char *name, RecBool *rec_bool, bool lock) RecErrT RecLookupRecord(const char *name, void (*callback)(const RecRecord *, void *), void *data, bool lock) { - RecErrT err = REC_ERR_FAIL; + RecErrT err = REC_ERR_FAIL; + ts::Metrics &api_metrics = ts::Metrics::getInstance(); + auto it = api_metrics.find(name); - if (lock) { - ink_rwlock_rdlock(&g_records_rwlock); - } + if (it != api_metrics.end()) { + RecRecord r; + auto &&[name, val] = *it; - if (auto it = g_records_ht.find(name); it != g_records_ht.end()) { - RecRecord *r = it->second; + r.rec_type = RECT_PLUGIN; + r.data_type = RECD_INT; + r.name = name.data(); + r.data.rec_int = val; - rec_mutex_acquire(&(r->lock)); - callback(r, data); + callback(&r, data); err = REC_ERR_OKAY; - rec_mutex_release(&(r->lock)); - } + } else { + if (lock) { + ink_rwlock_rdlock(&g_records_rwlock); + } - if (lock) { - ink_rwlock_unlock(&g_records_rwlock); + if (auto it = g_records_ht.find(name); it != g_records_ht.end()) { + RecRecord *r = it->second; + + rec_mutex_acquire(&(r->lock)); + callback(r, data); + err = REC_ERR_OKAY; + rec_mutex_release(&(r->lock)); + } + + if (lock) { + ink_rwlock_unlock(&g_records_rwlock); + } } return err; @@ -520,6 +529,21 @@ RecLookupMatchingRecords(unsigned rec_type, const char *match, void (*callback)( return REC_ERR_FAIL; } + if (rec_type & RECT_PLUGIN) { // ToDo: This should change if we use the new metrics for core metrics + RecRecord r; + + r.rec_type = RECT_PLUGIN; + r.data_type = RECD_INT; + + for (auto &&[name, val] : ts::Metrics::getInstance()) { + if (regex.match(name.data()) >= 0) { + r.name = name.data(); + r.data.rec_int = val; + callback(&r, data); + } + } + } + num_records = g_num_records; for (int i = 0; i < num_records; i++) { RecRecord *r = &(g_records[i]); @@ -1062,6 +1086,15 @@ RecDumpRecords(RecT rec_type, RecDumpEntryCb callback, void *edata) rec_mutex_release(&(r->lock)); } } + // Also dump the new ts::Metrics if asked for + if (rec_type & RECT_PLUGIN) { // ToDo: This should change if we use the new metrics for core metrics + RecData datum; + + for (auto &&[name, val] : ts::Metrics::getInstance()) { + datum.rec_int = val; + callback(RECT_PLUGIN, edata, true, name.data(), TS_RECORDDATATYPE_INT, &datum); + } + } } void diff --git a/src/records/RecUtils.cc b/src/records/RecUtils.cc index e229a41f6f..53f27afcbf 100644 --- a/src/records/RecUtils.cc +++ b/src/records/RecUtils.cc @@ -50,8 +50,8 @@ RecRecordFree(RecRecord *r) RecRecord * RecAlloc(RecT rec_type, const char *name, RecDataT data_type) { - if (g_num_records >= max_records_entries) { - Warning("too many stats/configs, please increase max_records_entries using the --maxRecords command line option"); + if (g_num_records >= REC_MAX_RECORDS) { + Warning("too many stats/configs, please report a bug to d...@trafficserver.apache.org"); return nullptr; } diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 3e59226c69..6ba08015e3 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -46,7 +46,9 @@ link_libraries( inkcache fastlz aio + records tscore + tsapi tscpputil proxy inknet diff --git a/src/traffic_crashlog/CMakeLists.txt b/src/traffic_crashlog/CMakeLists.txt index 3f43c20ba6..13df48df1b 100644 --- a/src/traffic_crashlog/CMakeLists.txt +++ b/src/traffic_crashlog/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(traffic_crashlog ts::inkevent ts::records ts::tscore + ts::tsapi ) install(TARGETS traffic_crashlog) diff --git a/src/traffic_crashlog/Makefile.inc b/src/traffic_crashlog/Makefile.inc index f7c69fe6d8..e73314ab6c 100644 --- a/src/traffic_crashlog/Makefile.inc +++ b/src/traffic_crashlog/Makefile.inc @@ -41,4 +41,5 @@ traffic_crashlog_traffic_crashlog_LDADD = \ $(top_builddir)/iocore/net/libinknet.a \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/api/libtsapi.la \ @HWLOC_LIBS@ @SWOC_LIBS@ @YAMLCPP_LIBS@ @LIBPCRE@ @LIBCAP@ diff --git a/src/traffic_layout/CMakeLists.txt b/src/traffic_layout/CMakeLists.txt index e898d65cba..7a02a6a507 100644 --- a/src/traffic_layout/CMakeLists.txt +++ b/src/traffic_layout/CMakeLists.txt @@ -28,6 +28,10 @@ target_link_libraries(traffic_layout ts::records OpenSSL::Crypto yaml-cpp::yaml-cpp + ts::tscore + ts::tsapi + PCRE::PCRE + ${OPENSSL_LIBRARY} ) if(TS_USE_HWLOC) diff --git a/src/traffic_layout/Makefile.inc b/src/traffic_layout/Makefile.inc index 6f7409c9d0..d4f2637a90 100644 --- a/src/traffic_layout/Makefile.inc +++ b/src/traffic_layout/Makefile.inc @@ -45,4 +45,5 @@ traffic_layout_traffic_layout_LDADD = \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/api/libtsapi.la \ @SWOC_LIBS@ @HWLOC_LIBS@ @YAMLCPP_LIBS@ @LIBLZMA@ @LIBPCRE@ @LIBCAP@ diff --git a/src/traffic_logcat/Makefile.inc b/src/traffic_logcat/Makefile.inc index 44677d66f3..199c851b1f 100644 --- a/src/traffic_logcat/Makefile.inc +++ b/src/traffic_logcat/Makefile.inc @@ -46,6 +46,7 @@ traffic_logcat_traffic_logcat_LDADD = \ $(top_builddir)/iocore/utils/libinkutils.a \ $(top_builddir)/src/tscore/libtscore.a \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ + $(top_builddir)/src/api/libtsapi.la \ @SWOC_LIBS@ @HWLOC_LIBS@ \ @YAMLCPP_LIBS@ @LIBPCRE@ @OPENSSL_LIBS@ @LIBCAP@ \ @LIBPROFILER@ -lm diff --git a/src/traffic_logstats/Makefile.inc b/src/traffic_logstats/Makefile.inc index 3afd3960d8..f446f49735 100644 --- a/src/traffic_logstats/Makefile.inc +++ b/src/traffic_logstats/Makefile.inc @@ -50,11 +50,12 @@ traffic_logstats_traffic_logstats_LDADD = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/iocore/utils/libinkutils.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ + @OPENSSL_LIBS@ \ @SWOC_LIBS@ \ @HWLOC_LIBS@ \ - @OPENSSL_LIBS@ \ + @LIBCAP@ \ @LIBPCRE@ \ @YAMLCPP_LIBS@ \ - @LIBCAP@ \ @LIBPROFILER@ -lm diff --git a/src/traffic_server/CMakeLists.txt b/src/traffic_server/CMakeLists.txt index 390c8edefd..35325b9026 100644 --- a/src/traffic_server/CMakeLists.txt +++ b/src/traffic_server/CMakeLists.txt @@ -35,6 +35,7 @@ target_include_directories(traffic_server PRIVATE target_link_libraries(traffic_server PRIVATE ts::tscore + ts::tsapi ts::http ts::http_remap ts::http2 diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index a400fc3d36..3ad360b06a 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -34,6 +34,7 @@ #include "tscore/I_Layout.h" #include "tscore/I_Version.h" #include "tscore/Diags.h" +#include "api/Metrics.h" #include "InkAPIInternal.h" #include "Log.h" @@ -102,10 +103,6 @@ extern AppVersionInfo appVersionInfo; -// Globals for new librecords stats -static int api_rsb_index; -static RecRawStatBlock *api_rsb; - /** Reservation for a user arg. */ struct UserArg { @@ -389,6 +386,7 @@ HttpAPIHooks *http_global_hooks = nullptr; SslAPIHooks *ssl_hooks = nullptr; LifecycleAPIHooks *lifecycle_hooks = nullptr; ConfigUpdateCbTable *global_config_cbs = nullptr; +static ts::Metrics &global_api_metrics = ts::Metrics::getInstance(); static char traffic_server_version[128] = ""; static int ts_major_version = 0; @@ -752,11 +750,7 @@ sdk_sanity_check_null_ptr(void const *ptr) static TSReturnCode sdk_sanity_check_stat_id(int id) { - if (id < 0 || id >= api_rsb->max_stats) { - return TS_ERROR; - } - - return TS_SUCCESS; + return (global_api_metrics.valid(id) ? TS_SUCCESS : TS_ERROR); } static TSReturnCode @@ -1829,18 +1823,6 @@ api_init() lifecycle_hooks = new LifecycleAPIHooks; global_config_cbs = new ConfigUpdateCbTable; - int api_metrics = max_records_entries - REC_INTERNAL_RECORDS; - if (api_metrics > 0) { - api_rsb = RecAllocateRawStatBlock(api_metrics); - if (nullptr == api_rsb) { - Warning("Can't allocate API stats block"); - } else { - Debug("sdk", "initialized SDK stats APIs with %d slots", api_metrics); - } - } else { - api_rsb = nullptr; - } - // Setup the version string for returning to plugins ink_strlcpy(traffic_server_version, appVersionInfo.VersionStr, sizeof(traffic_server_version)); // Extract the elements. @@ -7511,40 +7493,9 @@ TSCacheScan(TSCont contp, TSCacheKey key, int KB_per_second) int TSStatCreate(const char *the_name, TSRecordDataType the_type, TSStatPersistence persist, TSStatSync sync) { - int id = ink_atomic_increment(&api_rsb_index, 1); - RecRawStatSyncCb syncer = RecRawStatSyncCount; - - // TODO: This only supports "int" data types at this point, since the "Raw" stats - // interfaces only supports integers. Going forward, we could extend either the "Raw" - // stats APIs, or make non-int use the direct (synchronous) stats APIs (slower). - if ((sdk_sanity_check_null_ptr((void *)the_name) != TS_SUCCESS) || (sdk_sanity_check_null_ptr((void *)api_rsb) != TS_SUCCESS) || - (id >= api_rsb->max_stats)) { - return TS_ERROR; - } - - switch (sync) { - case TS_STAT_SYNC_SUM: - syncer = RecRawStatSyncSum; - break; - case TS_STAT_SYNC_AVG: - syncer = RecRawStatSyncAvg; - break; - case TS_STAT_SYNC_TIMEAVG: - syncer = RecRawStatSyncHrTimeAvg; - break; - default: - syncer = RecRawStatSyncCount; - break; - } + int id = global_api_metrics.newMetric(the_name); - switch (persist) { - case TS_STAT_PERSISTENT: - RecRegisterRawStat(api_rsb, RECT_PLUGIN, the_name, (RecDataT)the_type, RECP_PERSISTENT, id, syncer); - break; - case TS_STAT_NON_PERSISTENT: - RecRegisterRawStat(api_rsb, RECT_PLUGIN, the_name, (RecDataT)the_type, RECP_NON_PERSISTENT, id, syncer); - break; - default: + if (id == ts::Metrics::NOT_FOUND) { return TS_ERROR; } @@ -7555,49 +7506,44 @@ void TSStatIntIncrement(int id, TSMgmtInt amount) { sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS); - RecIncrRawStat(api_rsb, nullptr, id, amount); + global_api_metrics[id].fetch_add(amount); } void TSStatIntDecrement(int id, TSMgmtInt amount) { - RecDecrRawStat(api_rsb, nullptr, id, amount); + sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS); + global_api_metrics[id].fetch_sub(amount); } TSMgmtInt TSStatIntGet(int id) { - TSMgmtInt value; - sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS); - RecGetGlobalRawStatSum(api_rsb, id, &value); - return value; + return global_api_metrics[id].load(); } void TSStatIntSet(int id, TSMgmtInt value) { sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS); - RecSetGlobalRawStatSum(api_rsb, id, value); + global_api_metrics[id].store(value); } TSReturnCode TSStatFindName(const char *name, int *idp) { - int id; - sdk_assert(sdk_sanity_check_null_ptr((void *)name) == TS_SUCCESS); + sdk_assert(sdk_sanity_check_null_ptr((void *)idp) == TS_SUCCESS); - if (RecGetRecordOrderAndId(name, nullptr, &id, true, true) != REC_ERR_OKAY) { - return TS_ERROR; - } + int id = global_api_metrics.lookup(name); - if (RecGetGlobalRawStatPtr(api_rsb, id) == nullptr) { + if (id == ts::Metrics::NOT_FOUND) { return TS_ERROR; + } else { + *idp = id; + return TS_SUCCESS; } - - *idp = id; - return TS_SUCCESS; } /************************** Tracing API ****************************/ diff --git a/src/traffic_server/Makefile.inc b/src/traffic_server/Makefile.inc index 136c1a52aa..4926ce79e6 100644 --- a/src/traffic_server/Makefile.inc +++ b/src/traffic_server/Makefile.inc @@ -78,6 +78,7 @@ traffic_server_traffic_server_LDADD = \ $(top_builddir)/iocore/cache/libinkcache.a \ $(top_builddir)/lib/fastlz/libfastlz.a \ $(top_builddir)/iocore/aio/libinkaio.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/proxy/libproxy.a \ $(top_builddir)/iocore/net/libinknet.a \ $(top_builddir)/src/records/librecords_p.a \ diff --git a/src/traffic_server/traffic_server.cc b/src/traffic_server/traffic_server.cc index fd9a3635b0..cd52b915a7 100644 --- a/src/traffic_server/traffic_server.cc +++ b/src/traffic_server/traffic_server.cc @@ -207,8 +207,6 @@ static ArgumentDescription argument_descriptions[] = { {"disable_freelist", 'f', "Disable the freelist memory allocator", "T", &cmd_disable_freelist, "PROXY_DPRINTF_LEVEL", nullptr}, {"disable_pfreelist", 'F', "Disable the freelist memory allocator in ProxyAllocator", "T", &cmd_disable_pfreelist, "PROXY_DPRINTF_LEVEL", nullptr}, - {"maxRecords", 'm', "Max number of librecords metrics and configurations (default & minimum: 1600)", "I", &max_records_entries, - "PROXY_MAX_RECORDS", nullptr}, #if TS_HAS_TESTS {"regression", 'R', "Regression Level (quick:1..long:3)", "I", ®ression_level, "PROXY_REGRESSION", nullptr}, diff --git a/tools/benchmark/Makefile.am b/tools/benchmark/Makefile.am index 93417a0fff..772fe19208 100644 --- a/tools/benchmark/Makefile.am +++ b/tools/benchmark/Makefile.am @@ -49,6 +49,7 @@ benchmark_LD_ADD = \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ $(top_builddir)/src/records/librecords_p.a \ $(top_builddir)/src/tscore/libtscore.a \ + $(top_builddir)/src/api/libtsapi.la \ $(top_builddir)/src/tscpp/util/libtscpputil.la \ @HWLOC_LIBS@ \ @LIBPCRE@ \