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 _<<Configuration>>_ for
*--print-log-stats*::
Print statistics counters from the stats log in machine-parseable
- (tab-separated) format. See <<config_stats_log,*stats_log*>>.
+ (tab-separated or JSON) format. See <<config_stats_log,*stats_log*>> and
+ `--format`.
*--print-stats*::
Print statistics counter IDs and corresponding values in machine-parsable
- (tab-separated) format.
+ (tab-separated or JSON) format. See `--format`.
END = 84
};
+enum class StatisticFormat {
+ Tab,
+ Json,
+};
+
} // namespace core
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<std::string> lines;
return util::join(lines, "");
}
+std::string
+Statistics::format_json(const Config& config,
+ const util::TimePoint& last_updated) const
+{
+ std::vector<std::string> 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<std::string, Statistic>
Statistics::get_id_map()
{
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;
uint64_t count_stats(unsigned flags) const;
std::vector<std::pair<std::string, uint64_t>> 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 ---
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
EVICT_NAMESPACE,
EVICT_OLDER_THAN,
EXTRACT_RESULT,
+ FORMAT,
HASH_FILE,
INSPECT,
PRINT_LOG_STATS,
{"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'},
uint8_t verbosity = 0;
+ StatisticFormat format = StatisticFormat::Tab;
std::optional<uint64_t> trim_max_size;
std::optional<util::SizeUnitPrefixType> trim_suffix_type;
bool trim_lru_mtime = false;
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);
switch (c) {
case CONFIG_PATH:
case 'd': // --dir
+ case FORMAT:
case RECOMPRESS_THREADS:
case TRIM_MAX_SIZE:
case TRIM_METHOD:
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;
}
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;
}