From: Joel Rosdahl Date: Wed, 11 May 2022 17:57:50 +0000 (+0200) Subject: feat: Improve --show-stats X-Git-Tag: v4.7~216 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a69e6f6a1f635b4f658f424df69b9c70354b0967;p=thirdparty%2Fccache.git feat: Improve --show-stats - Added percentage for most values. - All indented values now have their total count equal to the parent value. - Moved presentation of {direct,preprocessed}_cache_{hit,miss} counters to a separate "Successful lookups" section. - Removed "Use the -v/--verbose option for more details." from --show-stats output since it's a bit wordy. --- diff --git a/src/core/Statistics.cpp b/src/core/Statistics.cpp index c1f0a52c7..0f6c04562 100644 --- a/src/core/Statistics.cpp +++ b/src/core/Statistics.cpp @@ -146,9 +146,9 @@ percent(const uint64_t nominator, const uint64_t denominator) if (denominator == 0) { return ""; } else if (nominator >= denominator) { - return FMT("({:.1f} %)", (100.0 * nominator) / denominator); + return FMT("({:5.1f}%)", (100.0 * nominator) / denominator); } else { - return FMT("({:.2f} %)", (100.0 * nominator) / denominator); + return FMT("({:5.2f}%)", (100.0 * nominator) / denominator); } } @@ -197,6 +197,25 @@ Statistics::get_stats(unsigned flags, const bool all) const return result; } +static void +add_ratio_row(util::TextTable& table, + const std::string& text, + const uint64_t nominator, + const uint64_t denominator) +{ + if (denominator > 0) { + table.add_row({ + text, + nominator, + "/", + denominator, + percent(nominator, denominator), + }); + } else { + table.add_row({text, nominator}); + } +} + std::string Statistics::format_human_readable(const Config& config, const time_t last_updated, @@ -214,54 +233,67 @@ Statistics::format_human_readable(const Config& config, const uint64_t p_misses = S(preprocessed_cache_miss); const uint64_t hits = d_hits + p_hits; const uint64_t misses = S(cache_miss); + const uint64_t uncacheable = count_stats(FLAG_UNCACHEABLE); + const uint64_t errors = count_stats(FLAG_ERROR); + const uint64_t total_calls = hits + misses + errors + uncacheable; + + auto cmp_fn = [](const auto& e1, const auto& e2) { + return e1.first.compare(e2.first) < 0; + }; - table.add_heading("Summary:"); if (verbosity > 0 && !from_log) { - table.add_row({" Cache directory:", C(config.cache_dir()).colspan(4)}); + table.add_row({"Cache directory:", C(config.cache_dir()).colspan(4)}); table.add_row( - {" Primary config:", C(config.primary_config_path()).colspan(4)}); + {"Primary config:", C(config.primary_config_path()).colspan(4)}); table.add_row( - {" Secondary config:", C(config.secondary_config_path()).colspan(4)}); + {"Secondary config:", C(config.secondary_config_path()).colspan(4)}); table.add_row( - {" Stats updated:", C(format_timestamp(last_updated)).colspan(4)}); + {"Stats updated:", C(format_timestamp(last_updated)).colspan(4)}); if (verbosity > 1) { const uint64_t last_zeroed = S(stats_zeroed_timestamp); table.add_row( - {" Stats zeroed:", C(format_timestamp(last_zeroed)).colspan(4)}); + {"Stats zeroed:", C(format_timestamp(last_zeroed)).colspan(4)}); } } - table.add_row({ - " Hits:", - hits, - "/", - hits + misses, - percent(hits, hits + misses), - }); - table.add_row({ - " Direct:", - d_hits, - "/", - d_hits + d_misses, - percent(d_hits, d_hits + d_misses), - }); - table.add_row({ - " Preprocessed:", - p_hits, - "/", - p_hits + p_misses, - percent(p_hits, p_hits + p_misses), - }); - table.add_row({" Misses:", misses}); - table.add_row({" Direct:", d_misses}); - table.add_row({" Preprocessed:", p_misses}); - - const auto errors = count_stats(FLAG_ERROR); - const auto uncacheable = count_stats(FLAG_UNCACHEABLE); - if (verbosity > 1 || errors > 0) { - table.add_row({" Errors:", errors}); + + if (total_calls > 0 || verbosity > 1) { + add_ratio_row(table, "Cacheable calls:", hits + misses, total_calls); + add_ratio_row(table, " Hits:", hits, hits + misses); + add_ratio_row(table, " Direct:", d_hits, hits); + add_ratio_row(table, " Preprocessed:", p_hits, hits); + add_ratio_row(table, " Misses:", misses, hits + misses); } - if (verbosity > 1 || uncacheable > 0) { - table.add_row({" Uncacheable:", uncacheable}); + + if (uncacheable > 0 || verbosity > 1) { + add_ratio_row(table, "Uncacheable calls:", uncacheable, total_calls); + if (verbosity > 0) { + auto uncacheable_stats = get_stats(FLAG_UNCACHEABLE, verbosity > 1); + std::sort(uncacheable_stats.begin(), uncacheable_stats.end(), cmp_fn); + for (const auto& descr_count : uncacheable_stats) { + add_ratio_row(table, + FMT(" {}:", descr_count.first), + descr_count.second, + uncacheable); + } + } + } + + if (errors > 0 || verbosity > 1) { + add_ratio_row(table, "Errors:", errors, total_calls); + if (verbosity > 0) { + auto error_stats = get_stats(FLAG_ERROR, verbosity > 1); + std::sort(error_stats.begin(), error_stats.end(), cmp_fn); + for (const auto& descr_count : error_stats) { + add_ratio_row( + table, FMT(" {}:", descr_count.first), descr_count.second, errors); + } + } + } + + if (total_calls > 0 && verbosity > 0) { + table.add_heading("Successful lookups:"); + add_ratio_row(table, " Direct:", d_hits, d_hits + d_misses); + add_ratio_row(table, " Preprocessed:", p_hits, p_hits + p_misses); } const uint64_t g = 1'000'000'000; @@ -270,14 +302,8 @@ Statistics::format_human_readable(const Config& config, const uint64_t pri_size = S(cache_size_kibibyte) * 1024; const uint64_t cleanups = S(cleanups_performed); table.add_heading("Primary storage:"); - table.add_row({ - " Hits:", - pri_hits, - "/", - pri_hits + pri_misses, - percent(pri_hits, pri_hits + pri_misses), - }); - table.add_row({" Misses:", pri_misses}); + add_ratio_row(table, " Hits:", pri_hits, pri_hits + pri_misses); + add_ratio_row(table, " Misses:", pri_misses, pri_hits + pri_misses); if (!from_log) { table.add_row({ " Cache size (GB):", @@ -308,14 +334,8 @@ Statistics::format_human_readable(const Config& config, if (verbosity > 1 || sec_hits + sec_misses + sec_errors + sec_timeouts > 0) { table.add_heading("Secondary storage:"); - table.add_row({ - " Hits:", - sec_hits, - "/", - sec_hits + sec_misses, - percent(sec_hits, sec_hits + sec_misses), - }); - table.add_row({" Misses:", sec_misses}); + add_ratio_row(table, " Hits:", sec_hits, sec_hits + sec_misses); + add_ratio_row(table, " Misses:", sec_misses, sec_hits + sec_misses); if (verbosity > 1 || sec_errors > 0) { table.add_row({" Errors:", sec_errors}); } @@ -324,28 +344,6 @@ Statistics::format_human_readable(const Config& config, } } - auto cmp_fn = [](const auto& e1, const auto& e2) { - return e1.first.compare(e2.first) < 0; - }; - - if (verbosity > 1 || (verbosity == 1 && errors > 0)) { - auto error_stats = get_stats(FLAG_ERROR, verbosity > 1); - std::sort(error_stats.begin(), error_stats.end(), cmp_fn); - table.add_heading("Errors:"); - for (const auto& descr_count : error_stats) { - table.add_row({FMT(" {}:", descr_count.first), descr_count.second}); - } - } - - if (verbosity > 1 || (verbosity == 1 && uncacheable > 0)) { - auto uncacheable_stats = get_stats(FLAG_UNCACHEABLE, verbosity > 1); - std::sort(uncacheable_stats.begin(), uncacheable_stats.end(), cmp_fn); - table.add_heading("Uncacheable:"); - for (const auto& descr_count : uncacheable_stats) { - table.add_row({FMT(" {}:", descr_count.first), descr_count.second}); - } - } - return table.render(); } diff --git a/src/core/mainoptions.cpp b/src/core/mainoptions.cpp index 73d5c054a..ef3c9d2f9 100644 --- a/src/core/mainoptions.cpp +++ b/src/core/mainoptions.cpp @@ -112,7 +112,8 @@ Common options: --show-log-stats print statistics counters from the stats log in human-readable format -s, --show-stats show summary of configuration and statistics - counters in human-readable format + counters in human-readable format (use + -v/--verbose once of twice for more details) -v, --verbose increase verbosity -z, --zero-stats zero statistics counters @@ -556,9 +557,6 @@ process_main_options(int argc, const char* const* argv) PRINT_RAW( stdout, statistics.format_human_readable(config, timestamp, verbosity, true)); - if (verbosity == 0) { - PRINT_RAW(stdout, "\nUse the -v/--verbose option for more details.\n"); - } break; } @@ -571,9 +569,6 @@ process_main_options(int argc, const char* const* argv) PRINT_RAW(stdout, statistics.format_human_readable( config, last_updated, verbosity, false)); - if (verbosity == 0) { - PRINT_RAW(stdout, "\nUse the -v/--verbose option for more details.\n"); - } break; }