MXS-2329 Use durations in log_throttling

This commit is contained in:
Johan Wikman 2019-04-29 12:06:53 +03:00
parent 9fb4116bf5
commit 75fbcc9393
2 changed files with 75 additions and 11 deletions

View File

@ -586,17 +586,17 @@ a while.
# A valid value looks like
# log_throttling = X, Y, Z
#
# where each value is a positive integer and X means the number of times a
# specific error may be logged within a time period of Y milliseconds, before
# the logging of that error is suppressed for Z milliseconds.
log_throttling=8, 2000, 15000
# where the first value X is a positive integer and means the number of times
# a specific error may be logged within a duration of Y, before the logging
# of that error is suppressed for a duration of Z.
log_throttling=8, 2s, 15000ms
```
In the example above, the logging of a particular error will be suppressed for
15 seconds if the error has been logged 8 times in 2 seconds.
The default is `10, 1000, 10000`, which means that if the same error is logged
10 times in one second, the logging of that error is suppressed for the
The default is `10, 1000ms, 10000ms`, which means that if the same error is
logged 10 times in one second, the logging of that error is suppressed for the
following 10 seconds.
To disable log throttling, add an entry with an empty value
@ -609,6 +609,9 @@ or one where any of the integers is 0.
```
log_throttling=0, 0, 0
```
The durations can be specified as documented [here](#durations). If no explicit
unit is provided, the value is interpreted as milliseconds in MaxScale 2.4. In
subsequent versions a value without a unit may be rejected.
Note that *notice*, *info* and *debug* messages are never throttled.

View File

@ -239,6 +239,14 @@ static pcre2_code* compile_regex_string(const char* regex_string,
static bool duration_is_valid(const char* zValue, mxs::config::DurationUnit* pUnit);
static bool get_seconds(const char* zName, const char* zValue, std::chrono::seconds* pSeconds);
static bool get_seconds(const char* zName, const char* zValue, time_t* pSeconds);
static bool get_milliseconds(const char* zName,
const char* zValue,
const char* zDisplay_value,
std::chrono::milliseconds* pMilliseconds);
static bool get_milliseconds(const char* zName,
const char* zValue,
const char* zDisplay_value,
time_t* pMilliseconds);
int config_get_ifaddr(unsigned char* output);
@ -2536,10 +2544,12 @@ static int handle_global_item(const char* name, const char* value)
else
{
int c = atoi(count);
int w = atoi(window_ms);
int s = atoi(suppress_ms);
time_t w;
time_t s;
if ((c >= 0) && (w >= 0) && (s >= 0))
if (c >= 0
&& get_milliseconds(name, window_ms, value, &w)
&& get_milliseconds(name, suppress_ms, value, &s))
{
MXS_LOG_THROTTLING throttling;
throttling.count = c;
@ -2551,8 +2561,8 @@ static int handle_global_item(const char* name, const char* value)
else
{
MXS_ERROR("Invalid value for the `log_throttling` configuration entry: '%s'. "
"The configuration entry `log_throttling` requires as value three positive "
"integers (or 0).", value);
"The configuration entry `log_throttling` requires as value one zero or "
"positive integer and two durations.", value);
return 0;
}
}
@ -5153,6 +5163,57 @@ static bool get_seconds(const char* zName, const char* zValue, time_t* pSeconds)
return valid;
}
static bool get_milliseconds(const char* zName,
const char* zValue,
const char* zDisplay_value,
std::chrono::milliseconds* pMilliseconds)
{
bool valid = false;
if (!zDisplay_value)
{
zDisplay_value = zValue;
}
mxs::config::DurationUnit unit;
std::chrono::milliseconds milliseconds;
if (get_suffixed_duration(zValue, &milliseconds, &unit))
{
if (unit == mxs::config::DURATION_IN_DEFAULT)
{
MXS_WARNING("Specifying durations without a suffix denoting the unit "
"has been deprecated: %s=%s. Use the suffixes 'h' (hour), "
"'m' (minute) 's' (second) or 'ms' (milliseconds).", zName, zDisplay_value);
}
*pMilliseconds = milliseconds;
valid = true;
}
else
{
MXS_ERROR("Invalid duration %s: %s=%s.", zName, zValue, zDisplay_value);
}
return valid;
}
static bool get_milliseconds(const char* zName,
const char* zValue,
const char* zDisplay_value,
time_t* pMilliseconds)
{
std::chrono::milliseconds milliseconds;
bool valid = get_milliseconds(zName, zValue, zDisplay_value, &milliseconds);
if (valid)
{
*pMilliseconds = milliseconds.count();
}
return valid;
}
bool config_parse_disk_space_threshold(SERVER::DiskSpaceLimits* pDisk_space_threshold,
const char* zDisk_space_threshold)
{