Skip to content

Commit

Permalink
Merge pull request #89 from bloomberg/print-datalimit
Browse files Browse the repository at this point in the history
Display configured data rate limits for LIMIT PRINT command
  • Loading branch information
Chinmay1412 authored Jul 21, 2022
2 parents 46f09fe + 5ecdbf7 commit 376179d
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 44 deletions.
26 changes: 25 additions & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ EXIT Exit the program gracefully.
FARM (ADD name selector backend* | PARTITION name policy | DELETE name | PRINT) - Change farms
HELP Print this help text.
LIMIT (CONN_RATE_ALARM | CONN_RATE) (VHOST vhostName numberOfConnections | DEFAULT numberOfConnections) - Configure connection rate limits (normal or alarmonly) for incoming clients connections
LIMIT DISABLE (CONN_RATE_ALARM | CONN_RATE) (VHOST vhostName | DEFAULT) - Disable configured connection rate limits (normal or alarmonly) for incoming clients
LIMIT (DATA_RATE_ALARM | DATA_RATE) (DEFAULT | VHOST vhostName) BytesPerSecond - Configure data rate limits or alarms for incoming client data
LIMIT DISABLE (CONN_RATE_ALARM | CONN_RATE | DATA_RATE_ALARM | DATA_RATE) (VHOST vhostName | DEFAULT) - Disable configured limit thresholds
LIMIT PRINT [vhostName] - Print the configured default or specific connection rate limits for specified vhost
LISTEN START port | START_SECURE port | STOP [port]
LOG CONSOLE verbosity | FILE verbosity
Expand Down Expand Up @@ -141,6 +142,21 @@ Apply limit on allowed average number of connections per second for all the vhos
#### LIMIT CONN_RATE VHOST vhostName numberOfConnections
Apply limit on allowed average number of connections per second for specified vhost. The specific limit takes priority over the default limit for any vhost.

#### LIMIT DATA_RATE_ALARM DEFAULT BytesPerSecond

Apply limit on allowed max bytes per second in alarm only mode for all the vhosts. So whenever any in-coming connection violates the data rate limit, the proxy will only emit log with Data Rate Alarm as a substring and the relevant limiter details, instead of actively limiting any data.

#### LIMIT DATA_RATE_ALARM VHOST vhostName BytesPerSecond

Apply limit on allowed max bytes per second in alarm only mode for specified vhost. The specific limit takes priority over the default limit for any vhost.

#### LIMIT DATA_RATE DEFAULT numberOfConnections

Apply limit on allowed max bytes per second for all the vhosts. So the data limit is enforced by counting the number of bytes read from the socket during each read operation, and pausing for one second before starting a read operation if the in-coming client connection violates the data.

#### LIMIT DATA_RATE VHOST vhostName numberOfConnections
Apply limit on allowed max bytes per second for specified vhost. The specific limit takes priority over the default limit for any vhost.

#### LIMIT DISABLE CONN_RATE_ALARM DEFAULT numberOfConnections

Remove default connection rate limit (allowed average number of connections per second) in alarm only mode for all the vhosts.
Expand All @@ -149,6 +165,14 @@ Remove default connection rate limit (allowed average number of connections per

Remove specific connection rate limit (allowed average number of connections per second) for the specified vhost. The default limit will be applied to the specified vhost, if the default limit is already configured.

#### LIMIT DISABLE DATA_RATE_ALARM DEFAULT numberOfConnections

Remove default data rate limit (allowed max bytes per second) in alarm only mode for all the vhosts.

#### LIMIT DISABLE DATA_RATE VHOST vhostName numberOfConnections

Remove specific data rate limit (allowed max bytes per second) for the specified vhost. The default data limit will be applied to the specified vhost, if the default data limit is already configured.

#### LIMIT PRINT [vhostName]

Print the configured limits in details for the specified vhost. If the vhostName is not specified, then the command will print all the configured default limits.
Expand Down
132 changes: 89 additions & 43 deletions libamqpprox/amqpprox_limitcontrolcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <amqpprox_server.h>
#include <amqpprox_session.h>

#include <limits>
#include <optional>
#include <sstream>
#include <string>
Expand Down Expand Up @@ -246,68 +247,109 @@ void handleDataRateLimit(
void printVhostLimits(
const std::string &vhostName,
ConnectionLimiterManager *connectionLimiterManager,
DataRateLimitManager *dataRateLimitManager,
ControlCommandOutput<ControlCommand::OutputFunctor> &output)
{
auto alarmLimiter =
bool anyConfiguredLimit = false;

auto alarmConnRateLimiter =
connectionLimiterManager->getAlarmOnlyConnectionRateLimiter(vhostName);
if (alarmLimiter) {
if (alarmConnRateLimiter) {
output << "Alarm only limit, for vhost " << vhostName << ", "
<< alarmLimiter->toString() << ".\n";
<< alarmConnRateLimiter->toString() << ".\n";
anyConfiguredLimit = true;
}

auto limiter =
else {
std::optional<uint32_t> alarmConnRateLimit =
connectionLimiterManager->getAlarmOnlyDefaultConnectionRateLimit();
if (alarmConnRateLimit) {
output << "Alarm only limit, for vhost " << vhostName
<< ", allow average " << *alarmConnRateLimit
<< " number of connections per second.\n";
anyConfiguredLimit = true;
}
}
auto connRateLimiter =
connectionLimiterManager->getConnectionRateLimiter(vhostName);
if (limiter) {
output << "For vhost " << vhostName << ", " << limiter->toString()
<< ".\n";
if (connRateLimiter) {
output << "For vhost " << vhostName << ", "
<< connRateLimiter->toString() << ".\n";
anyConfiguredLimit = true;
}

if (!alarmLimiter && !limiter) {
std::optional<uint32_t> alarmOnlyConnectionRateLimit =
connectionLimiterManager->getAlarmOnlyDefaultConnectionRateLimit();
std::optional<uint32_t> connectionRateLimit =
else {
std::optional<uint32_t> connRateLimit =
connectionLimiterManager->getDefaultConnectionRateLimit();
if (alarmOnlyConnectionRateLimit || connectionRateLimit) {
if (alarmOnlyConnectionRateLimit) {
output << "Alarm only limit, for vhost " << vhostName
<< ", allow average " << *alarmOnlyConnectionRateLimit
<< " number of connections per second.\n";
}
if (connectionRateLimit) {
output << "For vhost " << vhostName << ", allow average "
<< *connectionRateLimit
<< " number of connections per second.\n";
}
}
else {
output << "No default connection rate limit configured "
"for any vhost.\n";
if (connRateLimit) {
output << "For vhost " << vhostName << ", allow average "
<< *connRateLimit << " number of connections per second.\n";
anyConfiguredLimit = true;
}
}

std::size_t alarmDataRateLimit =
dataRateLimitManager->getDataRateAlarm(vhostName);
if (alarmDataRateLimit != std::numeric_limits<std::size_t>::max()) {
output << "Alarm only data limit, for vhost " << vhostName
<< ", allow max " << alarmDataRateLimit
<< " bytes per second.\n";
anyConfiguredLimit = true;
}

std::size_t dataRateLimit =
dataRateLimitManager->getDataRateLimit(vhostName);
if (dataRateLimit != std::numeric_limits<std::size_t>::max()) {
output << "For vhost " << vhostName << ", allow max " << dataRateLimit
<< " bytes per second.\n";
anyConfiguredLimit = true;
}

if (!anyConfiguredLimit) {
output << "No limit configured for vhost " << vhostName << ".\n";
}
}

void printAllLimits(
ConnectionLimiterManager *connectionLimiterManager,
DataRateLimitManager *dataRateLimitManager,
ControlCommandOutput<ControlCommand::OutputFunctor> &output)
{
std::optional<uint32_t> alarmOnlyConnectionRateLimit =
connectionLimiterManager->getAlarmOnlyDefaultConnectionRateLimit();
std::optional<uint32_t> connectionRateLimit =
connectionLimiterManager->getDefaultConnectionRateLimit();
if (alarmOnlyConnectionRateLimit || connectionRateLimit) {
if (alarmOnlyConnectionRateLimit) {
output << "Default limit for any vhost, allow average "
<< *alarmOnlyConnectionRateLimit
<< " connections per second in alarm only mode.\n";
}
if (connectionRateLimit) {
output << "Default limit for any vhost, allow average "
<< *connectionRateLimit << " connections per second.\n";
}

std::size_t alarmOnlyDataRateLimit =
dataRateLimitManager->getDefaultDataRateAlarm();
std::size_t dataRateLimit =
dataRateLimitManager->getDefaultDataRateLimit();

bool anyConfiguredLimit = false;
if (alarmOnlyConnectionRateLimit) {
output << "Default limit for any vhost, allow average "
<< *alarmOnlyConnectionRateLimit
<< " connections per second in alarm only mode.\n";
anyConfiguredLimit = true;
}
else {
output << "No default connection rate limit configured "
"for any vhost.\n";
if (connectionRateLimit) {
output << "Default limit for any vhost, allow average "
<< *connectionRateLimit << " connections per second.\n";
anyConfiguredLimit = true;
}

if (alarmOnlyDataRateLimit != std::numeric_limits<std::size_t>::max()) {
output << "Default data limit for any vhost, allow max "
<< alarmOnlyDataRateLimit
<< " bytes per second in alarm only mode.\n";
anyConfiguredLimit = true;
}
if (dataRateLimit != std::numeric_limits<std::size_t>::max()) {
output << "Default data limit for any vhost, allow max "
<< dataRateLimit << " bytes per second.\n";
anyConfiguredLimit = true;
}

if (!anyConfiguredLimit) {
output << "No default limit configured for any vhost.\n";
}
}

Expand Down Expand Up @@ -389,10 +431,14 @@ void LimitControlCommand::handleCommand(const std::string & /* command */,
if (subcommand == "PRINT") {
std::string vhostName;
if (iss >> vhostName) {
printVhostLimits(vhostName, d_connectionLimiterManager_p, output);
printVhostLimits(vhostName,
d_connectionLimiterManager_p,
d_dataRateLimitManager,
output);
}
else {
printAllLimits(d_connectionLimiterManager_p, output);
printAllLimits(
d_connectionLimiterManager_p, d_dataRateLimitManager, output);
}
return;
}
Expand Down

0 comments on commit 376179d

Please sign in to comment.