From c566f6dc31a39c40fdd66b463d4753d58d0580fc Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 31 Mar 2025 10:44:22 +0200 Subject: [PATCH 1/3] ApiFunction: store own name --- lib/remote/apifunction.cpp | 4 ++-- lib/remote/apifunction.hpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/remote/apifunction.cpp b/lib/remote/apifunction.cpp index 89e1d8734..f153dcb46 100644 --- a/lib/remote/apifunction.cpp +++ b/lib/remote/apifunction.cpp @@ -5,8 +5,8 @@ using namespace icinga; -ApiFunction::ApiFunction(Callback function) - : m_Callback(std::move(function)) +ApiFunction::ApiFunction(const char* name, Callback function) + : m_Name(name), m_Callback(std::move(function)) { } Value ApiFunction::Invoke(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& arguments) diff --git a/lib/remote/apifunction.hpp b/lib/remote/apifunction.hpp index 5a99db518..ea8b7cf1e 100644 --- a/lib/remote/apifunction.hpp +++ b/lib/remote/apifunction.hpp @@ -25,7 +25,12 @@ public: typedef std::function Callback; - ApiFunction(Callback function); + ApiFunction(const char* name, Callback function); + + const char* GetName() const noexcept + { + return m_Name; + } Value Invoke(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& arguments); @@ -33,6 +38,7 @@ public: static void Register(const String& name, const ApiFunction::Ptr& function); private: + const char* m_Name; Callback m_Callback; }; @@ -49,7 +55,7 @@ public: #define REGISTER_APIFUNCTION(name, ns, callback) \ INITIALIZE_ONCE([]() { \ - ApiFunction::Ptr func = new ApiFunction(callback); \ + ApiFunction::Ptr func = new ApiFunction(#ns "::" #name, callback); \ ApiFunctionRegistry::GetInstance()->Register(#ns "::" #name, func); \ }) From 3dd7b1580848a8ba41683c0ca0a797034e087bba Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 1 Apr 2025 15:38:38 +0200 Subject: [PATCH 2/3] Count incoming messages per type and endpoint --- lib/remote/endpoint.cpp | 13 +++++++++++++ lib/remote/endpoint.hpp | 8 ++++++++ lib/remote/jsonrpcconnection.cpp | 4 ++++ 3 files changed, 25 insertions(+) diff --git a/lib/remote/endpoint.cpp b/lib/remote/endpoint.cpp index e534fc178..48621432c 100644 --- a/lib/remote/endpoint.cpp +++ b/lib/remote/endpoint.cpp @@ -2,6 +2,7 @@ #include "remote/endpoint.hpp" #include "remote/endpoint-ti.cpp" +#include "remote/apifunction.hpp" #include "remote/apilistener.hpp" #include "remote/jsonrpcconnection.hpp" #include "remote/zone.hpp" @@ -35,6 +36,13 @@ void Endpoint::SetCachedZone(const Zone::Ptr& zone) m_Zone = zone; } +Endpoint::Endpoint() +{ + for (auto& [name, afunc] : ApiFunctionRegistry::GetInstance()->GetItems()) { + m_MessageCounters.emplace(afunc, 0); + } +} + void Endpoint::AddClient(const JsonRpcConnection::Ptr& client) { bool was_master = ApiListener::GetInstance()->IsMaster(); @@ -117,6 +125,11 @@ void Endpoint::AddMessageReceived(int bytes) SetLastMessageReceived(time); } +void Endpoint::AddMessageReceived(const intrusive_ptr& method) +{ + m_MessageCounters.at(method).fetch_add(1, std::memory_order_relaxed); +} + double Endpoint::GetMessagesSentPerSecond() const { return m_MessagesSent.CalculateRate(Utility::GetTime(), 60); diff --git a/lib/remote/endpoint.hpp b/lib/remote/endpoint.hpp index d641c2c6b..2ccfc053f 100644 --- a/lib/remote/endpoint.hpp +++ b/lib/remote/endpoint.hpp @@ -5,12 +5,16 @@ #include "remote/i2-remote.hpp" #include "remote/endpoint-ti.hpp" +#include "base/atomic.hpp" #include "base/ringbuffer.hpp" +#include #include +#include namespace icinga { +class ApiFunction; class JsonRpcConnection; class Zone; @@ -28,6 +32,8 @@ public: static boost::signals2::signal&)> OnConnected; static boost::signals2::signal&)> OnDisconnected; + Endpoint(); + void AddClient(const intrusive_ptr& client); void RemoveClient(const intrusive_ptr& client); std::set > GetClients() const; @@ -42,6 +48,7 @@ public: void AddMessageSent(int bytes); void AddMessageReceived(int bytes); + void AddMessageReceived(const intrusive_ptr& method); double GetMessagesSentPerSecond() const override; double GetMessagesReceivedPerSecond() const override; @@ -56,6 +63,7 @@ private: mutable std::mutex m_ClientsLock; std::set > m_Clients; intrusive_ptr m_Zone; + std::unordered_map, Atomic> m_MessageCounters; mutable RingBuffer m_MessagesSent{60}; mutable RingBuffer m_MessagesReceived{60}; diff --git a/lib/remote/jsonrpcconnection.cpp b/lib/remote/jsonrpcconnection.cpp index 889d4452c..e7dbb99e2 100644 --- a/lib/remote/jsonrpcconnection.cpp +++ b/lib/remote/jsonrpcconnection.cpp @@ -351,6 +351,10 @@ void JsonRpcConnection::MessageHandler(const Dictionary::Ptr& message) Log(LogNotice, "JsonRpcConnection") << "Call to non-existent function '" << method << "' from endpoint '" << m_Identity << "'."; } else { + if (m_Endpoint) { + m_Endpoint->AddMessageReceived(afunc); + } + Dictionary::Ptr params = message->Get("params"); if (params) resultMessage->Set("result", afunc->Invoke(origin, params)); From 98d097517b70cc5af6354869f1201ecd59f86079 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 1 Apr 2025 16:45:58 +0200 Subject: [PATCH 3/3] Introduce Endpoint#messages_received_per_type --- lib/remote/endpoint.cpp | 13 +++++++++++++ lib/remote/endpoint.hpp | 2 ++ lib/remote/endpoint.ti | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/lib/remote/endpoint.cpp b/lib/remote/endpoint.cpp index 48621432c..db908e558 100644 --- a/lib/remote/endpoint.cpp +++ b/lib/remote/endpoint.cpp @@ -149,3 +149,16 @@ double Endpoint::GetBytesReceivedPerSecond() const { return m_BytesReceived.CalculateRate(Utility::GetTime(), 60); } + +Dictionary::Ptr Endpoint::GetMessagesReceivedPerType() const +{ + DictionaryData result; + + for (auto& [afunc, cnt] : m_MessageCounters) { + if (auto v (cnt.load(std::memory_order_relaxed)); v) { + result.emplace_back(afunc->GetName(), v); + } + } + + return new Dictionary(std::move(result)); +} diff --git a/lib/remote/endpoint.hpp b/lib/remote/endpoint.hpp index 2ccfc053f..09ad8a4fd 100644 --- a/lib/remote/endpoint.hpp +++ b/lib/remote/endpoint.hpp @@ -56,6 +56,8 @@ public: double GetBytesSentPerSecond() const override; double GetBytesReceivedPerSecond() const override; + Dictionary::Ptr GetMessagesReceivedPerType() const override; + protected: void OnAllConfigLoaded() override; diff --git a/lib/remote/endpoint.ti b/lib/remote/endpoint.ti index 78551ecf0..2fa874b5e 100644 --- a/lib/remote/endpoint.ti +++ b/lib/remote/endpoint.ti @@ -54,6 +54,10 @@ class Endpoint : ConfigObject [no_user_modify, no_storage] double bytes_received_per_second { get; }; + + [no_user_modify, no_storage] Dictionary::Ptr messages_received_per_type { + get; + }; }; }