Skip to content

Commit a05aea1

Browse files
eliranroffetrabetti
authored andcommitted
Move Hystrix code from Admin to a decdicated file
Signed-off-by: Eliran Roffe <[email protected]>
1 parent 61659a3 commit a05aea1

File tree

8 files changed

+152
-140
lines changed

8 files changed

+152
-140
lines changed

include/envoy/server/admin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace Server {
3232
*/
3333
class HandlerInfo {
3434
public:
35-
virtual ~HandlerInfo() {};
35+
virtual ~HandlerInfo(){};
3636
virtual void Destroy() PURE;
3737
};
3838

source/common/stats/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ envoy_cc_library(
7777
hdrs = ["hystrix.h"],
7878
deps = [
7979
":stats_lib",
80+
"//include/envoy/server:admin_interface",
81+
"//include/envoy/server:instance_interface",
82+
"//source/common/buffer:buffer_lib",
8083
"//source/common/common:logger_lib",
8184
],
8285
)

source/common/stats/hystrix.cc

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <iostream>
66
#include <sstream>
77

8+
#include "common/buffer/buffer_impl.h"
89
#include "common/common/logger.h"
910

1011
namespace Envoy {
@@ -29,8 +30,6 @@ uint64_t Hystrix::getRollingValue(std::string cluster_name, std::string stats) {
2930
if (rolling_stats_map_.find(key) != rolling_stats_map_.end()) {
3031
// if the counter was reset, the result is negative
3132
// better return 0, will be back to normal once one rolling window passes
32-
// better idea what to return? could change the algorithm to keep last valid delta,
33-
// updated with pushNewValue and kept stable when the update is negative.
3433
if (rolling_stats_map_[key][current_index_] <
3534
rolling_stats_map_[key][(current_index_ + 1) % num_of_buckets_]) {
3635
return 0;
@@ -215,5 +214,81 @@ std::string Hystrix::printRollingWindow() {
215214
return out_str.str();
216215
}
217216

217+
void HystrixHandlerInfoImpl::Destroy() {
218+
if (data_timer_) {
219+
data_timer_->disableTimer();
220+
data_timer_.reset();
221+
}
222+
if (ping_timer_) {
223+
ping_timer_->disableTimer();
224+
ping_timer_.reset();
225+
}
226+
}
227+
228+
void HystrixHandler::HandleEventStream(HystrixHandlerInfoImpl* hystrix_handler_info,
229+
Server::Instance& server) {
230+
Server::Instance* serverPtr = &server;
231+
// start streaming
232+
hystrix_handler_info->data_timer_ = hystrix_handler_info->callbacks_->dispatcher().createTimer(
233+
[hystrix_handler_info, serverPtr]() -> void {
234+
HystrixHandler::prepareAndSendHystrixStream(hystrix_handler_info, serverPtr);
235+
});
236+
hystrix_handler_info->data_timer_->enableTimer(
237+
std::chrono::milliseconds(Stats::Hystrix::GetRollingWindowIntervalInMs()));
238+
239+
// start keep alive ping
240+
hystrix_handler_info->ping_timer_ =
241+
hystrix_handler_info->callbacks_->dispatcher().createTimer([hystrix_handler_info]() -> void {
242+
HystrixHandler::sendKeepAlivePing(hystrix_handler_info);
243+
});
244+
245+
hystrix_handler_info->ping_timer_->enableTimer(
246+
std::chrono::milliseconds(Stats::Hystrix::GetPingIntervalInMs()));
247+
}
248+
249+
void HystrixHandler::updateHystrixRollingWindow(HystrixHandlerInfoImpl* hystrix_handler_info,
250+
Server::Instance* server) {
251+
hystrix_handler_info->stats_->incCounter();
252+
for (auto& cluster : server->clusterManager().clusters()) {
253+
hystrix_handler_info->stats_->updateRollingWindowMap(server->stats(),
254+
cluster.second.get().info()->name());
255+
}
256+
}
257+
258+
void HystrixHandler::prepareAndSendHystrixStream(HystrixHandlerInfoImpl* hystrix_handler_info,
259+
Server::Instance* server) {
260+
updateHystrixRollingWindow(hystrix_handler_info, server);
261+
std::stringstream ss;
262+
for (auto& cluster : server->clusterManager().clusters()) {
263+
hystrix_handler_info->stats_->getClusterStats(
264+
ss, cluster.second.get().info()->name(),
265+
cluster.second.get()
266+
.info()
267+
->resourceManager(Upstream::ResourcePriority::Default)
268+
.pendingRequests()
269+
.max(),
270+
server->stats()
271+
.gauge("cluster." + cluster.second.get().info()->name() + ".membership_total")
272+
.value());
273+
}
274+
Buffer::OwnedImpl data;
275+
data.add(ss.str());
276+
hystrix_handler_info->callbacks_->encodeData(data, false);
277+
278+
// restart timer
279+
hystrix_handler_info->data_timer_->enableTimer(
280+
std::chrono::milliseconds(Stats::Hystrix::GetRollingWindowIntervalInMs()));
281+
}
282+
283+
void HystrixHandler::sendKeepAlivePing(HystrixHandlerInfoImpl* hystrix_handler_info) {
284+
Buffer::OwnedImpl data;
285+
data.add(":\n\n");
286+
hystrix_handler_info->callbacks_->encodeData(data, false);
287+
288+
// restart timer
289+
hystrix_handler_info->ping_timer_->enableTimer(
290+
std::chrono::milliseconds(Stats::Hystrix::GetPingIntervalInMs()));
291+
}
292+
218293
} // namespace Stats
219294
} // namespace Envoy

source/common/stats/hystrix.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include <memory>
33
#include <vector>
44

5+
#include "envoy/server/admin.h"
6+
#include "envoy/server/instance.h"
57
#include "envoy/stats/stats.h"
68

79
namespace Envoy {
@@ -101,5 +103,60 @@ class Hystrix {
101103

102104
typedef std::unique_ptr<Hystrix> HystrixPtr;
103105

106+
/**
107+
* This class contains data which will be sent from admin filter to a hystrix_event_stream handler
108+
* and build a class which contains the relevant data.
109+
*/
110+
class HystrixHandlerInfoImpl : public Server::HandlerInfo {
111+
public:
112+
HystrixHandlerInfoImpl(Http::StreamDecoderFilterCallbacks* callbacks)
113+
: stats_(new Stats::Hystrix()), data_timer_(nullptr), ping_timer_(nullptr),
114+
callbacks_(callbacks) {}
115+
virtual ~HystrixHandlerInfoImpl(){};
116+
virtual void Destroy();
117+
118+
/**
119+
* HystrixHandlerInfoImpl includes statistics for hystrix API, timers for build (and send) data
120+
* and keep alive messages and the handler's callback
121+
*/
122+
Stats::HystrixPtr stats_;
123+
Event::TimerPtr data_timer_;
124+
Event::TimerPtr ping_timer_;
125+
Http::StreamDecoderFilterCallbacks* callbacks_{};
126+
};
127+
128+
/**
129+
* Convert statistics from envoy format to hystrix format and prepare them and writes them to the
130+
* appropriate socket
131+
*/
132+
class HystrixHandler {
133+
public:
134+
static void HandleEventStream(HystrixHandlerInfoImpl* hystrix_handler_info,
135+
Server::Instance& server);
136+
/**
137+
* Update counter and set values of upstream_rq statistics
138+
* @param hystrix_handler_info is the data which is received in the hystrix handler from the admin
139+
* filter (callback, timers, statistics)
140+
* @param server contains envoy statistics
141+
*/
142+
static void updateHystrixRollingWindow(HystrixHandlerInfoImpl* hystrix_handler_info,
143+
Server::Instance* server);
144+
/**
145+
* Builds a buffer of envoy statistics which will be sent to hystrix dashboard according to
146+
* hystrix API
147+
* @param hystrix_handler_info is the data which is received in the hystrix handler from the admin
148+
* filter (callback, timers, statistics)
149+
* @param server contains envoy statistics*
150+
*/
151+
static void prepareAndSendHystrixStream(HystrixHandlerInfoImpl* hystrix_handler_info,
152+
Server::Instance* server);
153+
/**
154+
* Sends a keep alive (ping) message to hystrix dashboard
155+
* @param hystrix_handler_info is the data which is received in the hystrix handler from the admin
156+
* filter (callback, timers, statistics)
157+
*/
158+
static void sendKeepAlivePing(HystrixHandlerInfoImpl* hystrix_handler_info);
159+
};
160+
104161
} // namespace Stats
105162
} // namespace Envoy

source/server/http/admin.cc

Lines changed: 4 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -590,24 +590,9 @@ Http::Code AdminImpl::handlerHystrixEventStream(const std::string&,
590590
Http::Headers::get().AccessControlAllowOriginValue.All);
591591
response_headers.insertNoChunks().value().setReference("0");
592592

593-
HystrixHandlerInfoImpl& hystrix_handler_info = dynamic_cast<HystrixHandlerInfoImpl&>(handler_info);
594-
595-
// start streaming
596-
hystrix_handler_info.data_timer_ = hystrix_handler_info.callbacks_->dispatcher().createTimer(
597-
[this, &hystrix_handler_info]() -> void {
598-
HystrixHandler::prepareAndSendHystrixStream(&hystrix_handler_info, server_);
599-
});
600-
hystrix_handler_info.data_timer_->enableTimer(
601-
std::chrono::milliseconds(Stats::Hystrix::GetRollingWindowIntervalInMs()));
602-
603-
// start keep alive ping
604-
hystrix_handler_info.ping_timer_ =
605-
hystrix_handler_info.callbacks_->dispatcher().createTimer([&hystrix_handler_info]() -> void {
606-
HystrixHandler::sendKeepAlivePing(&hystrix_handler_info);
607-
});
608-
609-
hystrix_handler_info.ping_timer_->enableTimer(
610-
std::chrono::milliseconds(Stats::Hystrix::GetPingIntervalInMs()));
593+
Stats::HystrixHandlerInfoImpl& hystrix_handler_info =
594+
dynamic_cast<Stats::HystrixHandlerInfoImpl&>(handler_info);
595+
Stats::HystrixHandler::HandleEventStream(&hystrix_handler_info, server_);
611596

612597
ENVOY_LOG(debug, "start sending data to hystrix dashboard on port {}",
613598
hystrix_handler_info.callbacks_->connection()->localAddress()->asString());
@@ -627,7 +612,7 @@ void AdminFilter::onComplete() {
627612
handler_info_ = std::make_unique<HandlerInfoImpl>();
628613
code = parent_.runCallback(path, *header_map, response, *handler_info_);
629614
} else {
630-
handler_info_ = std::make_unique<HystrixHandlerInfoImpl>(callbacks_);
615+
handler_info_ = std::make_unique<Stats::HystrixHandlerInfoImpl>(callbacks_);
631616
code = parent_.runCallback(path, *header_map, response, *handler_info_);
632617
end_stream = false;
633618
}
@@ -846,60 +831,5 @@ bool AdminImpl::removeHandler(const std::string& prefix) {
846831
return false;
847832
}
848833

849-
void HystrixHandlerInfoImpl::Destroy() {
850-
if (data_timer_) {
851-
data_timer_->disableTimer();
852-
data_timer_.reset();
853-
}
854-
if (ping_timer_) {
855-
ping_timer_->disableTimer();
856-
ping_timer_.reset();
857-
}
858-
}
859-
860-
void HystrixHandler::updateHystrixRollingWindow(HystrixHandlerInfoImpl* hystrix_handler_info,
861-
Server::Instance& server) {
862-
hystrix_handler_info->stats_->incCounter();
863-
for (auto& cluster : server.clusterManager().clusters()) {
864-
hystrix_handler_info->stats_->updateRollingWindowMap(server.stats(),
865-
cluster.second.get().info()->name());
866-
}
867-
}
868-
869-
void HystrixHandler::prepareAndSendHystrixStream(HystrixHandlerInfoImpl* hystrix_handler_info,
870-
Server::Instance& server) {
871-
updateHystrixRollingWindow(hystrix_handler_info, server);
872-
std::stringstream ss;
873-
for (auto& cluster : server.clusterManager().clusters()) {
874-
hystrix_handler_info->stats_->getClusterStats(
875-
ss, cluster.second.get().info()->name(),
876-
cluster.second.get()
877-
.info()
878-
->resourceManager(Upstream::ResourcePriority::Default)
879-
.pendingRequests()
880-
.max(),
881-
server.stats()
882-
.gauge("cluster." + cluster.second.get().info()->name() + ".membership_total")
883-
.value());
884-
}
885-
Buffer::OwnedImpl data;
886-
data.add(ss.str());
887-
hystrix_handler_info->callbacks_->encodeData(data, false);
888-
889-
// restart timer
890-
hystrix_handler_info->data_timer_->enableTimer(
891-
std::chrono::milliseconds(Stats::Hystrix::GetRollingWindowIntervalInMs()));
892-
}
893-
894-
void HystrixHandler::sendKeepAlivePing(HystrixHandlerInfoImpl* hystrix_handler_info) {
895-
Buffer::OwnedImpl data;
896-
data.add(":\n\n");
897-
hystrix_handler_info->callbacks_->encodeData(data, false);
898-
899-
// restart timer
900-
hystrix_handler_info->ping_timer_->enableTimer(
901-
std::chrono::milliseconds(Stats::Hystrix::GetPingIntervalInMs()));
902-
}
903-
904834
} // namespace Server
905835
} // namespace Envoy

source/server/http/admin.h

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,6 @@ class HandlerInfoImpl : public HandlerInfo {
4040
virtual void Destroy(){};
4141
};
4242

43-
/**
44-
* This class contains data which will be sent from admin filter to a hystrix_event_stream handler
45-
* and build a class which contains the relevant data.
46-
*/
47-
class HystrixHandlerInfoImpl : public HandlerInfo {
48-
public:
49-
HystrixHandlerInfoImpl(Http::StreamDecoderFilterCallbacks* callbacks)
50-
: stats_(new Stats::Hystrix()), data_timer_(nullptr), ping_timer_(nullptr),
51-
callbacks_(callbacks) {}
52-
virtual ~HystrixHandlerInfoImpl(){};
53-
virtual void Destroy();
54-
55-
/**
56-
* HystrixHandlerInfoImpl includes statistics for hystrix API, timers for build (and send) data and
57-
* keep alive messages and the handler's callback
58-
*/
59-
Stats::HystrixPtr stats_;
60-
Event::TimerPtr data_timer_;
61-
Event::TimerPtr ping_timer_;
62-
Http::StreamDecoderFilterCallbacks* callbacks_{};
63-
};
64-
6543
/**
6644
* Implementation of Server::admin.
6745
*/
@@ -314,36 +292,5 @@ class PrometheusStatsFormatter {
314292
static std::string sanitizeName(const std::string& name);
315293
};
316294

317-
/**
318-
* Convert statistics from envoy format to hystrix format and prepare them and writes them to the
319-
* appropriate socket
320-
*/
321-
class HystrixHandler {
322-
public:
323-
/**
324-
* Update counter and set values of upstream_rq statistics
325-
* @param hystrix_handler_info is the data which is received in the hystrix handler from the admin
326-
* filter (callback, timers, statistics)
327-
* @param server contains envoy statistics
328-
*/
329-
static void updateHystrixRollingWindow(HystrixHandlerInfoImpl* hystrix_handler_info,
330-
Server::Instance& server);
331-
/**
332-
* Builds a buffer of envoy statistics which will be sent to hystrix dashboard according to
333-
* hystrix API
334-
* @param hystrix_handler_info is the data which is received in the hystrix handler from the admin
335-
* filter (callback, timers, statistics)
336-
* @param server contains envoy statistics*
337-
*/
338-
static void prepareAndSendHystrixStream(HystrixHandlerInfoImpl* hystrix_handler_info,
339-
Server::Instance& server);
340-
/**
341-
* Sends a keep alive (ping) message to hystrix dashboard
342-
* @param hystrix_handler_info is the data which is received in the hystrix handler from the admin
343-
* filter (callback, timers, statistics)
344-
*/
345-
static void sendKeepAlivePing(HystrixHandlerInfoImpl* hystrix_handler_info);
346-
};
347-
348295
} // namespace Server
349296
} // namespace Envoy

test/common/router/rds_impl_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ TEST_F(RdsImplTest, Basic) {
233233
)EOF";
234234
EXPECT_EQ("", rds_->versionInfo());
235235
Http::HeaderMapImpl header_map;
236-
Server::HandlerInfo handler_info;
236+
Server::HandlerInfoImpl handler_info;
237237
EXPECT_EQ(Http::Code::OK, handler_callback_("/routes", header_map, data, handler_info));
238238
EXPECT_EQ(routes_expected_output_no_routes, TestUtility::bufferToString(data));
239239
data.drain(data.length());
@@ -617,7 +617,7 @@ TEST_F(RouteConfigProviderManagerImplTest, Basic) {
617617

618618
// Test Admin /routes handler.
619619
Http::HeaderMapImpl header_map;
620-
Server::HandlerInfo handler_info;
620+
Server::HandlerInfoImpl handler_info;
621621
EXPECT_EQ(Http::Code::OK, handler_callback_("/routes", header_map, data, handler_info));
622622
EXPECT_EQ(routes_expected_output, TestUtility::bufferToString(data));
623623
data.drain(data.length());

0 commit comments

Comments
 (0)