From f2304f5b88e5b24de26c1414c69f96bc32dd2939 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Fri, 7 Nov 2025 20:05:42 +0100 Subject: [PATCH 1/2] Add "Lua time recordings" to web performancebrowser --- .../performancebrowser/performancebrowser.lua | 48 +++++++++++++++++++ [web]/performancebrowser/target.lua | 34 +++++++++++++ [web]/performancebrowser/viewer.lua | 3 ++ 3 files changed, 85 insertions(+) diff --git a/[web]/performancebrowser/performancebrowser.lua b/[web]/performancebrowser/performancebrowser.lua index 15011051a..2161a37eb 100644 --- a/[web]/performancebrowser/performancebrowser.lua +++ b/[web]/performancebrowser/performancebrowser.lua @@ -4,8 +4,56 @@ -- -- +-- Lua time recordings config +g_LuaTimingRecordings = { + Enabled = true, + Frequency = 2000, -- in milliseconds + HistoryLength = 300, -- number of records to keep + HighCPUResourcesAmount = 10, -- percentage threshold +} + +-- Global variable to store high usage resources similar to IPB +g_HighUsageResources = {} + -- Browser update function setQuery ( counter, user, target, category, options, filter, showClients ) local viewer = getViewer(user) return viewer:setQuery ( counter, target, category, options, filter, showClients ) end + +-- Date/time formatting function +local function getDateTimeString() + local time = getRealTime() + local weekday = ({"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"})[time.weekday + 1] + -- Weekday, DD.MM.YYYY, hh:mm:ss + return ("%s, %02d.%02d.%d, %02d:%02d:%02d"):format(weekday, time.monthday, time.month + 1, time.year + 1900, time.hour, time.minute, time.second) +end + +-- Save high CPU resources function (based on IPB alarm.lua) +function saveHighCPUResources() + local columns, rows = getPerformanceStats("Lua timing") + + if not rows then + return + end + + for index, row in pairs(rows) do + local usageText = row[2]:gsub("[^0-9%.]", "") + local usage = math.floor(tonumber(usageText) or 0) + + if (usage > g_LuaTimingRecordings.HighCPUResourcesAmount) then + -- Record this high usage to table + table.insert(g_HighUsageResources, 1, {row[1], row[2], getDateTimeString()}) + + -- Make sure it won't get too big + if #g_HighUsageResources > g_LuaTimingRecordings.HistoryLength then + table.remove(g_HighUsageResources, g_LuaTimingRecordings.HistoryLength) + end + end + end +end + +-- Start monitoring timer +if (g_LuaTimingRecordings.Enabled) then + setTimer(saveHighCPUResources, g_LuaTimingRecordings.Frequency, 0) +end \ No newline at end of file diff --git a/[web]/performancebrowser/target.lua b/[web]/performancebrowser/target.lua index 0d0ebae6e..389f3932a 100644 --- a/[web]/performancebrowser/target.lua +++ b/[web]/performancebrowser/target.lua @@ -69,6 +69,11 @@ end -- --------------------------------------------------------------------------- function Target:getPerformanceStats( username, queryCategoryName, queryOptionsText, queryFilterText ) + -- Handle our custom Lua time recordings category + if queryCategoryName == "Lua time recordings" then + return self:getLuaTimingRecordings( queryFilterText ) + end + if self.bIsServer then local a, b = getPerformanceStats ( queryCategoryName, queryOptionsText, queryFilterText ) return a, b, true @@ -155,3 +160,32 @@ addEventHandler('onNotifyStats', resourceRoot, end ) +--------------------------------------------------------------------------- +-- +-- Target:getLuaTimingRecordings() +-- +-- Get recorded high usage Lua timing data +-- +--------------------------------------------------------------------------- +function Target:getLuaTimingRecordings( queryFilterText ) + local columns = {"Resource", "CPU Usage", "Recorded Time"} + local rows = {} + + -- Get the global high usage resources if it exists + if g_HighUsageResources then + for i, recording in ipairs(g_HighUsageResources) do + local resourceName = recording[1] + local cpuUsage = recording[2] + local recordedTime = recording[3] + + -- Apply filter if specified + if not queryFilterText or queryFilterText == "" or + string.find(string.lower(resourceName), string.lower(queryFilterText), 1, true) then + table.insert(rows, {resourceName, cpuUsage, recordedTime}) + end + end + end + + return columns, rows, true +end + diff --git a/[web]/performancebrowser/viewer.lua b/[web]/performancebrowser/viewer.lua index d92f1dcb9..79cb9c563 100644 --- a/[web]/performancebrowser/viewer.lua +++ b/[web]/performancebrowser/viewer.lua @@ -155,6 +155,9 @@ function Viewer:getCategoriesRaw () local categories = {} for _,row in ipairs(rowList) do table.insert( categories, row[1] ) + if ( row[1] == "Lua timing" ) then -- Add our custom Lua time recordings category + table.insert( categories, "Lua time recordings" ) + end end return categories end From 54cce536d357d4e43b34227e67af35246febf7e6 Mon Sep 17 00:00:00 2001 From: Xenius97 Date: Fri, 7 Nov 2025 20:13:20 +0100 Subject: [PATCH 2/2] Fix lint issue --- [web]/performancebrowser/target.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/[web]/performancebrowser/target.lua b/[web]/performancebrowser/target.lua index 389f3932a..c715289f2 100644 --- a/[web]/performancebrowser/target.lua +++ b/[web]/performancebrowser/target.lua @@ -179,8 +179,7 @@ function Target:getLuaTimingRecordings( queryFilterText ) local recordedTime = recording[3] -- Apply filter if specified - if not queryFilterText or queryFilterText == "" or - string.find(string.lower(resourceName), string.lower(queryFilterText), 1, true) then + if not queryFilterText or queryFilterText == "" or string.find(string.lower(resourceName), string.lower(queryFilterText), 1, true) then table.insert(rows, {resourceName, cpuUsage, recordedTime}) end end