]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
7c673cae FG |
3 | |
4 | #include <string> | |
5 | #include <map> | |
6 | ||
7 | #include "rgw_rados.h" | |
8 | #include "rgw_usage.h" | |
9 | #include "rgw_formats.h" | |
20effc67 | 10 | #include "rgw_sal.h" |
7c673cae | 11 | |
20effc67 | 12 | using namespace std; |
7c673cae FG |
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); | |
9f95a23c TL |
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); | |
7c673cae FG |
28 | formatter->close_section(); // entry |
29 | } | |
30 | formatter->close_section(); // categories | |
31 | } | |
32 | ||
1e59de90 | 33 | int RGWUsage::show(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, |
20effc67 TL |
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) | |
7c673cae FG |
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; | |
20effc67 TL |
57 | int ret; |
58 | ||
7c673cae | 59 | while (is_truncated) { |
20effc67 TL |
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 { | |
1e59de90 | 67 | ret = driver->read_all_usage(dpp, start_epoch, end_epoch, max_entries, &is_truncated, |
20effc67 TL |
68 | usage_iter, usage); |
69 | } | |
7c673cae FG |
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"); | |
9f95a23c TL |
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); | |
7c673cae FG |
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 | ||
1e59de90 | 155 | int RGWUsage::trim(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, |
20effc67 | 156 | rgw::sal::User* user , rgw::sal::Bucket* bucket, |
f51cf556 | 157 | uint64_t start_epoch, uint64_t end_epoch, optional_yield y) |
7c673cae | 158 | { |
20effc67 | 159 | if (bucket) { |
f51cf556 | 160 | return bucket->trim_usage(dpp, start_epoch, end_epoch, y); |
20effc67 | 161 | } else if (user) { |
f51cf556 | 162 | return user->trim_usage(dpp, start_epoch, end_epoch, y); |
20effc67 | 163 | } else { |
f51cf556 | 164 | return driver->trim_all_usage(dpp, start_epoch, end_epoch, y); |
20effc67 | 165 | } |
11fdf7f2 TL |
166 | } |
167 | ||
f51cf556 | 168 | int RGWUsage::clear(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, optional_yield y) |
11fdf7f2 | 169 | { |
f51cf556 | 170 | return driver->clear_usage(dpp, y); |
7c673cae | 171 | } |