]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include <string> | |
5 | #include <map> | |
6 | ||
7 | #include "rgw_rados.h" | |
8 | #include "rgw_usage.h" | |
9 | #include "rgw_formats.h" | |
10 | ||
11 | using namespace std; | |
12 | ||
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_int("bytes_sent", usage.bytes_sent); | |
25 | formatter->dump_int("bytes_received", usage.bytes_received); | |
26 | formatter->dump_int("ops", usage.ops); | |
27 | formatter->dump_int("successful_ops", usage.successful_ops); | |
28 | formatter->close_section(); // entry | |
29 | } | |
30 | formatter->close_section(); // categories | |
31 | } | |
32 | ||
33 | int RGWUsage::show(RGWRados *store, rgw_user& uid, uint64_t start_epoch, | |
34 | uint64_t end_epoch, bool show_log_entries, bool show_log_sum, | |
35 | map<string, bool> *categories, | |
36 | RGWFormatterFlusher& flusher) | |
37 | { | |
38 | uint32_t max_entries = 1000; | |
39 | ||
40 | bool is_truncated = true; | |
41 | ||
42 | RGWUsageIter usage_iter; | |
43 | Formatter *formatter = flusher.get_formatter(); | |
44 | ||
45 | map<rgw_user_bucket, rgw_usage_log_entry> usage; | |
46 | ||
47 | flusher.start(0); | |
48 | ||
49 | formatter->open_object_section("usage"); | |
50 | if (show_log_entries) { | |
51 | formatter->open_array_section("entries"); | |
52 | } | |
53 | string last_owner; | |
54 | bool user_section_open = false; | |
55 | map<string, rgw_usage_log_entry> summary_map; | |
56 | while (is_truncated) { | |
57 | int ret = store->read_usage(uid, start_epoch, end_epoch, max_entries, | |
58 | &is_truncated, usage_iter, usage); | |
59 | ||
60 | if (ret == -ENOENT) { | |
61 | ret = 0; | |
62 | is_truncated = false; | |
63 | } | |
64 | ||
65 | if (ret < 0) { | |
66 | return ret; | |
67 | } | |
68 | ||
69 | map<rgw_user_bucket, rgw_usage_log_entry>::iterator iter; | |
70 | for (iter = usage.begin(); iter != usage.end(); ++iter) { | |
71 | const rgw_user_bucket& ub = iter->first; | |
72 | const rgw_usage_log_entry& entry = iter->second; | |
73 | ||
74 | if (show_log_entries) { | |
75 | if (ub.user.compare(last_owner) != 0) { | |
76 | if (user_section_open) { | |
77 | formatter->close_section(); | |
78 | formatter->close_section(); | |
79 | } | |
80 | formatter->open_object_section("user"); | |
81 | formatter->dump_string("user", ub.user); | |
82 | formatter->open_array_section("buckets"); | |
83 | user_section_open = true; | |
84 | last_owner = ub.user; | |
85 | } | |
86 | formatter->open_object_section("bucket"); | |
87 | formatter->dump_string("bucket", ub.bucket); | |
88 | utime_t ut(entry.epoch, 0); | |
89 | ut.gmtime(formatter->dump_stream("time")); | |
90 | formatter->dump_int("epoch", entry.epoch); | |
91 | string owner = entry.owner.to_str(); | |
92 | string payer = entry.payer.to_str(); | |
93 | formatter->dump_string("owner", owner); | |
94 | if (!payer.empty() && payer != owner) { | |
95 | formatter->dump_string("payer", payer); | |
96 | } | |
97 | dump_usage_categories_info(formatter, entry, categories); | |
98 | formatter->close_section(); // bucket | |
99 | flusher.flush(); | |
100 | } | |
101 | ||
102 | summary_map[ub.user].aggregate(entry, categories); | |
103 | } | |
104 | } | |
105 | if (show_log_entries) { | |
106 | if (user_section_open) { | |
107 | formatter->close_section(); // buckets | |
108 | formatter->close_section(); //user | |
109 | } | |
110 | formatter->close_section(); // entries | |
111 | } | |
112 | ||
113 | if (show_log_sum) { | |
114 | formatter->open_array_section("summary"); | |
115 | map<string, rgw_usage_log_entry>::iterator siter; | |
116 | for (siter = summary_map.begin(); siter != summary_map.end(); ++siter) { | |
117 | const rgw_usage_log_entry& entry = siter->second; | |
118 | formatter->open_object_section("user"); | |
119 | formatter->dump_string("user", siter->first); | |
120 | dump_usage_categories_info(formatter, entry, categories); | |
121 | rgw_usage_data total_usage; | |
122 | entry.sum(total_usage, *categories); | |
123 | formatter->open_object_section("total"); | |
124 | formatter->dump_int("bytes_sent", total_usage.bytes_sent); | |
125 | formatter->dump_int("bytes_received", total_usage.bytes_received); | |
126 | formatter->dump_int("ops", total_usage.ops); | |
127 | formatter->dump_int("successful_ops", total_usage.successful_ops); | |
128 | formatter->close_section(); // total | |
129 | ||
130 | formatter->close_section(); // user | |
131 | ||
132 | flusher.flush(); | |
133 | } | |
134 | ||
135 | formatter->close_section(); // summary | |
136 | } | |
137 | ||
138 | formatter->close_section(); // usage | |
139 | flusher.flush(); | |
140 | ||
141 | return 0; | |
142 | } | |
143 | ||
144 | int RGWUsage::trim(RGWRados *store, rgw_user& uid, uint64_t start_epoch, | |
145 | uint64_t end_epoch) | |
146 | { | |
147 | return store->trim_usage(uid, start_epoch, end_epoch); | |
148 | } |