diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5e13a629f..a0ad4cbf0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,6 +53,7 @@ set(memgraph_src_files transactions/engine_master.cpp transactions/engine_single_node.cpp transactions/engine_worker.cpp + utils/demangle.cpp utils/file.cpp utils/network.cpp utils/watchdog.cpp diff --git a/src/communication/rpc/client.hpp b/src/communication/rpc/client.hpp index 105c4c0be..bcad97fcd 100644 --- a/src/communication/rpc/client.hpp +++ b/src/communication/rpc/client.hpp @@ -10,6 +10,8 @@ #include "communication/rpc/messages.hpp" #include "io/network/endpoint.hpp" #include "io/network/socket.hpp" +#include "stats/metrics.hpp" +#include "utils/demangle.hpp" namespace communication::rpc { @@ -28,8 +30,14 @@ class Client { "TRequestResponse::Request must be derived from Message"); static_assert(std::is_base_of::value, "TRequestResponse::Response must be derived from Message"); - auto response = Call(std::unique_ptr( - std::make_unique(std::forward(args)...))); + std::string request_name = + fmt::format("rpc.client.{}.{}", service_name_, + utils::Demangle(typeid(Req).name()).value_or("unknown")); + std::unique_ptr response = nullptr; + stats::Stopwatch(request_name, [&] { + response = Call(std::unique_ptr( + std::make_unique(std::forward(args)...))); + }); auto *real_response = dynamic_cast(response.get()); if (!real_response && response) { // Since message_id was checked in private Call function, this means diff --git a/src/communication/rpc/server.cpp b/src/communication/rpc/server.cpp index d7563db16..4d23e0011 100644 --- a/src/communication/rpc/server.cpp +++ b/src/communication/rpc/server.cpp @@ -7,6 +7,7 @@ #include "communication/rpc/server.hpp" #include "stats/metrics.hpp" +#include "utils/demangle.hpp" namespace communication::rpc { @@ -72,10 +73,12 @@ Server::Server(System &system, const std::string &service_name, auto it = callbacks_accessor.find(message->type_index()); if (it == callbacks_accessor.end()) continue; - auto req_name = RequestName(service_name, message->type_index()); + auto request_name = fmt::format( + "rpc.server.{}.{}", service_name, + utils::Demangle(message->type_index().name()).value_or("unknown")); std::unique_ptr response = nullptr; - stats::Stopwatch(req_name, + stats::Stopwatch(request_name, [&] { response = it->second(*(message.get())); }); SendMessage(*socket, message_id, response); } diff --git a/src/utils/demangle.cpp b/src/utils/demangle.cpp new file mode 100644 index 000000000..217c2ec72 --- /dev/null +++ b/src/utils/demangle.cpp @@ -0,0 +1,18 @@ +#include "utils/demangle.hpp" + +#include + +namespace utils { + +std::experimental::optional Demangle(const char *mangled_name) { + int s; + char *type_name = abi::__cxa_demangle(mangled_name, nullptr, nullptr, &s); + std::experimental::optional ret = std::experimental::nullopt; + if (s == 0) { + ret = type_name; + free(type_name); + } + return ret; +} + +} // namespace utils diff --git a/src/utils/demangle.hpp b/src/utils/demangle.hpp new file mode 100644 index 000000000..70556fe6f --- /dev/null +++ b/src/utils/demangle.hpp @@ -0,0 +1,17 @@ +/** + * @file + */ +#pragma once + +#include +#include + +namespace utils { + +/** + * Converts a mangled name to a human-readable name using abi::__cxa_demangle. + * Returns nullopt if the conversion failed. + */ +std::experimental::optional Demangle(const char *mangled_name); + +} // namespace utils diff --git a/tests/unit/demangle.cpp b/tests/unit/demangle.cpp new file mode 100644 index 000000000..78953729b --- /dev/null +++ b/tests/unit/demangle.cpp @@ -0,0 +1,23 @@ +#include "glog/logging.h" +#include "gtest/gtest.h" + +#include "utils/demangle.hpp" + +using utils::Demangle; + +struct DummyStruct {}; + +template +class DummyClass {}; + +TEST(Demangle, Demangle) { + int x; + char *s; + DummyStruct t; + DummyClass c; + + EXPECT_EQ(*Demangle(typeid(x).name()), "int"); + EXPECT_EQ(*Demangle(typeid(s).name()), "char*"); + EXPECT_EQ(*Demangle(typeid(t).name()), "DummyStruct"); + EXPECT_EQ(*Demangle(typeid(c).name()), "DummyClass"); +}