]> git.proxmox.com Git - ceph.git/blame - ceph/src/osd/osd_types_fmt.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / osd / osd_types_fmt.h
CommitLineData
20effc67
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3#pragma once
4/**
5 * \file fmtlib formatters for some types.h classes
6 */
7
8#include "common/hobject_fmt.h"
9#include "osd/osd_types.h"
1e59de90
TL
10#include <fmt/chrono.h>
11#if FMT_VERSION >= 90000
12#include <fmt/ostream.h>
13#endif
20effc67
TL
14
15template <>
16struct fmt::formatter<osd_reqid_t> {
17 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
18
19 template <typename FormatContext>
1e59de90 20 auto format(const osd_reqid_t& req_id, FormatContext& ctx) const
20effc67
TL
21 {
22 return fmt::format_to(ctx.out(), "{}.{}:{}", req_id.name, req_id.inc,
23 req_id.tid);
24 }
25};
26
27template <>
28struct fmt::formatter<pg_shard_t> {
29 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
30
31 template <typename FormatContext>
1e59de90 32 auto format(const pg_shard_t& shrd, FormatContext& ctx) const
20effc67
TL
33 {
34 if (shrd.is_undefined()) {
35 return fmt::format_to(ctx.out(), "?");
36 }
37 if (shrd.shard == shard_id_t::NO_SHARD) {
38 return fmt::format_to(ctx.out(), "{}", shrd.get_osd());
39 }
40 return fmt::format_to(ctx.out(), "{}({})", shrd.get_osd(), shrd.shard);
41 }
42};
43
44template <>
45struct fmt::formatter<eversion_t> {
46 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
47
48 template <typename FormatContext>
1e59de90 49 auto format(const eversion_t& ev, FormatContext& ctx) const
20effc67
TL
50 {
51 return fmt::format_to(ctx.out(), "{}'{}", ev.epoch, ev.version);
52 }
53};
54
55template <>
56struct fmt::formatter<chunk_info_t> {
57 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
58
59 template <typename FormatContext>
60 auto format(const chunk_info_t& ci, FormatContext& ctx)
61 {
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));
65 }
66};
67
68template <>
69struct fmt::formatter<object_manifest_t> {
70 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
71
72 template <typename FormatContext>
1e59de90 73 auto format(const object_manifest_t& om, FormatContext& ctx) const
20effc67
TL
74 {
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);
80 }
81 return fmt::format_to(ctx.out(), ")");
82 }
83};
84
85template <>
86struct fmt::formatter<object_info_t> {
87 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
88
89 template <typename FormatContext>
1e59de90 90 auto format(const object_info_t& oi, FormatContext& ctx) const
20effc67
TL
91 {
92 fmt::format_to(ctx.out(), "{}({} {} {} s {} uv {}", oi.soid, oi.version,
93 oi.last_reqid, (oi.flags ? oi.get_flag_string() : ""), oi.size,
94 oi.user_version);
95 if (oi.is_data_digest()) {
96 fmt::format_to(ctx.out(), " dd {:x}", oi.data_digest);
97 }
98 if (oi.is_omap_digest()) {
99 fmt::format_to(ctx.out(), " od {:x}", oi.omap_digest);
100 }
101
102 fmt::format_to(ctx.out(), " alloc_hint [{} {} {}]", oi.expected_object_size,
103 oi.expected_write_size, oi.alloc_hint_flags);
104
105 if (oi.has_manifest()) {
106 fmt::format_to(ctx.out(), " {}", oi.manifest);
107 }
108 return fmt::format_to(ctx.out(), ")");
109 }
110};
2a845540
TL
111
112template <>
113struct fmt::formatter<pg_t> {
114 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
115
116 template <typename FormatContext>
1e59de90 117 auto format(const pg_t& pg, FormatContext& ctx) const
2a845540
TL
118 {
119 return fmt::format_to(ctx.out(), "{}.{:x}", pg.pool(), pg.m_seed);
120 }
121};
1e59de90
TL
122
123
124template <>
125struct fmt::formatter<spg_t> {
126 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
127
128 template <typename FormatContext>
129 auto format(const spg_t& spg, FormatContext& ctx) const
130 {
131 if (shard_id_t::NO_SHARD == spg.shard.id) {
132 return fmt::format_to(ctx.out(), "{}", spg.pgid);
133 } else {
134 return fmt::format_to(ctx.out(), "{}s{}>", spg.pgid, spg.shard.id);
135 }
136 }
137};
138
139template <>
140struct fmt::formatter<pg_history_t> {
141 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
142
143 template <typename FormatContext>
144 auto format(const pg_history_t& pgh, FormatContext& ctx) const
145 {
146 fmt::format_to(ctx.out(),
147 "ec={}/{} lis/c={}/{} les/c/f={}/{}/{} sis={}",
148 pgh.epoch_created,
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);
156
157 if (pgh.prior_readable_until_ub != ceph::timespan::zero()) {
158 return fmt::format_to(ctx.out(),
159 " pruub={}",
160 pgh.prior_readable_until_ub);
161 } else {
162 return ctx.out();
163 }
164 }
165};
166
167template <>
168struct fmt::formatter<pg_info_t> {
169 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
170
171 template <typename FormatContext>
172 auto format(const pg_info_t& pgi, FormatContext& ctx)
173 {
174 fmt::format_to(ctx.out(), "{}({}", pgi.pgid, (pgi.dne() ? " DNE" : ""));
175 if (pgi.is_empty()) {
176 fmt::format_to(ctx.out(), " empty");
177 } else {
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);
181 }
182 fmt::format_to(ctx.out(), " ({},{}]", pgi.log_tail, pgi.last_update);
183 }
184 if (pgi.is_incomplete()) {
185 fmt::format_to(ctx.out(), " lb {}", pgi.last_backfill);
186 }
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(),
192 " n={} {})",
193 pgi.stats.stats.sum.num_objects,
194 pgi.history);
195 }
196};
197
198// snaps and snap-sets
199
200template <>
201struct fmt::formatter<SnapSet> {
202 template <typename ParseContext>
203 constexpr auto parse(ParseContext& ctx)
204 {
205 auto it = ctx.begin();
206 if (it != ctx.end() && *it == 'D') {
207 verbose = true;
208 ++it;
209 }
210 return it;
211 }
212
213 template <typename FormatContext>
214 auto format(const SnapSet& snps, FormatContext& ctx)
215 {
216 if (verbose) {
217 // similar to SnapSet::dump()
218 fmt::format_to(ctx.out(),
219 "snaps{{{}: clns ({}): ",
220 snps.seq,
221 snps.clones.size());
222 for (auto cln : snps.clones) {
223
224 fmt::format_to(ctx.out(), "[{}: sz:", cln);
225
226 auto cs = snps.clone_size.find(cln);
227 if (cs != snps.clone_size.end()) {
228 fmt::format_to(ctx.out(), "{} ", cs->second);
229 } else {
230 fmt::format_to(ctx.out(), "??");
231 }
232
233 auto co = snps.clone_overlap.find(cln);
234 if (co != snps.clone_overlap.end()) {
235 fmt::format_to(ctx.out(), "olp:{} ", co->second);
236 } else {
237 fmt::format_to(ctx.out(), "olp:?? ");
238 }
239
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);
243 } else {
244 fmt::format_to(ctx.out(), "cl-snps:?? ]");
245 }
246 }
247
248 return fmt::format_to(ctx.out(), "}}");
249
250 } else {
251 return fmt::format_to(ctx.out(),
252 "{}={}:{}",
253 snps.seq,
254 snps.snaps,
255 snps.clone_snaps);
256 }
257 }
258
259 bool verbose{false};
260};
261
262template <>
263struct fmt::formatter<ScrubMap::object> {
264 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
265
266 ///\todo: consider passing the 'D" flag to control snapset dump
267 template <typename FormatContext>
268 auto format(const ScrubMap::object& so, FormatContext& ctx)
269 {
270 fmt::format_to(ctx.out(),
271 "so{{ sz:{} dd:{} od:{} ",
272 so.size,
273 so.digest,
274 so.digest_present);
275
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
281 /// specifier
282 fmt::format_to(ctx.out(), "{{{}:<<OI_ATTR>>({})}} ", k, bkstr.length());
283 } else if (k == std::string{SS_ATTR}) {
284 bufferlist bl;
285 bl.push_back(v);
286 SnapSet sns{bl};
287 fmt::format_to(ctx.out(), "{{{}:{:D}}} ", k, sns);
288 } else {
289 fmt::format_to(ctx.out(), "{{{}:{}({})}} ", k, bkstr, bkstr.length());
290 }
291 }
292
293 return fmt::format_to(ctx.out(), "}}");
294 }
295};
296
297template <>
298struct fmt::formatter<ScrubMap> {
299 template <typename ParseContext>
300 constexpr auto parse(ParseContext& ctx)
301 {
302 auto it = ctx.begin();
303 if (it != ctx.end() && *it == 'D') {
304 debug_log = true; // list the objects
305 ++it;
306 }
307 return it;
308 }
309
310 template <typename FormatContext>
311 auto format(const ScrubMap& smap, FormatContext& ctx)
312 {
313 fmt::format_to(ctx.out(),
314 "smap{{ valid:{} incr-since:{} #:{}",
315 smap.valid_through,
316 smap.incr_since,
317 smap.objects.size());
318 if (debug_log) {
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);
322 }
323 fmt::format_to(ctx.out(), "\n");
324 }
325 return fmt::format_to(ctx.out(), "}}");
326 }
327
328 bool debug_log{false};
329};
330
331#if FMT_VERSION >= 90000
332template <> struct fmt::formatter<ObjectRecoveryInfo> : fmt::ostream_formatter {};
333template <> struct fmt::formatter<ObjectRecoveryProgress> : fmt::ostream_formatter {};
334template <> struct fmt::formatter<PastIntervals> : fmt::ostream_formatter {};
335template <> struct fmt::formatter<pg_log_op_return_item_t> : fmt::ostream_formatter {};
336template <> struct fmt::formatter<watch_info_t> : fmt::ostream_formatter {};
337template <> struct fmt::formatter<pg_log_entry_t> : fmt::ostream_formatter {};
338template <bool TrackChanges> struct fmt::formatter<pg_missing_set<TrackChanges>> : fmt::ostream_formatter {};
339#endif