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
+13 -11
View File
@@ -144,6 +144,7 @@ function filesystem.makeReadStream(content)
end
return out
end
properHandle.readBytes = readBytes
properHandle.readUnicodeChar = readUnicodeChar
properHandle.iterateBytes = iterateBytes
@@ -151,9 +152,11 @@ function filesystem.makeReadStream(content)
function properHandle.write()
return nil
end
function properHandle.close()
content = nil
end
return properHandle
end
@@ -277,6 +280,7 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
end
end
end
properHandle.readBytes = readBytes
properHandle.readUnicodeChar = readUnicodeChar
properHandle.iterateBytes = iterateBytes
@@ -309,12 +313,14 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
return component.invoke(self.address, "write", self.handle, data)
end
end
function properHandle.close(self)
if buffered then
content = nil
end
return component.invoke(self.address, "close", self.handle)
end
if address == computer.getBootAddress() then
local eeprom
pcall(function()
@@ -339,6 +345,7 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
checkArg(2, data, "string")
content = content .. data
end
function properHandle.close(self)
return eeprom[setFunc](content)
end
@@ -359,25 +366,19 @@ function filesystem.open(path, mode, buffered) -- opens a file and returns its h
end
if buffered then
-- Calculate current absolute position in file
local currentAbsolutePos = bufferOffset + readCursor - 1
-- Seek the underlying file handle to the correct position
-- Seek real handle position to buffer handle position
component.invoke(self.address, "seek", self.handle, "set", currentAbsolutePos)
-- Now perform the actual seek
local newPos = component.invoke(self.address, "seek", self.handle, whence, offset)
-- Invalidate the buffer and reset positions
local newPos = component.invoke(self.address, "seek", self.handle, whence, math.max(offset, -currentAbsolutePos))
content = nil
bufferOffset = newPos or 0
readCursor = 1
return newPos
else
return component.invoke(self.address, "seek", self.handle, whence, offset)
return component.invoke(self.address, "seek", self.handle, whence, math.max(offset, -currentAbsolutePos))
end
end
return properHandle
end
@@ -561,7 +562,8 @@ function filesystem.rename(fromPath, toPath)
copyRecursive(fromAddress, fromAbsPath, toAddress, toAbsPath)
filesystem.remove(fromPath) -- component.invoke(fromAddress,"remove", fromAbsPath)
else
local handle, data, tmpdata = filesystem.open(fromPath), "", nil -- component.invoke(fromAddress, "open", fromAbsPath, "r"), "", nil
local handle, data, tmpdata = filesystem.open(fromPath), "",
nil -- component.invoke(fromAddress, "open", fromAbsPath, "r"), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger) -- component.invoke(fromAddress, "read", handle, math.huge or math.maxinteger)
data = data .. (tmpdata or "")
+28 -14
View File
@@ -1,4 +1,5 @@
local fs, computer
local chunkSize = 1024
if require then
fs = require("filesystem")
computer = require("computer")
@@ -8,7 +9,9 @@ else
computer = _G.computer
end
logFileSizeLimit = 16384
local log = {}
local logFileSizeLimit = 16384
local function writeToLog(path, text)
local handle
@@ -22,20 +25,30 @@ local function writeToLog(path, text)
-- 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
local currentChunk = ""
readHandle:seek("end", -chunkSize)
repeat
local readText = readHandle:read(chunkSize)
currentChunk = 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)
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)
@@ -49,20 +62,21 @@ local function writeToLog(path, text)
end
end
local log = {}
setmetatable(log, {
["__index"] = function(tab, index)
["__index"] = function(_, index)
return {
["logpath"] = fs.concat("/halyde/logs/", index .. ".log"),
["info"] = function(text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "INFO [" .. computer.uptime() .. "] " .. text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
"INFO [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
end,
["warn"] = function(text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "WARN [" .. computer.uptime() .. "] " .. text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
"WARN [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
end,
["error"] = function(text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "ERROR [" .. computer.uptime() .. "] " .. text)
writeToLog(fs.concat("/halyde/logs/", index .. ".log"),
"ERROR [" .. string.format("%.2f", computer.uptime()) .. "] " .. text)
end,
}
end,