Skip to content

Commit 3f0f133

Browse files
committed
Forward all collected cluster stats to all connected parents
1 parent eead969 commit 3f0f133

File tree

2 files changed

+73
-16
lines changed

2 files changed

+73
-16
lines changed

lib/remote/statsreporter.cpp

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222
#include "base/function.hpp"
2323
#include "base/objectlock.hpp"
2424
#include "base/scriptglobal.hpp"
25-
#include "base/utility.hpp"
2625
#include "base/value.hpp"
2726
#include "remote/apifunction.hpp"
2827
#include "remote/endpoint.hpp"
2928
#include "remote/messageorigin.hpp"
3029
#include "remote/statsreporter.hpp"
3130
#include "remote/zone.hpp"
3231
#include <boost/bind.hpp>
32+
#include <boost/thread/mutex.hpp>
3333
#include <atomic>
34+
#include <set>
3435

3536
using namespace icinga;
3637

@@ -56,20 +57,40 @@ void StatsReporter::OnConnected(const Endpoint::Ptr& endpoint)
5657

5758
void StatsReporter::ReportStats()
5859
{
59-
Dictionary::Ptr stats;
60+
Dictionary::Ptr message;
6061

6162
for (auto& zone : Zone::GetLocalZone()->GetAllParents()) {
6263
for (auto& endpoint : zone->GetEndpoints()) {
6364
for (auto& client : endpoint->GetClients()) {
64-
if (!stats) {
65-
stats = GenerateStats();
65+
if (!message) {
66+
Dictionary::Ptr allStats = new Dictionary;
6667

67-
if (!stats) {
68-
return;
68+
auto stats (GenerateStats());
69+
70+
if (stats)
71+
allStats->Set(Endpoint::GetLocalEndpoint()->GetName(), stats);
72+
73+
{
74+
boost::mutex::scoped_lock lock (m_Mutex);
75+
76+
for (auto& endpointStats : m_SecondaryStats) {
77+
allStats->Set(endpointStats.first, endpointStats.second);
78+
}
6979
}
80+
81+
if (!allStats->GetLength())
82+
return;
83+
84+
message = new Dictionary({
85+
{ "jsonrpc", "2.0" },
86+
{ "method", "event::ClusterStats" },
87+
{ "params", new Dictionary({
88+
{ "stats", allStats }
89+
}) }
90+
});
7091
}
7192

72-
client->SendMessage(stats);
93+
client->SendMessage(message);
7394

7495
break;
7596
}
@@ -93,21 +114,50 @@ Dictionary::Ptr StatsReporter::GenerateStats()
93114
}
94115
}
95116

96-
return new Dictionary({
97-
{ "jsonrpc", "2.0" },
98-
{ "method", "event::ClusterStats" },
99-
{ "params", new Dictionary({
100-
{ "ctime", Utility::GetTime() },
101-
{ "stats", status }
102-
}) }
103-
});
117+
return status;
104118
}
105119

106120
return nullptr;
107121
}
108122

109123
Value StatsReporter::ClusterStatsAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
110124
{
111-
// TODO
125+
auto endpoint (origin->FromClient->GetEndpoint());
126+
127+
if (endpoint && endpoint->GetZone()->IsChildOf(Zone::GetLocalZone())) {
128+
auto rawStats (params->Get("stats"));
129+
130+
if (rawStats.IsObject()) {
131+
Dictionary::Ptr allStats (rawStats);
132+
133+
if (allStats) {
134+
// For security reasons
135+
std::set<String> neighborhood;
136+
137+
for (auto& endpoint : Zone::GetLocalZone()->GetEndpoints()) {
138+
neighborhood.emplace(endpoint->GetName());
139+
}
140+
141+
ObjectLock lock (allStats);
142+
143+
for (auto& endpointStats : allStats) {
144+
if (endpointStats.second.IsObject()) {
145+
Dictionary::Ptr stats (endpointStats.second);
146+
147+
if (stats && neighborhood.find(endpointStats.first) == neighborhood.end()) {
148+
m_Instance.ClusterStatsHandler(endpointStats.first, endpointStats.second);
149+
}
150+
}
151+
}
152+
}
153+
}
154+
}
155+
112156
return Empty;
113157
}
158+
159+
void StatsReporter::ClusterStatsHandler(const String& endpoint, const Dictionary::Ptr& stats)
160+
{
161+
boost::mutex::scoped_lock lock (m_Mutex);
162+
m_SecondaryStats[endpoint] = stats;
163+
}

lib/remote/statsreporter.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@
2121
#define STATSREPORTER_H
2222

2323
#include "base/dictionary.hpp"
24+
#include "base/string.hpp"
2425
#include "base/timer.hpp"
2526
#include "base/value.hpp"
2627
#include "remote/endpoint.hpp"
2728
#include "remote/messageorigin.hpp"
2829
#include <atomic>
30+
#include <boost/thread/mutex.hpp>
31+
#include <map>
2932

3033
namespace icinga
3134
{
@@ -44,11 +47,15 @@ class StatsReporter
4447
void OnConnected(const Endpoint::Ptr& endpoint);
4548
void ReportStats();
4649
Dictionary::Ptr GenerateStats();
50+
void ClusterStatsHandler(const String& endpoint, const Dictionary::Ptr& stats);
4751

4852
static StatsReporter m_Instance;
4953

5054
std::atomic_flag m_HasBeenInitialized;
5155
Timer::Ptr timer;
56+
57+
boost::mutex m_Mutex;
58+
std::map<String, Dictionary::Ptr> m_SecondaryStats;
5259
};
5360

5461
}

0 commit comments

Comments
 (0)