From: Amos Jeffries Date: Sat, 31 Jan 2015 19:09:22 +0000 (+1300) Subject: Per-rule refresh_pattern matching statistics X-Git-Tag: merge-candidate-3-v1~307 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5ea775169885e224f977702e8a759c4044b868a;p=thirdparty%2Fsquid.git Per-rule refresh_pattern matching statistics .. to make it blindingly obvious from the cachemgr report which rules are completely useless. Such as when the global dot pattern (.) is placed ahead of custom rules, or one rules pattern is always a subset of an earlier pattern. This also allows sysadmin to tune refresh_pattern ordering so most commonly matching rules are first. --- diff --git a/src/RefreshPattern.h b/src/RefreshPattern.h index 506f5eefd4..da2c5237c6 100644 --- a/src/RefreshPattern.h +++ b/src/RefreshPattern.h @@ -38,6 +38,13 @@ public: #endif } flags; int max_stale; + + // statistics about how many matches this pattern has had + mutable struct stats_ { + uint64_t matchTests; + uint64_t matchCount; + // TODO: some stats to indicate how useful/less the flags are would be nice. + } stats; }; #endif /* SQUID_REFRESHPATTERN_H_ */ diff --git a/src/refresh.cc b/src/refresh.cc index f57060768a..cdd015356e 100644 --- a/src/refresh.cc +++ b/src/refresh.cc @@ -107,8 +107,11 @@ refreshLimits(const char *url) const RefreshPattern *R; for (R = Config.Refresh; R; R = R->next) { - if (!regexec(&(R->compiled_pattern), url, 0, 0, 0)) + ++(R->stats.matchTests); + if (!regexec(&(R->compiled_pattern), url, 0, 0, 0)) { + ++(R->stats.matchCount); return R; + } } return NULL; @@ -694,14 +697,24 @@ refreshCountsStats(StoreEntry * sentry, struct RefreshCounts &rc) sum += refreshCountsStatsEntry(sentry, rc, STALE_MAX_RULE, "Stale: refresh_pattern max age rule"); sum += refreshCountsStatsEntry(sentry, rc, STALE_LMFACTOR_RULE, "Stale: refresh_pattern last-mod factor percentage"); sum += refreshCountsStatsEntry(sentry, rc, STALE_DEFAULT, "Stale: by default"); - - storeAppendPrintf(sentry, "%6d\t%6.2f\tTOTAL\n", rc.total, xpercent(rc.total, sum)); storeAppendPrintf(sentry, "\n"); } static void refreshStats(StoreEntry * sentry) { + // display per-rule counts of usage and tests + storeAppendPrintf(sentry, "\nRefresh pattern usage:\n\n"); + storeAppendPrintf(sentry, " Used \tChecks \t%% Matches\tPattern\n"); + for (const RefreshPattern *R = Config.Refresh; R; R = R->next) { + storeAppendPrintf(sentry, " %10" PRIu64 "\t%10" PRIu64 "\t%6.2f\t%s%s\n", + R->stats.matchCount, + R->stats.matchTests, + xpercent(R->stats.matchCount, R->stats.matchTests), + (R->flags.icase ? "-i " : ""), + R->pattern); + } + int i; int total = 0;