From 75fbcc9393ee2ee9aee9e756dc0151a45d3923c5 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Mon, 29 Apr 2019 12:06:53 +0300 Subject: [PATCH] MXS-2329 Use durations in log_throttling --- .../Getting-Started/Configuration-Guide.md | 15 ++-- server/core/config.cc | 71 +++++++++++++++++-- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 0af6e5886..ca221a8cd 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -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. diff --git a/server/core/config.cc b/server/core/config.cc index b7e89949e..6db0e4ac5 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -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) {