Last active
May 15, 2023 17:21
-
-
Save zwim/9896498977c8eeb679b516059e752de7 to your computer and use it in GitHub Desktop.
KOReader user patch, to limit the crash.log's filesize during run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- A KOReader patch for limiting the crash.log file size during run (and not only on KOReader start) | |
-- The menu entry can be found in Filemanager: Settings > More tools > Developer options > Limit log file size | |
-- Version 0.2 | |
-- Kobo os.execute("truncate") is not available -> os.execute("busybox truncate") | |
-- Version 0.3 | |
-- onSuspend and onResume work now | |
-- Version 0.4 | |
-- unschedule tasks in onClose | |
-- Version 0.5 | |
-- don't use onClose, but onExit (unschedule and close) | |
local FFIUtil = require("ffi/util") | |
local UIManager = require("ui/uimanager") | |
local _ = require("gettext") | |
local T = FFIUtil.template | |
local WidgetContainer = require("ui/widget/container/widgetcontainer") | |
local datetime = require("datetime") | |
local lfs = require("libs/libkoreader-lfs") | |
local logger = require("logger") | |
local util = require("util") | |
local truncate_cmd | |
if os.execute("which truncate") == 0 then | |
truncate_cmd = "truncate -s 0 crash.log" | |
elseif os.execute("busybox truncate --help") == 0 then | |
truncate_cmd = "busybox truncate -s 0 crash.log" | |
else | |
logger.dbg("Crashlog: truncate command not found!") | |
return | |
end | |
local function crashlog_exists() | |
return lfs.attributes("crash.log", "mode") == "file" | |
end | |
if not crashlog_exists() then | |
logger.dbg("Crashlog: crash.log does not exist on this device.") | |
return | |
end | |
--- crash.log handling --- | |
local CRASHLOG_MAXSIZE = 500000 -- 500000 is the maximum filesize in koreader.sh startup | |
local CRASHLOG_OVERCOMMIT_FACTOR = 2.5 -- factor the file size can be overcomitted, before trimming should happen during KOReader running | |
local MINIMAL_TRIM_INTERVAL_S = 5*60 -- should be at least > a few minutes | |
local CrashLog = WidgetContainer:extend{ | |
name = "limit_crashlog", | |
} | |
function CrashLog:init() | |
self:maybeSchedule() | |
end | |
function CrashLog:exists() | |
return crashlog_exists() | |
end | |
function CrashLog:size() | |
return lfs.attributes("crash.log", "size") | |
end | |
--- Trim the crash.log file | |
function CrashLog:trim() | |
if not CrashLog.exists() then | |
return | |
end | |
local crashlog_size = CrashLog:size() | |
logger.dbg("Crashlog: original filesize", util.getFriendlySize(crashlog_size)) | |
if crashlog_size > CRASHLOG_MAXSIZE * CRASHLOG_OVERCOMMIT_FACTOR then | |
if os.execute("tail -c 500000 crash.log > crash.log.tail ") ~= 0 then return end | |
if os.execute(truncate_cmd) ~= 0 then return end | |
if os.execute("echo '... trimmed ...' >> crash.log") ~= 0 then return end | |
if os.execute("cat crash.log.tail >> crash.log") ~= 0 then return end | |
if os.execute("rm crash.log.tail") ~= 0 then return end | |
if os.execute("sync") ~= 0 then return end | |
logger.dbg("Crashlog: trimmed filesize", util.getFriendlySize(CrashLog:size())) | |
end | |
end | |
--- Trim the logfile and schedule the next trim if necessary | |
-- @number time_s if >= MINIMA_TRIM_INTERVAL_S then trim and schedule, else unschedule | |
function CrashLog:maybeSchedule(time_s) | |
local schedule_time_s = time_s or G_reader_settings:readSetting("crashlog_autotrim_time_s", -1) | |
if schedule_time_s >= MINIMAL_TRIM_INTERVAL_S then -- don't schedule, when time is within a minute | |
self:trim() | |
UIManager:scheduleIn(schedule_time_s, self.maybeSchedule, self) | |
else | |
UIManager:unschedule(self.maybeSchedule) | |
end | |
end | |
function CrashLog:onSuspend() | |
logger.dbg("Crashlog: onSuspend") | |
if G_reader_settings:readSetting("crashlog_autotrim_time_s", -1) >= 0 then | |
self:trim() | |
self:maybeSchedule(0) | |
end | |
end | |
function CrashLog:onResume() | |
logger.dbg("Crashlog: onResume") | |
self:maybeSchedule() | |
end | |
function CrashLog:onExit() | |
logger.dbg("Crashlog: onExit") | |
UIManager:unschedule(self.maybeSchedule) | |
UIManager:close(self) | |
end | |
--- monkey patch the developer menu --- | |
local FileManagerMenu = require("apps/filemanager/filemanagermenu") | |
local setUpdateItemTable_orig = FileManagerMenu.setUpdateItemTable | |
FileManagerMenu.setUpdateItemTable = function(self) | |
setUpdateItemTable_orig(self) | |
local function find_table(table, id) | |
for i, v in pairs(table) do | |
if v.id == id then | |
return v, true | |
end | |
end | |
end | |
local table_to_insert, found = find_table(self.tab_item_table, "tools") | |
if not found then return end | |
table_to_insert, found = find_table(table_to_insert, "more_tools") | |
if not found then return end | |
table_to_insert, found = find_table(table_to_insert.sub_item_table, "developer_options") | |
if not found then return end | |
table.insert(table_to_insert.sub_item_table, { | |
text_func = function() | |
local crashlog_autotrim_time_s = G_reader_settings:readSetting("crashlog_autotrim_time_s", -1) | |
local size = util.getFriendlySize(CrashLog:size()) | |
if crashlog_autotrim_time_s < 0 then | |
return T(_("Limit log file size (%1)"), size) | |
elseif crashlog_autotrim_time_s == 0 then | |
return T(_("Limit log file size (%1, %2)"), size, "only on suspend") | |
else | |
local time_string = datetime.secondsToClockDuration("letters", crashlog_autotrim_time_s, true, true, true) | |
return T(_("Limit log file size (%1, %2)"), size, time_string) | |
end | |
end, | |
enabled_func = function() | |
return CrashLog:exists() | |
end, | |
checked_func = function() | |
return G_reader_settings:readSetting("crashlog_autotrim_time_s", -1) >= 0 | |
end, | |
callback = function() | |
local crashlog_autotrim_time_s = G_reader_settings:readSetting("crashlog_autotrim_time_s") | |
local time_table_s = {6*3600, 3600, 30*60, 15*60, 0, -1} | |
if crashlog_autotrim_time_s >= time_table_s[1] then | |
crashlog_autotrim_time_s = -1 | |
else | |
for i = 2, #time_table_s do | |
if crashlog_autotrim_time_s >= time_table_s[i] then | |
crashlog_autotrim_time_s = time_table_s[i-1] | |
break | |
end | |
end | |
end | |
G_reader_settings:saveSetting("crashlog_autotrim_time_s", crashlog_autotrim_time_s) | |
CrashLog:maybeSchedule() | |
end, | |
keep_menu_open = true, | |
}) | |
end | |
--- initialisations | |
UIManager:show(CrashLog:new()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CHANGELOG
Version 0.5
don't use onClose, but onExit (unschedule and close)
Version 0.4
onSuspend and onResume work now
Version 0.3
unschedule tasks in onClose
Version 0.2
os.execute("truncate")
is not available on Kobo, so check iftruncate
is available, if not try to usebusybox truncate
works on emulator and Kobo
Version 0.1:
initial commit; works on the emulator