]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Show dynamic rates and bursts for ratelimit buckets
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 10 Apr 2018 12:17:57 +0000 (13:17 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 10 Apr 2018 12:55:35 +0000 (13:55 +0100)
src/plugins/lua/ratelimit.lua

index 2b6989e1a9c188f6d708898ebe528aa775ba0ac1..8e00aa342680ceb41ff956477a766be4fd4d10fc 100644 (file)
@@ -56,6 +56,7 @@ local settings = {
 local bucket_check_script = [[
   local last = redis.call('HGET', KEYS[1], 'l')
   local now = tonumber(KEYS[2])
+  local dynr, dynb = 0, 0
   if not last then
     -- New bucket
     redis.call('HSET', KEYS[1], 'l', KEYS[2])
@@ -72,22 +73,23 @@ local bucket_check_script = [[
   if burst > 0 then
    if last < tonumber(KEYS[2]) then
     local rate = tonumber(KEYS[3])
-    local dyn = tonumber(redis.call('HGET', KEYS[1], 'dr')) / 10000.0
-    rate = rate * dyn
+    dynr = tonumber(redis.call('HGET', KEYS[1], 'dr')) / 10000.0
+    rate = rate * dynr
     local leaked = ((now - last) * rate)
     burst = burst - leaked
     redis.call('HINCRBYFLOAT', KEYS[1], 'b', -(leaked))
    end
-   local dyn = tonumber(redis.call('HGET', KEYS[1], 'db')) / 10000.0
+   dynb = tonumber(redis.call('HGET', KEYS[1], 'db')) / 10000.0
 
-   if burst * dyn > tonumber(KEYS[4]) then
-    return 1
+   if burst * dynb > tonumber(KEYS[4]) then
+    return {1, burst, dynr, dynb}
    end
   else
+    burst = 0
     redis.call('HSET', KEYS[1], 'b', '0')
   end
 
-  return 0
+  return {0, burst, dynr, dynb}
 ]]
 local bucket_check_id
 
@@ -115,7 +117,7 @@ local bucket_update_script = [[
     redis.call('HSET', KEYS[1], 'dr', '10000')
     redis.call('HSET', KEYS[1], 'db', '10000')
     redis.call('EXPIRE', KEYS[1], KEYS[7])
-    return
+    return {1, 1, 1}
   end
 
   local burst = tonumber(redis.call('HGET', KEYS[1], 'b'))
@@ -135,6 +137,8 @@ local bucket_update_script = [[
   redis.call('HINCRBYFLOAT', KEYS[1], 'b', 1)
   redis.call('HSET', KEYS[1], 'l', KEYS[2])
   redis.call('EXPIRE', KEYS[1], KEYS[7])
+
+  return {burst, dr, db}
 ]]
 local bucket_update_id
 
@@ -368,13 +372,13 @@ local function ratelimit_cb(task)
       if err then
         rspamd_logger.errx('cannot check limit %s: %s %s', prefix, err, data)
       end
-      if data and data == 1 then
+      if data and data[1] and data[1] == 1 then
         if settings.info_symbol then
           task:insert_result(settings.info_symbol, 1.0, prefix)
         end
         rspamd_logger.infox(task,
-                'ratelimit "%s(%s)" exceeded, (%s / %s)',
-                lim_name, prefix, bucket[2], bucket[1])
+                'ratelimit "%s(%s)" exceeded, (%s / %s): %s (%s:%s dyn)',
+                lim_name, prefix, bucket[2], bucket[1], data[2], data[3], data[4])
         task:set_pre_result('soft reject',
                 message_func(task, lim_name, prefix, bucket))
       end
@@ -428,16 +432,19 @@ local function ratelimit_update_cb(task)
     -- Update each bucket
     for k, v in pairs(prefixes) do
       local bucket = v.bucket
-      local function update_bucket_cb(err, _)
+      local function update_bucket_cb(err, data)
         if err then
           rspamd_logger.errx(task, 'cannot update rate bucket %s: %s',
-              k, err)
+                  k, err)
+        else
+          rspamd_logger.debugm(N, task,
+                  "updated limit %s:%s (%s/%s), burst: %s, dyn_rate: %s, dyn_burst: %s",
+                  v.name, k, bucket[2], bucket[1], data[1], data[2], data[3])
         end
       end
       local now = rspamd_util.get_time()
       now = lua_util.round(now * 1000.0) -- Get milliseconds
-      rspamd_logger.debugm(N, task, "update limit %s:%s (%s/%s)",
-              v.name, k, bucket[2], bucket[1])
+
       lua_redis.exec_redis_script(bucket_update_id,
               {task = task, is_write = true},
               update_bucket_cb,