view mod_pinger/mod_pinger.lua @ 5668:ecfd7aece33b

mod_measure_modules: Report module statuses via OpenMetrics Someone in the chat asked about a health check endpoint, which reminded me of mod_http_status, which provides access to module statuses with full details. After that, this idea came about, which seems natural. As noted in the README, it could be used to monitor that critical modules are in fact loaded correctly. As more modules use the status API, the more useful this module and mod_http_status becomes.
author Kim Alvefur <zash@zash.se>
date Fri, 06 Oct 2023 18:34:39 +0200
parents 8298b06e6603
children
line wrap: on
line source

local new_watchdog = require "util.watchdog".new;
local filters = require "util.filters";
local st = require "util.stanza";

local idle_timeout = module:get_option_number("c2s_idle_timeout", 300);
local ping_timeout = module:get_option_number("c2s_ping_timeout",  30);

function update_watchdog(data, session)
	if session.idle_watchdog then
		session.idle_watchdog:reset();
		session.idle_pinged = nil;
	end
	return data;
end

function check_session(watchdog)
	local session = watchdog.session;
	if session.smacks then
		unwatch_session(session);
		return;
	end
	if not session.idle_pinged then
		session.idle_pinged = true;
		session.send(st.iq({ type = "get", from = module.host, id = "idle-check" })
				:tag("ping", { xmlns = "urn:xmpp:ping" }));
		return ping_timeout; -- Call us again after ping_timeout
	else
		module:log("info", "Client %q silent for too long, closing...", session.full_jid);
		session:close("connection-timeout");
	end
end


function watch_session(session)
	if not session.idle_watchdog
	and not session.requests then -- Don't watch BOSH connections (BOSH already has timeouts)
		session.idle_watchdog = new_watchdog(idle_timeout, check_session);
		session.idle_watchdog.session = session;
		filters.add_filter(session, "bytes/in", update_watchdog);
	end
end

function unwatch_session(session)
	if session.idle_watchdog then
		filters.remove_filter(session, "bytes/in", update_watchdog);
		session.idle_watchdog:cancel();
		session.idle_watchdog = nil;
	end
end

module:hook("resource-bind", function (event) watch_session(event.session); end);
module:hook("resource-unbind", function (event) unwatch_session(event.session); end);