Made filesystem seeking more failsafe and added better log trimming.

- Trying to seek before the start of a file stream now does not cause an
error
- Logs are now trimmed between log entries
This commit is contained in:
2025-09-16 19:36:41 +03:00
parent 894641734f
commit 8b51217324
3 changed files with 638 additions and 622 deletions
+38 -38
View File
@@ -8,8 +8,8 @@ local log = assert(loadfile("/lib/log.lua")(loadfile))
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat repeat
tmpdata = handle:read(math.huge) tmpdata = handle:read(math.huge)
_OSLOGO = _OSLOGO .. (tmpdata or "") _OSLOGO = _OSLOGO .. (tmpdata or "")
until not tmpdata until not tmpdata
handle:close() handle:close()
@@ -20,46 +20,46 @@ _G.package = { ["preloaded"] = {} }
loadfile("/halyde/kernel/modules/datatools.lua")() loadfile("/halyde/kernel/modules/datatools.lua")()
function _G.reqgen(load) function _G.reqgen(load)
return function(module, ...) return function(module, ...)
local args = table.pack(...) local args = table.pack(...)
if package.preloaded[module] then if package.preloaded[module] then
return package.preloaded[module] return package.preloaded[module]
end end
local modulepath local modulepath
if filesystem.exists(module) then if filesystem.exists(module) then
modulepath = module modulepath = module
elseif filesystem.exists("/lib/" .. module .. ".lua") then elseif filesystem.exists("/lib/" .. module .. ".lua") then
modulepath = "/lib/" .. module .. ".lua" modulepath = "/lib/" .. module .. ".lua"
elseif elseif
shell shell
and shell.workingDirectory and shell.workingDirectory
and filesystem.exists(filesystem.concat(shell.workingDirectory, module .. ".lua")) and filesystem.exists(filesystem.concat(shell.workingDirectory, module .. ".lua"))
then then
modulepath = shell.workingDirectory .. module .. ".lua" modulepath = shell.workingDirectory .. module .. ".lua"
end end
assert(modulepath, "Module not found\nPossible locations:\n/lib/" .. module .. ".lua") assert(modulepath, "Module not found\nPossible locations:\n/lib/" .. module .. ".lua")
local handle, data, tmpdata = filesystem.open(modulepath), "", nil local handle, data, tmpdata = filesystem.open(modulepath), "", nil
repeat repeat
tmpdata = handle:read(math.huge or math.maxinteger) tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "") data = data .. (tmpdata or "")
until not tmpdata until not tmpdata
handle:close() handle:close()
return (assert(load(data, "=" .. modulepath))(table.unpack(args))) return (assert(load(data, "=" .. modulepath))(table.unpack(args)))
end end
end end
_G.require = reqgen(_G.load) _G.require = reqgen(_G.load)
log.kernel.info("Generated userland require function") log.kernel.info("Generated userland require function")
function _G.package.preload(module) function _G.package.preload(module)
local handle, data, tmpdata = assert(filesystem.open("/lib/" .. module .. ".lua", "r")), "", nil local handle, data, tmpdata = assert(filesystem.open("/lib/" .. module .. ".lua", "r")), "", nil
repeat repeat
tmpdata = handle:read(math.huge or math.maxinteger) tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "") data = data .. (tmpdata or "")
until not tmpdata until not tmpdata
handle:close() handle:close()
package.preloaded[module] = assert(load(data, "=" .. module))() package.preloaded[module] = assert(load(data, "=" .. module))()
_G[module] = nil _G[module] = nil
end end
-- Datatools is imported twice?? -- Datatools is imported twice??
@@ -80,10 +80,10 @@ gpu.setResolution(gpu.maxResolution())
log.kernel.info("Bound GPU to screen " .. tostring(screenAddress)) log.kernel.info("Bound GPU to screen " .. tostring(screenAddress))
if not filesystem.exists("/halyde/config/shell.json") then -- Auto-generate configs if not filesystem.exists("/halyde/config/shell.json") then -- Auto-generate configs
filesystem.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json") filesystem.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json")
end end
if not filesystem.exists("/halyde/config/startupapps.json") then if not filesystem.exists("/halyde/config/startupapps.json") then
filesystem.copy("/halyde/config/generate/startupapps.json", "/halyde/config/startupapps.json") filesystem.copy("/halyde/config/generate/startupapps.json", "/halyde/config/startupapps.json")
end end
log.kernel.info("Starting tsched") log.kernel.info("Starting tsched")
+526 -524
View File
File diff suppressed because it is too large Load Diff
+74 -60
View File
@@ -1,71 +1,85 @@
local fs, computer local fs, computer
local chunkSize = 1024
if require then if require then
fs = require("filesystem") fs = require("filesystem")
computer = require("computer") computer = require("computer")
else else
local loadfile = ... local loadfile = ...
fs = loadfile("/lib/filesystem.lua")(loadfile) fs = loadfile("/lib/filesystem.lua")(loadfile)
computer = _G.computer computer = _G.computer
end
logFileSizeLimit = 16384
local function writeToLog(path, text)
local handle
if fs.exists(path) then
handle = assert(fs.open(path, "a"))
else
handle = assert(fs.open(path, "w"))
end
handle:write(text .. "\n")
handle:close()
-- Log trimming if it gets too long
if fs.size(path) > logFileSizeLimit then
ocelot.log("Trimming log...")
local newlineCounter = 0
local sizeCounter = 0
local readHandle = fs.open(path, "r")
local chunkSize = 1024
readHandle:seek("end", -chunkSize)
repeat
local readText = readHandle:read(chunkSize)
readHandle:seek(-chunkSize * 2)
local _, newlineCount = readText:gsub("\n", "\n")
newlineCounter = newlineCounter + newlineCount
sizeCounter = sizeCounter + chunkSize
until sizeCounter >= logFileSizeLimit * 0.75
readHandle:seek(chunkSize)
local writeHandle = fs.open(path, "w")
while true do
local tmpdata = readHandle:read(math.huge or math.maxinteger)
if not tmpdata then
break
end
writeHandle:write(tmpdata)
end
readHandle:close()
writeHandle:close()
end
end end
local log = {} local log = {}
local logFileSizeLimit = 16384
local function writeToLog(path, text)
local handle
if fs.exists(path) then
handle = assert(fs.open(path, "a"))
else
handle = assert(fs.open(path, "w"))
end
handle:write(text .. "\n")
handle:close()
-- Log trimming if it gets too long
if fs.size(path) > logFileSizeLimit then
local sizeCounter = 0
local readHandle = fs.open(path, "r")
local currentChunk = ""
readHandle:seek("end", -chunkSize)
repeat
currentChunk = readHandle:read(chunkSize)
readHandle:seek(-chunkSize * 2)
sizeCounter = sizeCounter + chunkSize
until sizeCounter >= logFileSizeLimit * 0.75
while true do
local infoEntry = currentChunk:find("INFO [", 1, true)
local warnEntry = currentChunk:find("WARN [", 1, true)
local errorEntry = currentChunk:find("ERROR [", 1, true)
if not infoEntry and not warnEntry and not errorEntry then
readHandle:seek(-chunkSize)
else
readHandle:seek(math.min(infoEntry or math.huge or math.maxinteger, warnEntry or math.huge or math.maxinteger,
errorEntry or math.huge or math.maxinteger) - 1)
break
end
if readHandle:seek("cur") == 0 then -- Failsafe to prevent infinite loops
break
end
end
local writeHandle = fs.open(path, "w")
while true do
local tmpdata = readHandle:read(math.huge or math.maxinteger)
if not tmpdata then
break
end
writeHandle:write(tmpdata)
end
readHandle:close()
writeHandle:close()
end
end
setmetatable(log, { setmetatable(log, {
["__index"] = function(tab, index) ["__index"] = function(_, index)
return { return {
["logpath"] = fs.concat("/halyde/logs/", index .. ".log"), ["logpath"] = fs.concat("/halyde/logs/", index .. ".log"),
["info"] = function(text) ["info"] = function(text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "INFO [" .. computer.uptime() .. "] " .. text) writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
end, "INFO [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
["warn"] = function(text) end,
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "WARN [" .. computer.uptime() .. "] " .. text) ["warn"] = function(text)
end, writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
["error"] = function(text) "WARN [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "ERROR [" .. computer.uptime() .. "] " .. text) end,
end, ["error"] = function(text)
} writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
end, "ERROR [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
end,
}
end,
}) })
return log return log