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 <[email protected]>
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 <[email protected]>
* 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
[email protected]");
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@ \