cc-mek-scada/scada-common/log.lua

244 lines
5.6 KiB
Lua
Raw Normal View History

2022-05-06 14:48:46 +00:00
local util = require("scada-common.util")
--
-- File System Logger
--
2022-05-10 21:06:27 +00:00
---@class log
local log = {}
2022-05-10 21:06:27 +00:00
---@alias MODE integer
local MODE = {
APPEND = 0,
NEW = 1
}
log.MODE = MODE
2022-05-10 21:06:27 +00:00
-- whether to log debug messages or not
2022-03-23 19:41:08 +00:00
local LOG_DEBUG = true
2022-05-06 14:48:46 +00:00
local _log_sys = {
path = "/log.txt",
mode = MODE.APPEND,
2022-05-16 16:50:51 +00:00
file = nil,
dmesg_out = nil
2022-05-06 14:48:46 +00:00
}
2022-05-10 21:06:27 +00:00
---@type function
2022-05-10 15:35:52 +00:00
local free_space = fs.getFreeSpace
-- initialize logger
2022-05-10 21:06:27 +00:00
---@param path string file path
---@param write_mode MODE
2022-05-16 16:50:51 +00:00
---@param dmesg_redirect? table terminal/window to direct dmesg to
log.init = function (path, write_mode, dmesg_redirect)
2022-05-10 15:35:52 +00:00
_log_sys.path = path
_log_sys.mode = write_mode
if _log_sys.mode == MODE.APPEND then
_log_sys.file = fs.open(path, "a")
else
2022-05-27 22:17:52 +00:00
_log_sys.file = fs.open(path, "w")
2022-05-10 15:35:52 +00:00
end
2022-05-16 16:50:51 +00:00
if dmesg_redirect then
_log_sys.dmesg_out = dmesg_redirect
else
_log_sys.dmesg_out = term.current()
end
2022-05-10 15:35:52 +00:00
end
-- direct dmesg output to a monitor/window
---@param window table window or terminal reference
log.direct_dmesg = function (window)
_log_sys.dmesg_out = window
end
2022-05-10 15:35:52 +00:00
-- private log write function
2022-05-10 21:06:27 +00:00
---@param msg string
local _log = function (msg)
2022-05-06 14:48:46 +00:00
local time_stamp = os.date("[%c] ")
2022-05-26 03:24:15 +00:00
local stamped = time_stamp .. util.strval(msg)
2022-04-27 22:43:07 +00:00
-- attempt to write log
2022-05-10 15:35:52 +00:00
local status, result = pcall(function ()
2022-05-06 14:48:46 +00:00
_log_sys.file.writeLine(stamped)
_log_sys.file.flush()
2022-04-27 22:43:07 +00:00
end)
2022-05-06 14:48:46 +00:00
-- if we don't have space, we need to create a new log file
2022-04-27 22:43:07 +00:00
if not status then
if result == "Out of space" then
2022-05-06 14:48:46 +00:00
-- will delete log file
2022-04-27 22:43:07 +00:00
elseif result ~= nil then
2022-05-06 14:48:46 +00:00
util.println("unknown error writing to logfile: " .. result)
2022-04-27 22:43:07 +00:00
end
end
2022-05-10 15:35:52 +00:00
if (result == "Out of space") or (free_space(_log_sys.path) < 100) then
2022-04-27 22:43:07 +00:00
-- delete the old log file and open a new one
2022-05-06 14:48:46 +00:00
_log_sys.file.close()
fs.delete(_log_sys.path)
2022-05-10 15:35:52 +00:00
log.init(_log_sys.path, _log_sys.mode)
2022-04-27 22:43:07 +00:00
-- leave a message
2022-05-06 14:48:46 +00:00
_log_sys.file.writeLine(time_stamp .. "recycled log file")
_log_sys.file.writeLine(stamped)
_log_sys.file.flush()
2022-04-27 22:43:07 +00:00
end
end
-- dmesg style logging for boot because I like linux-y things
---@param msg string message
---@param tag? string log tag
---@param tag_color? integer log tag color
log.dmesg = function (msg, tag, tag_color)
msg = util.strval(msg)
tag = tag or ""
tag = util.strval(tag)
local t_stamp = string.format("%12.2f", os.clock())
2022-05-16 16:50:51 +00:00
local out = _log_sys.dmesg_out
local out_w, out_h = out.getSize()
local lines = { msg }
-- wrap if needed
if string.len(msg) > out_w then
local remaining = true
local s_start = 1
local s_end = out_w
local i = 1
lines = {}
while remaining do
local line = string.sub(msg, s_start, s_end)
if line == "" then
remaining = false
else
lines[i] = line
s_start = s_end + 1
s_end = s_end + out_w
i = i + 1
end
end
end
-- start output with tag and time, assuming we have enough width for this to be on one line
local cur_x, cur_y = out.getCursorPos()
if cur_x > 1 then
if cur_y == out_h then
out.scroll(1)
out.setCursorPos(1, cur_y)
else
out.setCursorPos(1, cur_y + 1)
end
end
-- colored time
local initial_color = out.getTextColor()
out.setTextColor(colors.white)
out.write("[")
out.setTextColor(colors.lightGray)
out.write(t_stamp)
out.setTextColor(colors.white)
out.write("] ")
-- colored tag
if tag ~= "" then
out.write("[")
out.setTextColor(tag_color)
out.write(tag)
out.setTextColor(colors.white)
out.write("] ")
end
out.setTextColor(initial_color)
2022-05-16 16:50:51 +00:00
-- output message
for i = 1, #lines do
cur_x, cur_y = out.getCursorPos()
2022-05-16 16:50:51 +00:00
if i > 1 and cur_x > 1 then
2022-05-16 16:50:51 +00:00
if cur_y == out_h then
out.scroll(1)
out.setCursorPos(1, cur_y)
else
out.setCursorPos(1, cur_y + 1)
end
end
out.write(lines[i])
end
_log("[" .. t_stamp .. "] " .. tag .. " " .. msg)
2022-05-16 16:50:51 +00:00
end
2022-05-10 15:35:52 +00:00
-- log debug messages
2022-05-10 21:06:27 +00:00
---@param msg string message
---@param trace? boolean include file trace
log.debug = function (msg, trace)
2022-03-23 19:41:08 +00:00
if LOG_DEBUG then
local dbg_info = ""
if trace then
2022-05-06 14:48:46 +00:00
local info = debug.getinfo(2)
2022-03-23 19:41:08 +00:00
local name = ""
2022-05-06 14:48:46 +00:00
if info.name ~= nil then
name = ":" .. info.name .. "():"
2022-03-23 19:41:08 +00:00
end
2022-05-06 14:48:46 +00:00
dbg_info = info.short_src .. ":" .. name .. info.currentline .. " > "
2022-03-23 19:41:08 +00:00
end
2022-05-26 03:24:15 +00:00
_log("[DBG] " .. dbg_info .. util.strval(msg))
2022-03-23 19:41:08 +00:00
end
end
2022-05-10 15:35:52 +00:00
-- log info messages
2022-05-10 21:06:27 +00:00
---@param msg string message
log.info = function (msg)
2022-05-26 03:24:15 +00:00
_log("[INF] " .. util.strval(msg))
end
2022-05-10 15:35:52 +00:00
-- log warning messages
2022-05-10 21:06:27 +00:00
---@param msg string message
log.warning = function (msg)
2022-05-26 03:24:15 +00:00
_log("[WRN] " .. util.strval(msg))
2022-03-23 19:41:08 +00:00
end
2022-05-10 15:35:52 +00:00
-- log error messages
2022-05-10 21:06:27 +00:00
---@param msg string message
---@param trace? boolean include file trace
log.error = function (msg, trace)
local dbg_info = ""
2022-05-10 15:35:52 +00:00
if trace then
2022-05-06 14:48:46 +00:00
local info = debug.getinfo(2)
local name = ""
2022-05-06 14:48:46 +00:00
if info.name ~= nil then
name = ":" .. info.name .. "():"
end
2022-05-10 15:35:52 +00:00
2022-05-06 14:48:46 +00:00
dbg_info = info.short_src .. ":" .. name .. info.currentline .. " > "
end
2022-05-26 03:24:15 +00:00
_log("[ERR] " .. dbg_info .. util.strval(msg))
end
2022-05-10 15:35:52 +00:00
-- log fatal errors
2022-05-10 21:06:27 +00:00
---@param msg string message
log.fatal = function (msg)
2022-05-26 03:24:15 +00:00
_log("[FTL] " .. util.strval(msg))
end
return log