From 8bae1a7629f95f394887f1d4b63d72e0ef0efcc6 Mon Sep 17 00:00:00 2001 From: hbeni Date: Tue, 19 Mar 2024 20:29:15 +0100 Subject: [PATCH] Server/Statusbot: add config options and chat commands New startup config option --purge to be able to adjust the purge interval of stale entries New support for chat commands to change the purge interval in realtime Fix #181 --- server/statuspage/config.dist.ini | 9 +- server/statuspage/fgcom-status.bot.lua | 112 ++++++++++++++++++++++--- 2 files changed, 107 insertions(+), 14 deletions(-) diff --git a/server/statuspage/config.dist.ini b/server/statuspage/config.dist.ini index 9f6613b5..7606a755 100644 --- a/server/statuspage/config.dist.ini +++ b/server/statuspage/config.dist.ini @@ -5,8 +5,8 @@ ; [json-database] -; path to database file -file="/tmp/fgcom-web.db" +; path to database file (provided by the statusbot) +file="/tmp/fgcom-web.db" [ui] @@ -19,7 +19,10 @@ db_stale=15 ; after this many seconds, stale entries will be marked as such mark_stale_entries=30 -; after this many seconds, stale entries will not be displayed anymore +; after this many seconds, stale entries will not be displayed anymore. +; NOTE: this value should be equal or less the --purge parameter of the statusbot, +; you cannot exceed the bots db purge setting (purged stale entries are not visible +; to the statuspage, so cannot be displayed). hide_stale_entries=60 ; Show link to usage statistics. diff --git a/server/statuspage/fgcom-status.bot.lua b/server/statuspage/fgcom-status.bot.lua index 210bdc5b..a6edcfde 100644 --- a/server/statuspage/fgcom-status.bot.lua +++ b/server/statuspage/fgcom-status.bot.lua @@ -37,7 +37,7 @@ Installation of this plugin is described in the projects readme: https://github. ]] dofile("sharedFunctions.inc.lua") -- include shared functions -fgcom.botversion = "1.8.2" +fgcom.botversion = "1.9.0" json = require("dkjson") local botname = "FGCOM-Status" fgcom.callsign = "FGCOM-Status" @@ -52,6 +52,7 @@ local speed = 5 -- update interval in seconds local weburl = "" local stats = "" local speedStats = 60 -- write interval for statistic entries in seconds +local stalepurge = 60 -- clean out stale entries after this seconds if arg[1] then @@ -59,7 +60,7 @@ if arg[1] then print(botname..", "..fgcom.getVersion()) print("usage: "..arg[0].." [opt=val ...]") print(" Options:") - print(" --name= Change Bot's name (default="..botname..")") + print(" --name= Change Bot's name (default="..fgcom.callsign..")") print(" --host= host to connect to (default="..host..")") print(" --port= port to connect to (default="..port..")") print(" --channel= channel to join (default="..fgcom.channel..")") @@ -70,6 +71,7 @@ if arg[1] then print(" --web= Advertise url in comment (default=no commercials!)") print(" --stats= append usage stats to this file (default=no)") print(" --speedst= usage stats update interval (seconds, default="..speedStats..")") + print(" --purge= stale entries retention time (seconds, default="..stalepurge..")") print(" --debug print debug messages (default=no)") print(" --version print version and exit") os.exit(0) @@ -78,7 +80,7 @@ if arg[1] then for _, opt in ipairs(arg) do _, _, k, v = string.find(opt, "--(%w+)=(.+)") --print("KEY='"..k.."'; VAL='"..v.."'") - if k=="name" then botname=v end + if k=="name" then fgcom.callsign=v end if k=="host" then host=v end if k=="port" then port=v end if k=="channel" then fgcom.channel=v end @@ -89,6 +91,7 @@ if arg[1] then if k=="speedst" then speedStats=v end if k=="web" then weburl=v end if k=="stats" then stats=v end + if k=="purge" then stalepurge=v end if opt == "--debug" then fgcom.debugMode = true end if opt == "--version" then print(botname..", "..fgcom.getVersion()) os.exit(0) end end @@ -98,7 +101,7 @@ end -- Connect to server, so we get the API fgcom.log(botname..": connecting as '"..fgcom.callsign.."' to "..host.." on port "..port.." (cert: "..cert.."; key: "..key.."), joining: '"..fgcom.channel.."'") local client = assert(mumble.connect(host, port, cert, key)) -client:auth(botname) +client:auth(fgcom.callsign) fgcom.log("connect and bind: OK") @@ -187,6 +190,15 @@ local generateOutData = function() return dataJsonString end +-- function to disconnect the bot +shutdownBot = function() + fgcom.log("shutdownBot(): requested") + + -- finally disconnect from the server + client:disconnect() + fgcom.log("shutdownBot(): disconnected") + os.exit(0) +end -- function to get all channel users -- this updates the global playback_target table @@ -231,7 +243,7 @@ dbUpdateTimer_func = function(t) -- clean up stale entries fgcom.data.cleanupTimeout = 60 -- enhance timeout, so we can display them longer fgcom.data.cleanupPluginData() - + else fgcom.log("ERROR: unable to open db: "..tmpdb) -- lets try again in the next iteration.... os.exit(1) @@ -239,7 +251,6 @@ dbUpdateTimer_func = function(t) end - -- Timed loop to write usage statistics file -- The data is intendet to be compatible to gnuplot: " " for each line local statsWriterTimer = mumble.timer() @@ -298,6 +309,9 @@ client:hook("OnServerSync", function(client, event) event.user:move(ch) fgcom.log("joined channel "..fgcom.channel) + -- Establish authentication token + fgcom.auth.generateToken(nil) + -- Adjust comment if weburl:len() > 0 then fgcom.log("Advetising web url: "..weburl) @@ -315,8 +329,9 @@ client:hook("OnServerSync", function(client, event) -- start statistics collection if stats:len() > 0 then fgcom.log("Writing statistics to: "..stats) - statsWriterTimer:start(statsWriterTimer_func, 60, speedStats) + statsWriterTimer:start(statsWriterTimer_func, speedStats, speedStats) end + end) @@ -355,6 +370,8 @@ client:hook("OnMessage", function(client, event) --print("DBG: parsed command: command="..command) --if param then print("DBG: param="..param) end + local paramTimeSafeGuard = 5 -- do not allow update intervals below this + -- handle auth request if command == "auth" then if not param then event.actor:message("/auth needs a tokenstring as argument!") return end @@ -366,10 +383,13 @@ client:hook("OnMessage", function(client, event) event.actor:message(botname..", "..fgcom.getVersion().." commands:" .."" .."" - --.."" - --.."" + .."" + .."" + .."" + .."" + .."" + .."" .."
/helpshow this help.
/auth <token>Authenticate to be able to execute advanced commands.
/exitTerminate the bot.
/auth <token>Authenticate to be able to execute advanced commands.
/exitTerminate the bot.
/infoShow some configuration values.
/speed <secs>Change db update interval.
/purge <secs>Retention time for stale entries (Note, the purge is bound to the --speed interval)
/speedst <secs>Change usage statistics update interval.
" - .."
I do not obey to chat commands so far." ) return end @@ -380,7 +400,76 @@ client:hook("OnMessage", function(client, event) return end - -- no commands so far + if command == "exit" then + fgcom.dbg("exit command received") + event.actor:message("goodbye!") + shutdownBot() + end + + if command == "info" then + local stats_txt = "off"; + if stats:len() then stats_txt = stats end + event.actor:message("Info:" + .."" + .."" + .."" + .."" + .."" + .."" + .."" + .."
Version"..fgcom.getVersion().."
--db"..db.."
--speed"..speed.."
--purge"..stalepurge.." (Note, the purge is bound to the --speed interval)
--stats"..stats_txt.."
--speedst"..speedStats.."
" + ) + return + end + + if command == "speed" then + if not param then event.actor:message("/speed needs a number as argument!") return end + _, _, f = string.find(param, "([%d]+)") + if not f then event.actor:message("/speed param is not an integer!") return end + f = tonumber(f) + if f < paramTimeSafeGuard then event.actor:message("/speed must be >= "..paramTimeSafeGuard.."!") return end + local m = "DB update interval is now: "..f.." Seconds (was "..speed..")" + fgcom.log(m) + event.actor:message(m) + speed = f + dbUpdateTimer:stop() + dbUpdateTimer:start(dbUpdateTimer_func, 0.0, speed) + return + end + + if command == "purge" then + if not param then event.actor:message("/purge needs a number as argument!") return end + _, _, f = string.find(param, "([%d]+)") + if not f then event.actor:message("/purge param is not an integer!") return end + f = tonumber(f) + if f < paramTimeSafeGuard then event.actor:message("/purge must be >= "..paramTimeSafeGuard.."!") return end + if f < speed then event.actor:message("/purge must be bigger than --speed ("..speed..")!") return end + local m = "Stale entries retention time is now: "..f.." Seconds (was "..purge..")" + fgcom.log(m) + event.actor:message(m) + purge = f + return + end + + if command == "speedst" then + if stats:len() > 0 then + -- currently only to be turned on at startup for safety reasons (filesystem access!) + if not param then event.actor:message("/speedst needs a number as argument!") return end + _, _, f = string.find(param, "([%d]+)") + if not f then event.actor:message("/speedst param is not an integer!") return end + f = tonumber(f) + if f < paramTimeSafeGuard then event.actor:message("/speedst must be >= "..paramTimeSafeGuard.."!") return end + local m = "Usage statistics update interval is now: "..f.." Seconds (was "..speedStats..")" + fgcom.log(m) + event.actor:message(m) + speedStats = f + statsWriterTimer:stop() + statsWriterTimer:start(statsWriterTimer_func, 0.0, speedStats) + else + event.actor:message("Usage statistics collection is disabled, not changing update interval") + end + return + end end @@ -388,4 +477,5 @@ client:hook("OnMessage", function(client, event) end) +-- Finally start the bot mumble.loop()