diff --git a/src/Makefile.am b/src/Makefile.am index 2cd7b45fd47..0329a0fcf9d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -313,6 +313,7 @@ librgw_a_SOURCES = \ rgw/rgw_client_io.cc \ rgw/rgw_fcgi.cc \ rgw/rgw_xml.cc \ + rgw/rgw_usage.cc \ rgw/rgw_user.cc \ rgw/rgw_tools.cc \ rgw/rgw_rados.cc \ @@ -1716,6 +1717,7 @@ noinst_HEADERS = \ rgw/rgw_rest_swift.h\ rgw/rgw_rest_s3.h\ rgw/rgw_tools.h\ + rgw/rgw_usage.h\ rgw/rgw_user.h\ sample.ceph.conf\ tools/common.h\ diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index fcbeed78f46..339f044bcea 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -21,6 +21,7 @@ using namespace std; #include "rgw_acl_s3.h" #include "rgw_log.h" #include "rgw_formats.h" +#include "rgw_usage.h" #include "auth/Crypto.h" #define dout_subsys ceph_subsys_rgw @@ -648,25 +649,6 @@ static int remove_bucket(rgw_bucket& bucket, bool delete_children) return ret; } -void dump_usage_categories_info(Formatter *formatter, const rgw_usage_log_entry& entry, map& categories) -{ - formatter->open_array_section("categories"); - map::const_iterator uiter; - for (uiter = entry.usage_map.begin(); uiter != entry.usage_map.end(); ++uiter) { - if (categories.size() && !categories.count(uiter->first)) - continue; - const rgw_usage_data& usage = uiter->second; - formatter->open_object_section("entry"); - formatter->dump_string("category", uiter->first); - formatter->dump_int("bytes_sent", usage.bytes_sent); - formatter->dump_int("bytes_received", usage.bytes_received); - formatter->dump_int("ops", usage.ops); - formatter->dump_int("successful_ops", usage.successful_ops); - formatter->close_section(); // entry - } - formatter->close_section(); // categories -} - int main(int argc, char **argv) { vector args; @@ -1553,100 +1535,13 @@ next: parse_date(start_date, &start_epoch); parse_date(end_date, &end_epoch); - uint32_t max_entries = 1000; - - bool is_truncated = true; - - RGWUsageIter usage_iter; - - map usage; - - formatter->open_object_section("usage"); - if (show_log_entries) { - formatter->open_array_section("entries"); + int ret = RGWUsage::show(rgwstore, user_id, start_epoch, end_epoch, + show_log_entries, show_log_sum, &categories, + formatter); + if (ret < 0) { + cerr << "ERROR: failed to show usage" << std::endl; + return 1; } - string last_owner; - bool user_section_open = false; - map summary_map; - while (is_truncated) { - int ret = rgwstore->read_usage(user_id, start_epoch, end_epoch, max_entries, - &is_truncated, usage_iter, usage); - - if (ret == -ENOENT) { - ret = 0; - is_truncated = false; - } - - if (ret < 0) { - cerr << "ERROR: read_usage() returned ret=" << ret << std::endl; - break; - } - - map::iterator iter; - for (iter = usage.begin(); iter != usage.end(); ++iter) { - const rgw_user_bucket& ub = iter->first; - const rgw_usage_log_entry& entry = iter->second; - - if (show_log_entries) { - if (ub.user.compare(last_owner) != 0) { - if (user_section_open) { - formatter->close_section(); - formatter->close_section(); - } - formatter->open_object_section("user"); - formatter->dump_string("owner", ub.user); - formatter->open_array_section("buckets"); - user_section_open = true; - last_owner = ub.user; - } - formatter->open_object_section("bucket"); - formatter->dump_string("bucket", ub.bucket); - utime_t ut(entry.epoch, 0); - ut.gmtime(formatter->dump_stream("time")); - formatter->dump_int("epoch", entry.epoch); - dump_usage_categories_info(formatter, entry, categories); - formatter->close_section(); // bucket - formatter->flush(cout); - } - - summary_map[ub.user].aggregate(entry, &categories); - } - } - if (show_log_entries) { - if (user_section_open) { - formatter->close_section(); // buckets - formatter->close_section(); //user - } - formatter->close_section(); // entries - } - - if (show_log_sum) { - formatter->open_array_section("summary"); - map::iterator siter; - for (siter = summary_map.begin(); siter != summary_map.end(); ++siter) { - const rgw_usage_log_entry& entry = siter->second; - formatter->open_object_section("user"); - formatter->dump_string("user", siter->first); - dump_usage_categories_info(formatter, entry, categories); - rgw_usage_data total_usage; - entry.sum(total_usage, categories); - formatter->open_object_section("total"); - formatter->dump_int("bytes_sent", total_usage.bytes_sent); - formatter->dump_int("bytes_received", total_usage.bytes_received); - formatter->dump_int("ops", total_usage.ops); - formatter->dump_int("successful_ops", total_usage.successful_ops); - formatter->close_section(); // total - - formatter->close_section(); // user - - formatter->flush(cout); - } - - formatter->close_section(); // summary - } - - formatter->close_section(); // usage - formatter->flush(cout); } if (opt_cmd == OPT_USAGE_TRIM) { @@ -1661,7 +1556,7 @@ next: parse_date(start_date, &start_epoch); parse_date(end_date, &end_epoch); - int ret = rgwstore->trim_usage(user_id, start_epoch, end_epoch); + int ret = RGWUsage::trim(rgwstore, user_id, start_epoch, end_epoch); if (ret < 0) { cerr << "ERROR: read_usage() returned ret=" << ret << std::endl; return 1; diff --git a/src/rgw/rgw_usage.cc b/src/rgw/rgw_usage.cc new file mode 100644 index 00000000000..64cfe6bbb8a --- /dev/null +++ b/src/rgw/rgw_usage.cc @@ -0,0 +1,136 @@ + +#include +#include + +#include "rgw_rados.h" +#include "rgw_usage.h" + +using namespace std; + + +static void dump_usage_categories_info(Formatter *formatter, const rgw_usage_log_entry& entry, map *categories) +{ + formatter->open_array_section("categories"); + map::const_iterator uiter; + for (uiter = entry.usage_map.begin(); uiter != entry.usage_map.end(); ++uiter) { + if (categories && categories->size() && !categories->count(uiter->first)) + continue; + const rgw_usage_data& usage = uiter->second; + formatter->open_object_section("entry"); + formatter->dump_string("category", uiter->first); + formatter->dump_int("bytes_sent", usage.bytes_sent); + formatter->dump_int("bytes_received", usage.bytes_received); + formatter->dump_int("ops", usage.ops); + formatter->dump_int("successful_ops", usage.successful_ops); + formatter->close_section(); // entry + } + formatter->close_section(); // categories +} + +int RGWUsage::show(RGWRados *store, string& uid, uint64_t start_epoch, + uint64_t end_epoch, bool show_log_entries, bool show_log_sum, + map *categories, + ceph::Formatter *formatter) +{ + uint32_t max_entries = 1000; + + bool is_truncated = true; + + RGWUsageIter usage_iter; + + map usage; + + formatter->open_object_section("usage"); + if (show_log_entries) { + formatter->open_array_section("entries"); + } + string last_owner; + bool user_section_open = false; + map summary_map; + while (is_truncated) { + int ret = rgwstore->read_usage(uid, start_epoch, end_epoch, max_entries, + &is_truncated, usage_iter, usage); + + if (ret == -ENOENT) { + ret = 0; + is_truncated = false; + } + + if (ret < 0) { + return ret; + } + + map::iterator iter; + for (iter = usage.begin(); iter != usage.end(); ++iter) { + const rgw_user_bucket& ub = iter->first; + const rgw_usage_log_entry& entry = iter->second; + + if (show_log_entries) { + if (ub.user.compare(last_owner) != 0) { + if (user_section_open) { + formatter->close_section(); + formatter->close_section(); + } + formatter->open_object_section("user"); + formatter->dump_string("owner", ub.user); + formatter->open_array_section("buckets"); + user_section_open = true; + last_owner = ub.user; + } + formatter->open_object_section("bucket"); + formatter->dump_string("bucket", ub.bucket); + utime_t ut(entry.epoch, 0); + ut.gmtime(formatter->dump_stream("time")); + formatter->dump_int("epoch", entry.epoch); + dump_usage_categories_info(formatter, entry, categories); + formatter->close_section(); // bucket + formatter->flush(cout); + } + + summary_map[ub.user].aggregate(entry, categories); + } + } + if (show_log_entries) { + if (user_section_open) { + formatter->close_section(); // buckets + formatter->close_section(); //user + } + formatter->close_section(); // entries + } + + if (show_log_sum) { + formatter->open_array_section("summary"); + map::iterator siter; + for (siter = summary_map.begin(); siter != summary_map.end(); ++siter) { + const rgw_usage_log_entry& entry = siter->second; + formatter->open_object_section("user"); + formatter->dump_string("user", siter->first); + dump_usage_categories_info(formatter, entry, categories); + rgw_usage_data total_usage; + entry.sum(total_usage, *categories); + formatter->open_object_section("total"); + formatter->dump_int("bytes_sent", total_usage.bytes_sent); + formatter->dump_int("bytes_received", total_usage.bytes_received); + formatter->dump_int("ops", total_usage.ops); + formatter->dump_int("successful_ops", total_usage.successful_ops); + formatter->close_section(); // total + + formatter->close_section(); // user + + formatter->flush(cout); + } + + formatter->close_section(); // summary + } + + formatter->close_section(); // usage + formatter->flush(cout); + + return 0; +} + +int RGWUsage::trim(RGWRados *store, string& uid, uint64_t start_epoch, + uint64_t end_epoch) +{ + return store->trim_usage(uid, start_epoch, end_epoch); +} diff --git a/src/rgw/rgw_usage.h b/src/rgw/rgw_usage.h new file mode 100644 index 00000000000..1cf9ab8b6ba --- /dev/null +++ b/src/rgw/rgw_usage.h @@ -0,0 +1,25 @@ +#ifndef CEPH_RGW_USAGE_H +#define CEPH_RGW_USAGE_H + +#include +#include + +#include "common/Formatter.h" + +class RGWRados; + + +class RGWUsage +{ +public: + static int show(RGWRados *store, std::string& uid, uint64_t start_epoch, + uint64_t end_epoch, bool show_log_entries, bool show_log_sum, + std::map *categories, + ceph::Formatter *formatter); + + static int trim(RGWRados *store, std::string& uid, uint64_t start_epoch, + uint64_t end_epoch); +}; + + +#endif