From bdc8c22db889ba4a4e4cba6d3a893551ecc21449 Mon Sep 17 00:00:00 2001 From: Sudheer Vinukonda Date: Fri, 28 May 2021 13:34:44 -0700 Subject: [PATCH] Add hit stats for remap rules Ordering of remap rules in remap.config in an efficient manner is very important as it can have a significant impact on performance and throughput that can be achieved using ATS as a proxy server. For example, ATS uses a prefix trie to match a forward map rule, but, has to run through the regex_map rules sequentially. Interleaving regex_map rules with forward map rules can thus result in unnecessary overhead when those rules are not overlapping. Further, within regex_map rules, as far as possible ordering them based on their "hit" rate (decreasing order) can result in a significant performance improvement. This change adds stats to track hit rate for each remap rule (based on their line number/rank in the remap.config file) to allow for such visibility. --- mgmt/RecordsConfig.cc | 2 ++ proxy/http/remap/UrlRewrite.cc | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc index 2d5ed23393e..453622ea7b9 100644 --- a/mgmt/RecordsConfig.cc +++ b/mgmt/RecordsConfig.cc @@ -1470,6 +1470,8 @@ static const RecordElement RecordsConfig[] = //# Librecords based stats system (new as of v2.1.3) {RECT_CONFIG, "proxy.config.stat_api.max_stats_allowed", RECD_INT, "256", RECU_RESTART_TS, RR_NULL, RECC_INT, "[256-1000]", RECA_NULL} , + {RECT_CONFIG, "proxy.config.stat_remap.max_stats_allowed", RECD_INT, "256", RECU_RESTART_TS, RR_NULL, RECC_NULL, nullptr, RECA_NULL} + , //############ //# diff --git a/proxy/http/remap/UrlRewrite.cc b/proxy/http/remap/UrlRewrite.cc index bc81632d882..54cb0941197 100644 --- a/proxy/http/remap/UrlRewrite.cc +++ b/proxy/http/remap/UrlRewrite.cc @@ -32,6 +32,24 @@ #define modulePrefix "[ReverseProxy]" +static RecRawStatBlock *remap_rsb = nullptr; +static uint32_t max_remap_stats = 256; + +static void +register_remap_stats() +{ + if (remap_rsb != nullptr) { + return; + } + + remap_rsb = RecAllocateRawStatBlock(static_cast(max_remap_stats + 1)); + + for (size_t id = 1; id <= max_remap_stats; id++) { + std::string name = "remap.rule." + std::to_string(id); + RecRegisterRawStat(remap_rsb, RECT_PROCESS, name.c_str(), RECD_COUNTER, RECP_NON_PERSISTENT, id, RecRawStatSyncSum); + } +} + /** Determines where we are in a situation where a virtual path is being mapped to a server home page. If it is, we set a special flag @@ -81,6 +99,8 @@ UrlRewrite::load() REC_ReadConfigInteger(reverse_proxy, "proxy.config.reverse_proxy.enabled"); + REC_ReadConfigInteger(max_remap_stats, "proxy.config.stat_remap.max_stats_allowed"); + /* Initialize the plugin factory */ pluginFactory.setRuntimeDir(RecConfigReadRuntimeDir()).addSearchDir(RecConfigReadPluginDir()); @@ -688,6 +708,10 @@ UrlRewrite::BuildTable(const char *path) forward_mappings_with_recv_port.hash_lookup.reset(nullptr); } + if (zret == 0) { + register_remap_stats(); + } + return zret; } @@ -766,6 +790,16 @@ UrlRewrite::_mappingLookup(MappingsStore &mappings, URL *request_url, int reques Debug("url_rewrite", "Using regex mapping with rank %d", (mapping_container.getMapping())->getRank()); retval = true; } + + if (retval) { + int id = 1 + (mapping_container.getMapping())->getRank(); + if ((size_t)id < max_remap_stats) { + RecIncrRawStatSum(remap_rsb, this_ethread(), id, 1); + } else { + Debug("url_rewrite", "can't update stat, too many remap rules, max_stats configured %u, remap id %d", max_remap_stats, id); + } + } + return retval; }