]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_usage.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rgw / rgw_usage.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #include <string>
5 #include <map>
6
7 #include "rgw_rados.h"
8 #include "rgw_usage.h"
9 #include "rgw_formats.h"
10 #include "rgw_sal.h"
11
12 using namespace std;
13
14 static void dump_usage_categories_info(Formatter *formatter, const rgw_usage_log_entry& entry, map<string, bool> *categories)
15 {
16 formatter->open_array_section("categories");
17 map<string, rgw_usage_data>::const_iterator uiter;
18 for (uiter = entry.usage_map.begin(); uiter != entry.usage_map.end(); ++uiter) {
19 if (categories && !categories->empty() && !categories->count(uiter->first))
20 continue;
21 const rgw_usage_data& usage = uiter->second;
22 formatter->open_object_section("entry");
23 formatter->dump_string("category", uiter->first);
24 formatter->dump_unsigned("bytes_sent", usage.bytes_sent);
25 formatter->dump_unsigned("bytes_received", usage.bytes_received);
26 formatter->dump_unsigned("ops", usage.ops);
27 formatter->dump_unsigned("successful_ops", usage.successful_ops);
28 formatter->close_section(); // entry
29 }
30 formatter->close_section(); // categories
31 }
32
33 int RGWUsage::show(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver,
34 rgw::sal::User* user , rgw::sal::Bucket* bucket,
35 uint64_t start_epoch, uint64_t end_epoch, bool show_log_entries,
36 bool show_log_sum,
37 map<string, bool> *categories, RGWFormatterFlusher& flusher)
38 {
39 uint32_t max_entries = 1000;
40
41 bool is_truncated = true;
42
43 RGWUsageIter usage_iter;
44 Formatter *formatter = flusher.get_formatter();
45
46 map<rgw_user_bucket, rgw_usage_log_entry> usage;
47
48 flusher.start(0);
49
50 formatter->open_object_section("usage");
51 if (show_log_entries) {
52 formatter->open_array_section("entries");
53 }
54 string last_owner;
55 bool user_section_open = false;
56 map<string, rgw_usage_log_entry> summary_map;
57 int ret;
58
59 while (is_truncated) {
60 if (bucket) {
61 ret = bucket->read_usage(dpp, start_epoch, end_epoch, max_entries, &is_truncated,
62 usage_iter, usage);
63 } else if (user) {
64 ret = user->read_usage(dpp, start_epoch, end_epoch, max_entries, &is_truncated,
65 usage_iter, usage);
66 } else {
67 ret = driver->read_all_usage(dpp, start_epoch, end_epoch, max_entries, &is_truncated,
68 usage_iter, usage);
69 }
70
71 if (ret == -ENOENT) {
72 ret = 0;
73 is_truncated = false;
74 }
75
76 if (ret < 0) {
77 return ret;
78 }
79
80 map<rgw_user_bucket, rgw_usage_log_entry>::iterator iter;
81 for (iter = usage.begin(); iter != usage.end(); ++iter) {
82 const rgw_user_bucket& ub = iter->first;
83 const rgw_usage_log_entry& entry = iter->second;
84
85 if (show_log_entries) {
86 if (ub.user.compare(last_owner) != 0) {
87 if (user_section_open) {
88 formatter->close_section();
89 formatter->close_section();
90 }
91 formatter->open_object_section("user");
92 formatter->dump_string("user", ub.user);
93 formatter->open_array_section("buckets");
94 user_section_open = true;
95 last_owner = ub.user;
96 }
97 formatter->open_object_section("bucket");
98 formatter->dump_string("bucket", ub.bucket);
99 utime_t ut(entry.epoch, 0);
100 ut.gmtime(formatter->dump_stream("time"));
101 formatter->dump_int("epoch", entry.epoch);
102 string owner = entry.owner.to_str();
103 string payer = entry.payer.to_str();
104 formatter->dump_string("owner", owner);
105 if (!payer.empty() && payer != owner) {
106 formatter->dump_string("payer", payer);
107 }
108 dump_usage_categories_info(formatter, entry, categories);
109 formatter->close_section(); // bucket
110 flusher.flush();
111 }
112
113 summary_map[ub.user].aggregate(entry, categories);
114 }
115 }
116 if (show_log_entries) {
117 if (user_section_open) {
118 formatter->close_section(); // buckets
119 formatter->close_section(); //user
120 }
121 formatter->close_section(); // entries
122 }
123
124 if (show_log_sum) {
125 formatter->open_array_section("summary");
126 map<string, rgw_usage_log_entry>::iterator siter;
127 for (siter = summary_map.begin(); siter != summary_map.end(); ++siter) {
128 const rgw_usage_log_entry& entry = siter->second;
129 formatter->open_object_section("user");
130 formatter->dump_string("user", siter->first);
131 dump_usage_categories_info(formatter, entry, categories);
132 rgw_usage_data total_usage;
133 entry.sum(total_usage, *categories);
134 formatter->open_object_section("total");
135 encode_json("bytes_sent", total_usage.bytes_sent, formatter);
136 encode_json("bytes_received", total_usage.bytes_received, formatter);
137 encode_json("ops", total_usage.ops, formatter);
138 encode_json("successful_ops", total_usage.successful_ops, formatter);
139 formatter->close_section(); // total
140
141 formatter->close_section(); // user
142
143 flusher.flush();
144 }
145
146 formatter->close_section(); // summary
147 }
148
149 formatter->close_section(); // usage
150 flusher.flush();
151
152 return 0;
153 }
154
155 int RGWUsage::trim(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver,
156 rgw::sal::User* user , rgw::sal::Bucket* bucket,
157 uint64_t start_epoch, uint64_t end_epoch)
158 {
159 if (bucket) {
160 return bucket->trim_usage(dpp, start_epoch, end_epoch);
161 } else if (user) {
162 return user->trim_usage(dpp, start_epoch, end_epoch);
163 } else {
164 return driver->trim_all_usage(dpp, start_epoch, end_epoch);
165 }
166 }
167
168 int RGWUsage::clear(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver)
169 {
170 return driver->clear_usage(dpp);
171 }