]>
git.proxmox.com Git - ceph.git/blob - ceph/src/osd/osd_types_fmt.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 * \file fmtlib formatters for some types.h classes
8 #include "common/hobject_fmt.h"
9 #include "osd/osd_types.h"
10 #include <fmt/chrono.h>
11 #if FMT_VERSION >= 90000
12 #include <fmt/ostream.h>
16 struct fmt::formatter
<osd_reqid_t
> {
17 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
19 template <typename FormatContext
>
20 auto format(const osd_reqid_t
& req_id
, FormatContext
& ctx
) const
22 return fmt::format_to(ctx
.out(), "{}.{}:{}", req_id
.name
, req_id
.inc
,
28 struct fmt::formatter
<pg_shard_t
> {
29 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
31 template <typename FormatContext
>
32 auto format(const pg_shard_t
& shrd
, FormatContext
& ctx
) const
34 if (shrd
.is_undefined()) {
35 return fmt::format_to(ctx
.out(), "?");
37 if (shrd
.shard
== shard_id_t::NO_SHARD
) {
38 return fmt::format_to(ctx
.out(), "{}", shrd
.get_osd());
40 return fmt::format_to(ctx
.out(), "{}({})", shrd
.get_osd(), shrd
.shard
);
45 struct fmt::formatter
<eversion_t
> {
46 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
48 template <typename FormatContext
>
49 auto format(const eversion_t
& ev
, FormatContext
& ctx
) const
51 return fmt::format_to(ctx
.out(), "{}'{}", ev
.epoch
, ev
.version
);
56 struct fmt::formatter
<chunk_info_t
> {
57 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
59 template <typename FormatContext
>
60 auto format(const chunk_info_t
& ci
, FormatContext
& ctx
)
62 return fmt::format_to(ctx
.out(), "(len: {} oid: {} offset: {} flags: {})",
63 ci
.length
, ci
.oid
, ci
.offset
,
64 ci
.get_flag_string(ci
.flags
));
69 struct fmt::formatter
<object_manifest_t
> {
70 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
72 template <typename FormatContext
>
73 auto format(const object_manifest_t
& om
, FormatContext
& ctx
) const
75 fmt::format_to(ctx
.out(), "manifest({}", om
.get_type_name());
76 if (om
.is_redirect()) {
77 fmt::format_to(ctx
.out(), " {}", om
.redirect_target
);
78 } else if (om
.is_chunked()) {
79 fmt::format_to(ctx
.out(), " {}", om
.chunk_map
);
81 return fmt::format_to(ctx
.out(), ")");
86 struct fmt::formatter
<object_info_t
> {
87 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
89 template <typename FormatContext
>
90 auto format(const object_info_t
& oi
, FormatContext
& ctx
) const
92 fmt::format_to(ctx
.out(), "{}({} {} {} s {} uv {}", oi
.soid
, oi
.version
,
93 oi
.last_reqid
, (oi
.flags
? oi
.get_flag_string() : ""), oi
.size
,
95 if (oi
.is_data_digest()) {
96 fmt::format_to(ctx
.out(), " dd {:x}", oi
.data_digest
);
98 if (oi
.is_omap_digest()) {
99 fmt::format_to(ctx
.out(), " od {:x}", oi
.omap_digest
);
102 fmt::format_to(ctx
.out(), " alloc_hint [{} {} {}]", oi
.expected_object_size
,
103 oi
.expected_write_size
, oi
.alloc_hint_flags
);
105 if (oi
.has_manifest()) {
106 fmt::format_to(ctx
.out(), " {}", oi
.manifest
);
108 return fmt::format_to(ctx
.out(), ")");
113 struct fmt::formatter
<pg_t
> {
114 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
116 template <typename FormatContext
>
117 auto format(const pg_t
& pg
, FormatContext
& ctx
) const
119 return fmt::format_to(ctx
.out(), "{}.{:x}", pg
.pool(), pg
.m_seed
);
125 struct fmt::formatter
<spg_t
> {
126 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
128 template <typename FormatContext
>
129 auto format(const spg_t
& spg
, FormatContext
& ctx
) const
131 if (shard_id_t::NO_SHARD
== spg
.shard
.id
) {
132 return fmt::format_to(ctx
.out(), "{}", spg
.pgid
);
134 return fmt::format_to(ctx
.out(), "{}s{}>", spg
.pgid
, spg
.shard
.id
);
140 struct fmt::formatter
<pg_history_t
> {
141 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
143 template <typename FormatContext
>
144 auto format(const pg_history_t
& pgh
, FormatContext
& ctx
) const
146 fmt::format_to(ctx
.out(),
147 "ec={}/{} lis/c={}/{} les/c/f={}/{}/{} sis={}",
149 pgh
.epoch_pool_created
,
150 pgh
.last_interval_started
,
151 pgh
.last_interval_clean
,
152 pgh
.last_epoch_started
,
153 pgh
.last_epoch_clean
,
154 pgh
.last_epoch_marked_full
,
155 pgh
.same_interval_since
);
157 if (pgh
.prior_readable_until_ub
!= ceph::timespan::zero()) {
158 return fmt::format_to(ctx
.out(),
160 pgh
.prior_readable_until_ub
);
168 struct fmt::formatter
<pg_info_t
> {
169 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
171 template <typename FormatContext
>
172 auto format(const pg_info_t
& pgi
, FormatContext
& ctx
)
174 fmt::format_to(ctx
.out(), "{}({}", pgi
.pgid
, (pgi
.dne() ? " DNE" : ""));
175 if (pgi
.is_empty()) {
176 fmt::format_to(ctx
.out(), " empty");
178 fmt::format_to(ctx
.out(), " v {}", pgi
.last_update
);
179 if (pgi
.last_complete
!= pgi
.last_update
) {
180 fmt::format_to(ctx
.out(), " lc {}", pgi
.last_complete
);
182 fmt::format_to(ctx
.out(), " ({},{}]", pgi
.log_tail
, pgi
.last_update
);
184 if (pgi
.is_incomplete()) {
185 fmt::format_to(ctx
.out(), " lb {}", pgi
.last_backfill
);
187 fmt::format_to(ctx
.out(),
188 " local-lis/les={}/{}",
189 pgi
.last_interval_started
,
190 pgi
.last_epoch_started
);
191 return fmt::format_to(ctx
.out(),
193 pgi
.stats
.stats
.sum
.num_objects
,
198 // snaps and snap-sets
201 struct fmt::formatter
<SnapSet
> {
202 template <typename ParseContext
>
203 constexpr auto parse(ParseContext
& ctx
)
205 auto it
= ctx
.begin();
206 if (it
!= ctx
.end() && *it
== 'D') {
213 template <typename FormatContext
>
214 auto format(const SnapSet
& snps
, FormatContext
& ctx
)
217 // similar to SnapSet::dump()
218 fmt::format_to(ctx
.out(),
219 "snaps{{{}: clns ({}): ",
222 for (auto cln
: snps
.clones
) {
224 fmt::format_to(ctx
.out(), "[{}: sz:", cln
);
226 auto cs
= snps
.clone_size
.find(cln
);
227 if (cs
!= snps
.clone_size
.end()) {
228 fmt::format_to(ctx
.out(), "{} ", cs
->second
);
230 fmt::format_to(ctx
.out(), "??");
233 auto co
= snps
.clone_overlap
.find(cln
);
234 if (co
!= snps
.clone_overlap
.end()) {
235 fmt::format_to(ctx
.out(), "olp:{} ", co
->second
);
237 fmt::format_to(ctx
.out(), "olp:?? ");
240 auto cln_snps
= snps
.clone_snaps
.find(cln
);
241 if (cln_snps
!= snps
.clone_snaps
.end()) {
242 fmt::format_to(ctx
.out(), "cl-snps:{} ]", cln_snps
->second
);
244 fmt::format_to(ctx
.out(), "cl-snps:?? ]");
248 return fmt::format_to(ctx
.out(), "}}");
251 return fmt::format_to(ctx
.out(),
263 struct fmt::formatter
<ScrubMap::object
> {
264 constexpr auto parse(format_parse_context
& ctx
) { return ctx
.begin(); }
266 ///\todo: consider passing the 'D" flag to control snapset dump
267 template <typename FormatContext
>
268 auto format(const ScrubMap::object
& so
, FormatContext
& ctx
)
270 fmt::format_to(ctx
.out(),
271 "so{{ sz:{} dd:{} od:{} ",
276 // note the special handling of (1) OI_ATTR and (2) non-printables
277 for (auto [k
, v
] : so
.attrs
) {
278 std::string bkstr
{v
.raw_c_str(), v
.raw_length()};
279 if (k
== std::string
{OI_ATTR
}) {
280 /// \todo consider parsing the OI args here. Maybe add a specific format
282 fmt::format_to(ctx
.out(), "{{{}:<<OI_ATTR>>({})}} ", k
, bkstr
.length());
283 } else if (k
== std::string
{SS_ATTR
}) {
287 fmt::format_to(ctx
.out(), "{{{}:{:D}}} ", k
, sns
);
289 fmt::format_to(ctx
.out(), "{{{}:{}({})}} ", k
, bkstr
, bkstr
.length());
293 return fmt::format_to(ctx
.out(), "}}");
298 struct fmt::formatter
<ScrubMap
> {
299 template <typename ParseContext
>
300 constexpr auto parse(ParseContext
& ctx
)
302 auto it
= ctx
.begin();
303 if (it
!= ctx
.end() && *it
== 'D') {
304 debug_log
= true; // list the objects
310 template <typename FormatContext
>
311 auto format(const ScrubMap
& smap
, FormatContext
& ctx
)
313 fmt::format_to(ctx
.out(),
314 "smap{{ valid:{} incr-since:{} #:{}",
317 smap
.objects
.size());
319 fmt::format_to(ctx
.out(), " objects:");
320 for (const auto& [ho
, so
] : smap
.objects
) {
321 fmt::format_to(ctx
.out(), "\n\th.o<{}>:<{}> ", ho
, so
);
323 fmt::format_to(ctx
.out(), "\n");
325 return fmt::format_to(ctx
.out(), "}}");
328 bool debug_log
{false};
331 #if FMT_VERSION >= 90000
332 template <> struct fmt::formatter
<ObjectRecoveryInfo
> : fmt::ostream_formatter
{};
333 template <> struct fmt::formatter
<ObjectRecoveryProgress
> : fmt::ostream_formatter
{};
334 template <> struct fmt::formatter
<PastIntervals
> : fmt::ostream_formatter
{};
335 template <> struct fmt::formatter
<pg_log_op_return_item_t
> : fmt::ostream_formatter
{};
336 template <> struct fmt::formatter
<watch_info_t
> : fmt::ostream_formatter
{};
337 template <> struct fmt::formatter
<pg_log_entry_t
> : fmt::ostream_formatter
{};
338 template <bool TrackChanges
> struct fmt::formatter
<pg_missing_set
<TrackChanges
>> : fmt::ostream_formatter
{};