123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- --[[
- Copyright (c) 2022, Vsevolod Stakhov <vsevolod@rspamd.com>
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ]]--
-
- if confighelp then
- rspamd_config:add_example(nil, 'maps_stats',
- "Stores maps statistics in Redis", [[
- maps_stats {
- # one iteration step per 2 minutes
- interval = 2m;
- # how many elements to store in Redis
- count = 1k;
- # common prefix for elements
- prefix = 'rm_';
- }
- ]])
- end
-
- local redis_params
- local lua_util = require "lua_util"
- local rspamd_logger = require "rspamd_logger"
- local lua_redis = require "lua_redis"
- local N = "maps_stats"
-
- local settings = {
- interval = 120, -- one iteration step per 2 minutes
- count = 1000, -- how many elements to store in Redis
- prefix = 'rm_', -- common prefix for elements
- }
-
- local function process_map(map, ev_base, _)
- if map:get_nelts() > 0 and map:get_uri() ~= 'static' then
- local key = settings.prefix .. map:get_uri()
-
- local function redis_zrange_cb(err, data)
- if err then
- rspamd_logger.errx(rspamd_config, 'cannot delete extra elements in %s: %s',
- key, err)
- elseif data then
- rspamd_logger.infox(rspamd_config, 'cleared %s elements from %s',
- data, key)
- end
- end
- local function redis_card_cb(err, data)
- if err then
- rspamd_logger.errx(rspamd_config, 'cannot get number of elements in %s: %s',
- key, err)
- elseif data then
- if settings.count > 0 and tonumber(data) > settings.count then
- lua_redis.rspamd_redis_make_request_taskless(ev_base,
- rspamd_config,
- redis_params, -- connect params
- key, -- hash key
- true, -- is write
- redis_zrange_cb, --callback
- 'ZREMRANGEBYRANK', -- command
- {key, '0', tostring(-(settings.count) - 1)} -- arguments
- )
- end
- end
- end
- local ret, conn, _ = lua_redis.rspamd_redis_make_request_taskless(ev_base,
- rspamd_config,
- redis_params, -- connect params
- key, -- hash key
- true, -- is write
- redis_card_cb, --callback
- 'ZCARD', -- command
- {key} -- arguments
- )
-
- if ret and conn then
- local stats = map:get_stats(true)
- for k,s in pairs(stats) do
- if s > 0 then
- conn:add_cmd('ZINCRBY', {key, tostring(s), k})
- end
- end
- end
- end
- end
-
- if not lua_util.check_experimental(N) then
- return
- end
-
- local opts = rspamd_config:get_all_opt(N)
-
- if opts then
- for k,v in pairs(opts) do
- settings[k] = v
- end
- end
-
- redis_params = lua_redis.parse_redis_server(N, opts)
- -- XXX, this is a poor approach as not all maps are defined here...
- local tmaps = rspamd_config:get_maps()
- for _,m in ipairs(tmaps) do
- if m:get_uri() ~= 'static' then
- lua_redis.register_prefix(settings.prefix .. m:get_uri(), N,
- 'Maps stats data', {
- type = 'zlist',
- persistent = true,
- })
- end
- end
-
- if redis_params then
- rspamd_config:add_on_load(function (_, ev_base, worker)
- local maps = rspamd_config:get_maps()
-
- for _,m in ipairs(maps) do
- rspamd_config:add_periodic(ev_base,
- settings['interval'],
- function ()
- process_map(m, ev_base, worker)
- return true
- end, true)
- end
- end)
- end
|