]>
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" | |
10 | ||
7c673cae FG |
11 | |
12 | ||
13 | static void dump_usage_categories_info(Formatter *formatter, const rgw_usage_log_entry& entry, map<string, bool> *categories) | |
14 | { | |
15 | formatter->open_array_section("categories"); | |
16 | map<string, rgw_usage_data>::const_iterator uiter; | |
17 | for (uiter = entry.usage_map.begin(); uiter != entry.usage_map.end(); ++uiter) { | |
18 | if (categories && !categories->empty() && !categories->count(uiter->first)) | |
19 | continue; | |
20 | const rgw_usage_data& usage = uiter->second; | |
21 | formatter->open_object_section("entry"); | |
22 | formatter->dump_string("category", uiter->first); | |
9f95a23c TL |
23 | formatter->dump_unsigned("bytes_sent", usage.bytes_sent); |
24 | formatter->dump_unsigned("bytes_received", usage.bytes_received); | |
25 | formatter->dump_unsigned("ops", usage.ops); | |
26 | formatter->dump_unsigned("successful_ops", usage.successful_ops); | |
7c673cae FG |
27 | formatter->close_section(); // entry |
28 | } | |
29 | formatter->close_section(); // categories | |
30 | } | |
31 | ||
b3b6e05e | 32 | int RGWUsage::show(const DoutPrefixProvider *dpp, RGWRados *store, const rgw_user& uid, const string& bucket_name, uint64_t start_epoch, |
11fdf7f2 | 33 | uint64_t end_epoch, bool show_log_entries, bool show_log_sum, map<string, bool> *categories, |
7c673cae FG |
34 | RGWFormatterFlusher& flusher) |
35 | { | |
36 | uint32_t max_entries = 1000; | |
37 | ||
38 | bool is_truncated = true; | |
39 | ||
40 | RGWUsageIter usage_iter; | |
41 | Formatter *formatter = flusher.get_formatter(); | |
42 | ||
43 | map<rgw_user_bucket, rgw_usage_log_entry> usage; | |
44 | ||
45 | flusher.start(0); | |
46 | ||
47 | formatter->open_object_section("usage"); | |
48 | if (show_log_entries) { | |
49 | formatter->open_array_section("entries"); | |
50 | } | |
51 | string last_owner; | |
52 | bool user_section_open = false; | |
53 | map<string, rgw_usage_log_entry> summary_map; | |
54 | while (is_truncated) { | |
b3b6e05e | 55 | int ret = store->read_usage(dpp, uid, bucket_name, start_epoch, end_epoch, max_entries, |
7c673cae FG |
56 | &is_truncated, usage_iter, usage); |
57 | ||
58 | if (ret == -ENOENT) { | |
59 | ret = 0; | |
60 | is_truncated = false; | |
61 | } | |
62 | ||
63 | if (ret < 0) { | |
64 | return ret; | |
65 | } | |
66 | ||
67 | map<rgw_user_bucket, rgw_usage_log_entry>::iterator iter; | |
68 | for (iter = usage.begin(); iter != usage.end(); ++iter) { | |
69 | const rgw_user_bucket& ub = iter->first; | |
70 | const rgw_usage_log_entry& entry = iter->second; | |
71 | ||
72 | if (show_log_entries) { | |
73 | if (ub.user.compare(last_owner) != 0) { | |
74 | if (user_section_open) { | |
75 | formatter->close_section(); | |
76 | formatter->close_section(); | |
77 | } | |
78 | formatter->open_object_section("user"); | |
79 | formatter->dump_string("user", ub.user); | |
80 | formatter->open_array_section("buckets"); | |
81 | user_section_open = true; | |
82 | last_owner = ub.user; | |
83 | } | |
84 | formatter->open_object_section("bucket"); | |
85 | formatter->dump_string("bucket", ub.bucket); | |
86 | utime_t ut(entry.epoch, 0); | |
87 | ut.gmtime(formatter->dump_stream("time")); | |
88 | formatter->dump_int("epoch", entry.epoch); | |
89 | string owner = entry.owner.to_str(); | |
90 | string payer = entry.payer.to_str(); | |
91 | formatter->dump_string("owner", owner); | |
92 | if (!payer.empty() && payer != owner) { | |
93 | formatter->dump_string("payer", payer); | |
94 | } | |
95 | dump_usage_categories_info(formatter, entry, categories); | |
96 | formatter->close_section(); // bucket | |
97 | flusher.flush(); | |
98 | } | |
99 | ||
100 | summary_map[ub.user].aggregate(entry, categories); | |
101 | } | |
102 | } | |
103 | if (show_log_entries) { | |
104 | if (user_section_open) { | |
105 | formatter->close_section(); // buckets | |
106 | formatter->close_section(); //user | |
107 | } | |
108 | formatter->close_section(); // entries | |
109 | } | |
110 | ||
111 | if (show_log_sum) { | |
112 | formatter->open_array_section("summary"); | |
113 | map<string, rgw_usage_log_entry>::iterator siter; | |
114 | for (siter = summary_map.begin(); siter != summary_map.end(); ++siter) { | |
115 | const rgw_usage_log_entry& entry = siter->second; | |
116 | formatter->open_object_section("user"); | |
117 | formatter->dump_string("user", siter->first); | |
118 | dump_usage_categories_info(formatter, entry, categories); | |
119 | rgw_usage_data total_usage; | |
120 | entry.sum(total_usage, *categories); | |
121 | formatter->open_object_section("total"); | |
9f95a23c TL |
122 | encode_json("bytes_sent", total_usage.bytes_sent, formatter); |
123 | encode_json("bytes_received", total_usage.bytes_received, formatter); | |
124 | encode_json("ops", total_usage.ops, formatter); | |
125 | encode_json("successful_ops", total_usage.successful_ops, formatter); | |
7c673cae FG |
126 | formatter->close_section(); // total |
127 | ||
128 | formatter->close_section(); // user | |
129 | ||
130 | flusher.flush(); | |
131 | } | |
132 | ||
133 | formatter->close_section(); // summary | |
134 | } | |
135 | ||
136 | formatter->close_section(); // usage | |
137 | flusher.flush(); | |
138 | ||
139 | return 0; | |
140 | } | |
141 | ||
b3b6e05e | 142 | int RGWUsage::trim(const DoutPrefixProvider *dpp, RGWRados *store, const rgw_user& uid, const string& bucket_name, uint64_t start_epoch, |
11fdf7f2 | 143 | uint64_t end_epoch) |
7c673cae | 144 | { |
b3b6e05e | 145 | return store->trim_usage(dpp, uid, bucket_name, start_epoch, end_epoch); |
11fdf7f2 TL |
146 | } |
147 | ||
b3b6e05e | 148 | int RGWUsage::clear(const DoutPrefixProvider *dpp, RGWRados *store) |
11fdf7f2 | 149 | { |
b3b6e05e | 150 | return store->clear_usage(dpp); |
7c673cae | 151 | } |