diff --git a/include/ircd/resource/method.h b/include/ircd/resource/method.h index 51b8e080f..4139e7c86 100644 --- a/include/ircd/resource/method.h +++ b/include/ircd/resource/method.h @@ -70,9 +70,13 @@ struct ircd::resource::method::opts struct ircd::resource::method::stats { - uint64_t pending {0}; // Clients currently inside the method - uint64_t requests {0}; // The method was found and called. - uint64_t timeouts {0}; // The method's timeout was exceeded. - uint64_t completions {0}; // The handler returned without throwing. - uint64_t internal_errors {0}; // The handler threw a very bad exception. + using item = ircd::stats::item; + + item pending; ///< Clients currently inside the method + item requests; ///< The method was found and called. + item timeouts; ///< The method's timeout was exceeded. + item completions; ///< The handler returned without throwing. + item internal_errors; ///< The handler threw a very bad exception. + + stats(method &); }; diff --git a/ircd/resource.cc b/ircd/resource.cc index 4c49b9ba6..02f93622b 100644 --- a/ircd/resource.cc +++ b/ircd/resource.cc @@ -349,6 +349,56 @@ ircd::resource::method::default_payload_max { "default", long(128_KiB) }, }; +// +// method::stats +// + +namespace ircd +{ + static thread_local char method_stats_name_buf[128]; + static string_view method_stats_name(resource::method &, const string_view &); +} + +ircd::resource::method::stats::stats(method &m) +:pending +{ + { "name", method_stats_name(m, "pending") } +} +,requests +{ + { "name", method_stats_name(m, "requests") } +} +,timeouts +{ + { "name", method_stats_name(m, "timeouts") } +} +,completions +{ + { "name", method_stats_name(m, "completed") } +} +,internal_errors +{ + { "name", method_stats_name(m, "internal_errors") } +} +{ +} + +ircd::string_view +ircd::method_stats_name(resource::method &m, + const string_view &key) +{ + assert(m.resource); + assert(m.resource->path); + assert(m.name); + assert(key); + return fmt::sprintf + { + method_stats_name_buf, "ircd.resource.%s.%s.%s", + m.resource->path, + m.name, + key, + }; +} // // method::method // @@ -385,7 +435,7 @@ ircd::resource::method::method(struct resource &resource, } ,stats { - std::make_unique() + std::make_unique(*this) } ,methods_it{[this, &name] { @@ -420,7 +470,7 @@ noexcept "Resource '%s' method '%s' still waiting for %zu pending requests", resource->path, name, - stats->pending + uint64_t(stats->pending), }; const ctx::uninterruptible::nothrow ui; @@ -445,7 +495,7 @@ try ++stats->requests; const scope_count pending { - stats->pending + static_cast(stats->pending) }; // Bail out if the method limited the amount of content and it was exceeded.