Add client side RPC stats
Summary: ^^ Reviewers: mferencevic, buda Reviewed By: mferencevic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1224
This commit is contained in:
parent
16853e5b8a
commit
5ff1ca4a5d
@ -53,6 +53,7 @@ set(memgraph_src_files
|
|||||||
transactions/engine_master.cpp
|
transactions/engine_master.cpp
|
||||||
transactions/engine_single_node.cpp
|
transactions/engine_single_node.cpp
|
||||||
transactions/engine_worker.cpp
|
transactions/engine_worker.cpp
|
||||||
|
utils/demangle.cpp
|
||||||
utils/file.cpp
|
utils/file.cpp
|
||||||
utils/network.cpp
|
utils/network.cpp
|
||||||
utils/watchdog.cpp
|
utils/watchdog.cpp
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "communication/rpc/messages.hpp"
|
#include "communication/rpc/messages.hpp"
|
||||||
#include "io/network/endpoint.hpp"
|
#include "io/network/endpoint.hpp"
|
||||||
#include "io/network/socket.hpp"
|
#include "io/network/socket.hpp"
|
||||||
|
#include "stats/metrics.hpp"
|
||||||
|
#include "utils/demangle.hpp"
|
||||||
|
|
||||||
namespace communication::rpc {
|
namespace communication::rpc {
|
||||||
|
|
||||||
@ -28,8 +30,14 @@ class Client {
|
|||||||
"TRequestResponse::Request must be derived from Message");
|
"TRequestResponse::Request must be derived from Message");
|
||||||
static_assert(std::is_base_of<Message, Res>::value,
|
static_assert(std::is_base_of<Message, Res>::value,
|
||||||
"TRequestResponse::Response must be derived from Message");
|
"TRequestResponse::Response must be derived from Message");
|
||||||
auto response = Call(std::unique_ptr<Message>(
|
std::string request_name =
|
||||||
|
fmt::format("rpc.client.{}.{}", service_name_,
|
||||||
|
utils::Demangle(typeid(Req).name()).value_or("unknown"));
|
||||||
|
std::unique_ptr<Message> response = nullptr;
|
||||||
|
stats::Stopwatch(request_name, [&] {
|
||||||
|
response = Call(std::unique_ptr<Message>(
|
||||||
std::make_unique<Req>(std::forward<Args>(args)...)));
|
std::make_unique<Req>(std::forward<Args>(args)...)));
|
||||||
|
});
|
||||||
auto *real_response = dynamic_cast<Res *>(response.get());
|
auto *real_response = dynamic_cast<Res *>(response.get());
|
||||||
if (!real_response && response) {
|
if (!real_response && response) {
|
||||||
// Since message_id was checked in private Call function, this means
|
// Since message_id was checked in private Call function, this means
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "communication/rpc/server.hpp"
|
#include "communication/rpc/server.hpp"
|
||||||
#include "stats/metrics.hpp"
|
#include "stats/metrics.hpp"
|
||||||
|
#include "utils/demangle.hpp"
|
||||||
|
|
||||||
namespace communication::rpc {
|
namespace communication::rpc {
|
||||||
|
|
||||||
@ -72,10 +73,12 @@ Server::Server(System &system, const std::string &service_name,
|
|||||||
auto it = callbacks_accessor.find(message->type_index());
|
auto it = callbacks_accessor.find(message->type_index());
|
||||||
if (it == callbacks_accessor.end()) continue;
|
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<Message> response = nullptr;
|
std::unique_ptr<Message> response = nullptr;
|
||||||
|
|
||||||
stats::Stopwatch(req_name,
|
stats::Stopwatch(request_name,
|
||||||
[&] { response = it->second(*(message.get())); });
|
[&] { response = it->second(*(message.get())); });
|
||||||
SendMessage(*socket, message_id, response);
|
SendMessage(*socket, message_id, response);
|
||||||
}
|
}
|
||||||
|
18
src/utils/demangle.cpp
Normal file
18
src/utils/demangle.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "utils/demangle.hpp"
|
||||||
|
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
std::experimental::optional<std::string> Demangle(const char *mangled_name) {
|
||||||
|
int s;
|
||||||
|
char *type_name = abi::__cxa_demangle(mangled_name, nullptr, nullptr, &s);
|
||||||
|
std::experimental::optional<std::string> ret = std::experimental::nullopt;
|
||||||
|
if (s == 0) {
|
||||||
|
ret = type_name;
|
||||||
|
free(type_name);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace utils
|
17
src/utils/demangle.hpp
Normal file
17
src/utils/demangle.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <experimental/optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a mangled name to a human-readable name using abi::__cxa_demangle.
|
||||||
|
* Returns nullopt if the conversion failed.
|
||||||
|
*/
|
||||||
|
std::experimental::optional<std::string> Demangle(const char *mangled_name);
|
||||||
|
|
||||||
|
} // namespace utils
|
23
tests/unit/demangle.cpp
Normal file
23
tests/unit/demangle.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "glog/logging.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "utils/demangle.hpp"
|
||||||
|
|
||||||
|
using utils::Demangle;
|
||||||
|
|
||||||
|
struct DummyStruct {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class DummyClass {};
|
||||||
|
|
||||||
|
TEST(Demangle, Demangle) {
|
||||||
|
int x;
|
||||||
|
char *s;
|
||||||
|
DummyStruct t;
|
||||||
|
DummyClass<int> 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<int>");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user