From: Kaspar Schleiser Date: Mon, 22 Jan 2024 19:22:06 +0000 (+0100) Subject: feat: Add `--print-stats` format selection, JSON format (#1382) X-Git-Tag: v4.10~124 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c03c7e478fd9b330e7117dab6d6a41124b31d81;p=thirdparty%2Fccache.git feat: Add `--print-stats` format selection, JSON format (#1382) --- diff --git a/doc/MANUAL.adoc b/doc/MANUAL.adoc index 572eb0a27..0e9710ff7 100644 --- a/doc/MANUAL.adoc +++ b/doc/MANUAL.adoc @@ -258,6 +258,18 @@ directory to a certain size, use `CCACHE_MAXSIZE=_SIZE_ ccache -c`. working directory. This option is only useful when debugging ccache and its behavior. +*--format* _FORMAT_:: + + Specify format for `--print-log-stats` and `--print-stats`. Possible values + are: ++ +-- +*tab*:: + Tab separated. This is the default. +*json*:: + JSON formatted. +-- + *-k* _KEY_, *--get-config* _KEY_:: Print the value of configuration option _KEY_. See _<>_ for @@ -279,12 +291,13 @@ directory to a certain size, use `CCACHE_MAXSIZE=_SIZE_ ccache -c`. *--print-log-stats*:: Print statistics counters from the stats log in machine-parseable - (tab-separated) format. See <>. + (tab-separated or JSON) format. See <> and + `--format`. *--print-stats*:: Print statistics counter IDs and corresponding values in machine-parsable - (tab-separated) format. + (tab-separated or JSON) format. See `--format`. diff --git a/src/core/Statistic.hpp b/src/core/Statistic.hpp index 22b5fe71d..26926fc02 100644 --- a/src/core/Statistic.hpp +++ b/src/core/Statistic.hpp @@ -84,4 +84,9 @@ enum class Statistic { END = 84 }; +enum class StatisticFormat { + Tab, + Json, +}; + } // namespace core diff --git a/src/core/Statistics.cpp b/src/core/Statistics.cpp index c2fefba2b..3ae77ae4e 100644 --- a/src/core/Statistics.cpp +++ b/src/core/Statistics.cpp @@ -525,7 +525,22 @@ Statistics::format_human_readable(const Config& config, std::string Statistics::format_machine_readable(const Config& config, - const util::TimePoint& last_updated) const + const util::TimePoint& last_updated, + const StatisticFormat format) const +{ + switch (format) { + case StatisticFormat::Json: + return Statistics::format_json(config, last_updated); + case StatisticFormat::Tab: + /* fall through */ + default: + return Statistics::format_tab_separated(config, last_updated); + } +} + +std::string +Statistics::format_tab_separated(const Config& config, + const util::TimePoint& last_updated) const { std::vector lines; @@ -548,6 +563,32 @@ Statistics::format_machine_readable(const Config& config, return util::join(lines, ""); } +std::string +Statistics::format_json(const Config& config, + const util::TimePoint& last_updated) const +{ + std::vector lines; + + auto add_line = [&](auto id, auto value) { + lines.push_back(FMT("\"{}\": {}", id, value)); + }; + + add_line("stats_updated_timestamp", last_updated.sec()); + + for (const auto& field : k_statistics_fields) { + if (!(field.flags & FLAG_NEVER)) { + add_line(field.id, m_counters.get(field.statistic)); + } + } + + add_line("max_cache_size_kibibyte", config.max_size() / 1024); + add_line("max_files_in_cache", config.max_files()); + + std::sort(lines.begin(), lines.end()); + std::string result = "{\n " + util::join(lines, ",\n ") + "\n}\n"; + return result; +} + std::unordered_map Statistics::get_id_map() { diff --git a/src/core/Statistics.hpp b/src/core/Statistics.hpp index b2deab712..f0951ed28 100644 --- a/src/core/Statistics.hpp +++ b/src/core/Statistics.hpp @@ -46,9 +46,9 @@ public: bool from_log) const; // Format cache statistics in machine-readable format. - std::string - format_machine_readable(const Config& config, - const util::TimePoint& last_updated) const; + std::string format_machine_readable(const Config& config, + const util::TimePoint& last_updated, + const StatisticFormat format) const; const StatisticsCounters& counters() const; @@ -62,6 +62,12 @@ private: uint64_t count_stats(unsigned flags) const; std::vector> get_stats(unsigned flags, bool all) const; + // Format cache statistics in tab-separated format. + std::string format_tab_separated(const Config& config, + const util::TimePoint& last_updated) const; + // Format cache statistics in JSON format. + std::string format_json(const Config& config, + const util::TimePoint& last_updated) const; }; // --- Inline implementations --- diff --git a/src/core/mainoptions.cpp b/src/core/mainoptions.cpp index d11e6c43c..371a272fa 100644 --- a/src/core/mainoptions.cpp +++ b/src/core/mainoptions.cpp @@ -168,6 +168,8 @@ Options for scripting or debugging: PATH --extract-result PATH extract file data stored in result file at PATH to the current working directory + --format FORMAT specify format for --print-log-stats and + --print-stats (tab, json); default: tab -k, --get-config KEY print the value of configuration key KEY --hash-file PATH print the hash (160 bit BLAKE3) of the file at PATH @@ -423,6 +425,7 @@ enum { EVICT_NAMESPACE, EVICT_OLDER_THAN, EXTRACT_RESULT, + FORMAT, HASH_FILE, INSPECT, PRINT_LOG_STATS, @@ -449,6 +452,7 @@ const option long_options[] = { {"evict-namespace", required_argument, nullptr, EVICT_NAMESPACE}, {"evict-older-than", required_argument, nullptr, EVICT_OLDER_THAN}, {"extract-result", required_argument, nullptr, EXTRACT_RESULT}, + {"format", required_argument, nullptr, FORMAT}, {"get-config", required_argument, nullptr, 'k'}, {"hash-file", required_argument, nullptr, HASH_FILE}, {"help", no_argument, nullptr, 'h'}, @@ -484,6 +488,7 @@ process_main_options(int argc, const char* const* argv) uint8_t verbosity = 0; + StatisticFormat format = StatisticFormat::Tab; std::optional trim_max_size; std::optional trim_suffix_type; bool trim_lru_mtime = false; @@ -508,6 +513,16 @@ process_main_options(int argc, const char* const* argv) case 'd': // --dir util::setenv("CCACHE_DIR", arg); break; + case FORMAT: + if (arg == "tab") { + format = StatisticFormat::Tab; + } else if (arg == "json") { + format = StatisticFormat::Json; + } else { + PRINT(stderr, "Error: unknown format \"{}\"\n", arg); + return EXIT_FAILURE; + } + break; case CONFIG_PATH: util::setenv("CCACHE_CONFIGPATH", arg); @@ -569,6 +584,7 @@ process_main_options(int argc, const char* const* argv) switch (c) { case CONFIG_PATH: case 'd': // --dir + case FORMAT: case RECOMPRESS_THREADS: case TRIM_MAX_SIZE: case TRIM_METHOD: @@ -647,8 +663,9 @@ process_main_options(int argc, const char* const* argv) const auto [counters, last_updated] = storage::local::LocalStorage(config).get_all_statistics(); Statistics statistics(counters); - PRINT_RAW(stdout, - statistics.format_machine_readable(config, last_updated)); + PRINT_RAW( + stdout, + statistics.format_machine_readable(config, last_updated, format)); break; } @@ -745,7 +762,8 @@ process_main_options(int argc, const char* const* argv) Statistics statistics(StatsLog(config.stats_log()).read()); const auto timestamp = DirEntry(config.stats_log(), DirEntry::LogOnError::yes).mtime(); - PRINT_RAW(stdout, statistics.format_machine_readable(config, timestamp)); + PRINT_RAW(stdout, + statistics.format_machine_readable(config, timestamp, format)); break; }