Added logging system, fixed filesystem read handle buffering and added read handle seeking.

This commit is contained in:
2025-09-15 08:10:50 +03:00
parent d3d5f21ab1
commit 099fbee8c6
4 changed files with 667 additions and 483 deletions
+49 -35
View File
@@ -4,60 +4,72 @@ _G._OSVERSION = "HALYDE VERSION" -- TODO: Put this in a separate config file
_G._OSLOGO = "" _G._OSLOGO = ""
_G._PUBLIC = {} _G._PUBLIC = {}
_G._PUBLIC.unicode = assert(loadfile("/lib/unicode.lua")(loadfile)) _G._PUBLIC.unicode = assert(loadfile("/lib/unicode.lua")(loadfile))
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()
_G.package = {["preloaded"] = {}} log.kernel.info("Loaded OS logo")
_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 shell and shell.workingDirectory and filesystem.exists(filesystem.concat(shell.workingDirectory, module .. ".lua")) then elseif
modulepath = shell.workingDirectory .. module .. ".lua" shell
end and shell.workingDirectory
assert(modulepath, "Module not found\nPossible locations:\n/lib/" .. module .. ".lua") and filesystem.exists(filesystem.concat(shell.workingDirectory, module .. ".lua"))
local handle, data, tmpdata = filesystem.open(modulepath), "", nil then
repeat modulepath = shell.workingDirectory .. module .. ".lua"
tmpdata = handle:read(math.huge or math.maxinteger) end
data = data .. (tmpdata or "") assert(modulepath, "Module not found\nPossible locations:\n/lib/" .. module .. ".lua")
until not tmpdata local handle, data, tmpdata = filesystem.open(modulepath), "", nil
handle:close() repeat
return(assert(load(data, "="..modulepath))(table.unpack(args))) tmpdata = handle:read(math.huge or math.maxinteger)
end data = data .. (tmpdata or "")
until not tmpdata
handle:close()
return (assert(load(data, "=" .. modulepath))(table.unpack(args)))
end
end end
_G.require = reqgen(_G.load) _G.require = reqgen(_G.load)
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??
require("/halyde/kernel/datatools.lua") -- If this is not imported BEFORE modload gets run, modload requires filesystem which requires computer which requires datatools. TODO: When VFS is implemented, make the pre-VFS loading of filesystem load a more basic version. And remove this. require("/halyde/kernel/datatools.lua") -- If this is not imported BEFORE modload gets run, modload requires filesystem which requires computer which requires datatools. TODO: When VFS is implemented, make the pre-VFS loading of filesystem load a more basic version. And remove this.
log.kernel.info("Loading modules")
require("/halyde/kernel/modload.lua") require("/halyde/kernel/modload.lua")
package.preload("component") package.preload("component")
package.preload("computer") package.preload("computer")
log.kernel.info("Pre-loaded low-level packages")
local component = require("component") local component = require("component")
local gpu = component.gpu local gpu = component.gpu
@@ -65,12 +77,14 @@ local screenAddress = component.list("screen")()
gpu.bind(screenAddress) gpu.bind(screenAddress)
gpu.setResolution(gpu.maxResolution()) gpu.setResolution(gpu.maxResolution())
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")
require("/halyde/kernel/tsched.lua") require("/halyde/kernel/tsched.lua")
+6
View File
@@ -0,0 +1,6 @@
INFO [1.45] Loaded OS logo
INFO [1.5] Generated userland require function
INFO [1.5] Loading modules
INFO [2.2] Pre-loaded low-level packages
INFO [2.3] Bound GPU to screen d9443671-225d-4637-980f-fad46c9fb845
INFO [2.3] Starting tsched
+546 -423
View File
File diff suppressed because it is too large Load Diff
+66 -25
View File
@@ -1,30 +1,71 @@
local fs = require("filesystem") local fs, computer
local computer = require("computer") if require then
fs = require("filesystem")
computer = require("computer")
else
local loadfile = ...
fs = loadfile("/lib/filesystem.lua")(loadfile)
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
local log = {} local log = {}
function log.add(text, logType) setmetatable(log, {
checkArg(1, text, "string") ["__index"] = function(tab, index)
checkArg(2, logType, "string", "nil") return {
if logType ~= "debug" and logType ~= "info" and logType ~= "warning" and logType ~= "error" and logType then ["logpath"] = fs.concat("/halyde/logs/", index .. ".log"),
error("Log type must either be debug, info, warning or error.") ["info"] = function(text)
end writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "INFO [" .. computer.uptime() .. "] " .. text)
if not logType then end,
logType = "debug" ["warn"] = function(text)
end writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "WARN [" .. computer.uptime() .. "] " .. text)
local handle = fs.open("/halyde/system.log", "a") end,
local time = computer.uptime() ["error"] = function(text)
local logText = string.format("[%02d:%02d:%02d:%02d] " .. text, math.floor(time / 86400), math.floor(time / 3600 % 24), math.floor(time / 60 % 60), math.floor(time % 60)) .. "\n" writeToLog(fs.concat("/halyde/logs/", index .. ".log"), "ERROR [" .. computer.uptime() .. "] " .. text)
if logType == "debug" then end,
handle:write("\27[37m" .. logText) }
elseif logType == "info" then end,
handle:write("\27[97m" .. logText) })
elseif logType == "warning" then
handle:write("\27[93m" .. logText)
else
handle:write("\27[91m" .. logText)
end
handle:close()
end
return log return log