summaryrefslogtreecommitdiffstats
path: root/src/osd/osd_types_fmt.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/osd_types_fmt.h')
-rw-r--r--src/osd/osd_types_fmt.h339
1 files changed, 339 insertions, 0 deletions
diff --git a/src/osd/osd_types_fmt.h b/src/osd/osd_types_fmt.h
new file mode 100644
index 000000000..8d4813410
--- /dev/null
+++ b/src/osd/osd_types_fmt.h
@@ -0,0 +1,339 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+#pragma once
+/**
+ * \file fmtlib formatters for some types.h classes
+ */
+
+#include "common/hobject_fmt.h"
+#include "osd/osd_types.h"
+#include <fmt/chrono.h>
+#if FMT_VERSION >= 90000
+#include <fmt/ostream.h>
+#endif
+
+template <>
+struct fmt::formatter<osd_reqid_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const osd_reqid_t& req_id, FormatContext& ctx) const
+ {
+ return fmt::format_to(ctx.out(), "{}.{}:{}", req_id.name, req_id.inc,
+ req_id.tid);
+ }
+};
+
+template <>
+struct fmt::formatter<pg_shard_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const pg_shard_t& shrd, FormatContext& ctx) const
+ {
+ if (shrd.is_undefined()) {
+ return fmt::format_to(ctx.out(), "?");
+ }
+ if (shrd.shard == shard_id_t::NO_SHARD) {
+ return fmt::format_to(ctx.out(), "{}", shrd.get_osd());
+ }
+ return fmt::format_to(ctx.out(), "{}({})", shrd.get_osd(), shrd.shard);
+ }
+};
+
+template <>
+struct fmt::formatter<eversion_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const eversion_t& ev, FormatContext& ctx) const
+ {
+ return fmt::format_to(ctx.out(), "{}'{}", ev.epoch, ev.version);
+ }
+};
+
+template <>
+struct fmt::formatter<chunk_info_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const chunk_info_t& ci, FormatContext& ctx)
+ {
+ return fmt::format_to(ctx.out(), "(len: {} oid: {} offset: {} flags: {})",
+ ci.length, ci.oid, ci.offset,
+ ci.get_flag_string(ci.flags));
+ }
+};
+
+template <>
+struct fmt::formatter<object_manifest_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const object_manifest_t& om, FormatContext& ctx) const
+ {
+ fmt::format_to(ctx.out(), "manifest({}", om.get_type_name());
+ if (om.is_redirect()) {
+ fmt::format_to(ctx.out(), " {}", om.redirect_target);
+ } else if (om.is_chunked()) {
+ fmt::format_to(ctx.out(), " {}", om.chunk_map);
+ }
+ return fmt::format_to(ctx.out(), ")");
+ }
+};
+
+template <>
+struct fmt::formatter<object_info_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const object_info_t& oi, FormatContext& ctx) const
+ {
+ fmt::format_to(ctx.out(), "{}({} {} {} s {} uv {}", oi.soid, oi.version,
+ oi.last_reqid, (oi.flags ? oi.get_flag_string() : ""), oi.size,
+ oi.user_version);
+ if (oi.is_data_digest()) {
+ fmt::format_to(ctx.out(), " dd {:x}", oi.data_digest);
+ }
+ if (oi.is_omap_digest()) {
+ fmt::format_to(ctx.out(), " od {:x}", oi.omap_digest);
+ }
+
+ fmt::format_to(ctx.out(), " alloc_hint [{} {} {}]", oi.expected_object_size,
+ oi.expected_write_size, oi.alloc_hint_flags);
+
+ if (oi.has_manifest()) {
+ fmt::format_to(ctx.out(), " {}", oi.manifest);
+ }
+ return fmt::format_to(ctx.out(), ")");
+ }
+};
+
+template <>
+struct fmt::formatter<pg_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const pg_t& pg, FormatContext& ctx) const
+ {
+ return fmt::format_to(ctx.out(), "{}.{:x}", pg.pool(), pg.m_seed);
+ }
+};
+
+
+template <>
+struct fmt::formatter<spg_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const spg_t& spg, FormatContext& ctx) const
+ {
+ if (shard_id_t::NO_SHARD == spg.shard.id) {
+ return fmt::format_to(ctx.out(), "{}", spg.pgid);
+ } else {
+ return fmt::format_to(ctx.out(), "{}s{}>", spg.pgid, spg.shard.id);
+ }
+ }
+};
+
+template <>
+struct fmt::formatter<pg_history_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const pg_history_t& pgh, FormatContext& ctx) const
+ {
+ fmt::format_to(ctx.out(),
+ "ec={}/{} lis/c={}/{} les/c/f={}/{}/{} sis={}",
+ pgh.epoch_created,
+ pgh.epoch_pool_created,
+ pgh.last_interval_started,
+ pgh.last_interval_clean,
+ pgh.last_epoch_started,
+ pgh.last_epoch_clean,
+ pgh.last_epoch_marked_full,
+ pgh.same_interval_since);
+
+ if (pgh.prior_readable_until_ub != ceph::timespan::zero()) {
+ return fmt::format_to(ctx.out(),
+ " pruub={}",
+ pgh.prior_readable_until_ub);
+ } else {
+ return ctx.out();
+ }
+ }
+};
+
+template <>
+struct fmt::formatter<pg_info_t> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ template <typename FormatContext>
+ auto format(const pg_info_t& pgi, FormatContext& ctx)
+ {
+ fmt::format_to(ctx.out(), "{}({}", pgi.pgid, (pgi.dne() ? " DNE" : ""));
+ if (pgi.is_empty()) {
+ fmt::format_to(ctx.out(), " empty");
+ } else {
+ fmt::format_to(ctx.out(), " v {}", pgi.last_update);
+ if (pgi.last_complete != pgi.last_update) {
+ fmt::format_to(ctx.out(), " lc {}", pgi.last_complete);
+ }
+ fmt::format_to(ctx.out(), " ({},{}]", pgi.log_tail, pgi.last_update);
+ }
+ if (pgi.is_incomplete()) {
+ fmt::format_to(ctx.out(), " lb {}", pgi.last_backfill);
+ }
+ fmt::format_to(ctx.out(),
+ " local-lis/les={}/{}",
+ pgi.last_interval_started,
+ pgi.last_epoch_started);
+ return fmt::format_to(ctx.out(),
+ " n={} {})",
+ pgi.stats.stats.sum.num_objects,
+ pgi.history);
+ }
+};
+
+// snaps and snap-sets
+
+template <>
+struct fmt::formatter<SnapSet> {
+ template <typename ParseContext>
+ constexpr auto parse(ParseContext& ctx)
+ {
+ auto it = ctx.begin();
+ if (it != ctx.end() && *it == 'D') {
+ verbose = true;
+ ++it;
+ }
+ return it;
+ }
+
+ template <typename FormatContext>
+ auto format(const SnapSet& snps, FormatContext& ctx)
+ {
+ if (verbose) {
+ // similar to SnapSet::dump()
+ fmt::format_to(ctx.out(),
+ "snaps{{{}: clns ({}): ",
+ snps.seq,
+ snps.clones.size());
+ for (auto cln : snps.clones) {
+
+ fmt::format_to(ctx.out(), "[{}: sz:", cln);
+
+ auto cs = snps.clone_size.find(cln);
+ if (cs != snps.clone_size.end()) {
+ fmt::format_to(ctx.out(), "{} ", cs->second);
+ } else {
+ fmt::format_to(ctx.out(), "??");
+ }
+
+ auto co = snps.clone_overlap.find(cln);
+ if (co != snps.clone_overlap.end()) {
+ fmt::format_to(ctx.out(), "olp:{} ", co->second);
+ } else {
+ fmt::format_to(ctx.out(), "olp:?? ");
+ }
+
+ auto cln_snps = snps.clone_snaps.find(cln);
+ if (cln_snps != snps.clone_snaps.end()) {
+ fmt::format_to(ctx.out(), "cl-snps:{} ]", cln_snps->second);
+ } else {
+ fmt::format_to(ctx.out(), "cl-snps:?? ]");
+ }
+ }
+
+ return fmt::format_to(ctx.out(), "}}");
+
+ } else {
+ return fmt::format_to(ctx.out(),
+ "{}={}:{}",
+ snps.seq,
+ snps.snaps,
+ snps.clone_snaps);
+ }
+ }
+
+ bool verbose{false};
+};
+
+template <>
+struct fmt::formatter<ScrubMap::object> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+ ///\todo: consider passing the 'D" flag to control snapset dump
+ template <typename FormatContext>
+ auto format(const ScrubMap::object& so, FormatContext& ctx)
+ {
+ fmt::format_to(ctx.out(),
+ "so{{ sz:{} dd:{} od:{} ",
+ so.size,
+ so.digest,
+ so.digest_present);
+
+ // note the special handling of (1) OI_ATTR and (2) non-printables
+ for (auto [k, v] : so.attrs) {
+ std::string bkstr{v.raw_c_str(), v.raw_length()};
+ if (k == std::string{OI_ATTR}) {
+ /// \todo consider parsing the OI args here. Maybe add a specific format
+ /// specifier
+ fmt::format_to(ctx.out(), "{{{}:<<OI_ATTR>>({})}} ", k, bkstr.length());
+ } else if (k == std::string{SS_ATTR}) {
+ bufferlist bl;
+ bl.push_back(v);
+ SnapSet sns{bl};
+ fmt::format_to(ctx.out(), "{{{}:{:D}}} ", k, sns);
+ } else {
+ fmt::format_to(ctx.out(), "{{{}:{}({})}} ", k, bkstr, bkstr.length());
+ }
+ }
+
+ return fmt::format_to(ctx.out(), "}}");
+ }
+};
+
+template <>
+struct fmt::formatter<ScrubMap> {
+ template <typename ParseContext>
+ constexpr auto parse(ParseContext& ctx)
+ {
+ auto it = ctx.begin();
+ if (it != ctx.end() && *it == 'D') {
+ debug_log = true; // list the objects
+ ++it;
+ }
+ return it;
+ }
+
+ template <typename FormatContext>
+ auto format(const ScrubMap& smap, FormatContext& ctx)
+ {
+ fmt::format_to(ctx.out(),
+ "smap{{ valid:{} incr-since:{} #:{}",
+ smap.valid_through,
+ smap.incr_since,
+ smap.objects.size());
+ if (debug_log) {
+ fmt::format_to(ctx.out(), " objects:");
+ for (const auto& [ho, so] : smap.objects) {
+ fmt::format_to(ctx.out(), "\n\th.o<{}>:<{}> ", ho, so);
+ }
+ fmt::format_to(ctx.out(), "\n");
+ }
+ return fmt::format_to(ctx.out(), "}}");
+ }
+
+ bool debug_log{false};
+};
+
+#if FMT_VERSION >= 90000
+template <> struct fmt::formatter<ObjectRecoveryInfo> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<ObjectRecoveryProgress> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<PastIntervals> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<pg_log_op_return_item_t> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<watch_info_t> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<pg_log_entry_t> : fmt::ostream_formatter {};
+template <bool TrackChanges> struct fmt::formatter<pg_missing_set<TrackChanges>> : fmt::ostream_formatter {};
+#endif