232 lines
6.9 KiB
Plaintext
232 lines
6.9 KiB
Plaintext
|
--[[
|
||
|
MCM Logging Utility
|
||
|
17DEC2021
|
||
|
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
|
||
|
Author: RavenAscendant
|
||
|
--]]
|
||
|
|
||
|
--[[
|
||
|
Usage:
|
||
|
log = mcm_log.new("prefix")
|
||
|
Log files are created at appdata/logs/mcm and are named after the script that created them.
|
||
|
Because of this multiple log objects created in one script function more like channels with thier output to the shared file identified by the provided prefix.
|
||
|
Each log object must be individualy enabled. This allows for easy control of diferent levels of logging
|
||
|
err = mcm_log.new("ERR")
|
||
|
err.enabled = true
|
||
|
msg = mcm_log.new("MSG")
|
||
|
msg.enabled = true
|
||
|
A log object can be flagged to save the log file every line. (continuous logginf must also be enabled by the user in the MCM settings)
|
||
|
err.continuous = true
|
||
|
Three functions are provided
|
||
|
log(fmt) this function takes the same input as the anomaly printf it will write that text to a line in the log file
|
||
|
that line will be prefaced with the log objects pfrefix and the time_continual time stamp.
|
||
|
msg:log("hello %s", "world")
|
||
|
Oputput: MSG |22877|| hello world
|
||
|
|
||
|
printf(fmt) behaves just like log except that it will print to the xray log and console as well. (printing to the console will still work even if user disables MCM logging. Printing to the console will not happen if the log object is not enabled)
|
||
|
msg:printf(fmt)
|
||
|
|
||
|
lastly log_table(tbl, name) formats and prints a table to the log
|
||
|
|
||
|
changelog
|
||
|
1.0.0 inital
|
||
|
1.0.1 removed unused ltx, corected callback.
|
||
|
1.0.2 adding error handeling to more file operations
|
||
|
|
||
|
--]]
|
||
|
|
||
|
|
||
|
|
||
|
local mcm_path = "mcm/mcm_log/"
|
||
|
local NUMLOGS = axr_main.config:r_value("mcm", mcm_path.."numlogs", 2, 2)
|
||
|
local LOG_SAVE_FREQUENCY = axr_main.config:r_value("mcm", mcm_path.."savefreq", 2, 1000)
|
||
|
local CONTINUOUS_ENABLED = axr_main.config:r_value("mcm", mcm_path.."continuous", 1, false)
|
||
|
local TIMESTAMP_FREQ = axr_main.config:r_value("mcm", mcm_path.."timestamp", 2, 1000)
|
||
|
local logging_enabled = axr_main.config:r_value("mcm", mcm_path.."enable", 1, true)
|
||
|
|
||
|
|
||
|
|
||
|
local string_gsub = string.gsub
|
||
|
local files = {}
|
||
|
local PATH = getFS():update_path("$logs$","mcm")
|
||
|
local last_console = 0
|
||
|
local flush_time = 0
|
||
|
|
||
|
local function write_log(file, tc, prefix, fmt, continuous)
|
||
|
if not (logging_enabled and file) then return end
|
||
|
local txt = prefix.."\t|"..tc.."||" .. fmt.."\n"
|
||
|
file:write(txt)
|
||
|
if continuous and CONTINUOUS_ENABLED then
|
||
|
file:flush()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
class "MCM_Log"
|
||
|
function MCM_Log:__init(prefix)
|
||
|
self.prefix = prefix or ""
|
||
|
self.enabled = false
|
||
|
self.continuous = false
|
||
|
local info = debug.getinfo(4,"S")
|
||
|
local path_list = str_explode(info.short_src, "\\")
|
||
|
local name = path_list and str_explode(path_list[#path_list], "%.")
|
||
|
self.fname = name and name[1] or "mcm_log_fail"
|
||
|
end
|
||
|
|
||
|
function MCM_Log:Open_file()
|
||
|
if (not files[self.fname]) and logging_enabled then
|
||
|
local file, msg = io.open(PATH.."/"..self.fname.."_"..ui_mcm.get_session_id()..".log","a+")
|
||
|
if not file then
|
||
|
printf("!ERROR MCM Logs unable to create log file. Manualy creating the directory appdata/logs/mcm/ may solve this issue.")
|
||
|
return
|
||
|
end
|
||
|
files[self.fname] = file
|
||
|
files[self.fname]:write("======================\n")
|
||
|
files[self.fname]:write("=="..os.date("%d%b%Y %X") .."==\n")
|
||
|
files[self.fname]:write("=Continuous logging:=\n")
|
||
|
if not CONTINUOUS_ENABLED then
|
||
|
files[self.fname]:write("=========FALSE========\n")
|
||
|
else
|
||
|
files[self.fname]:write("=========TRUE=========\n")
|
||
|
end
|
||
|
files[self.fname]:write("======================\n")
|
||
|
files[self.fname]:flush()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
function MCM_Log:log(fmt, ...)
|
||
|
if not (self.enabled and logging_enabled )then return false end
|
||
|
if not (fmt) then return end
|
||
|
local fmt = tostring(fmt)
|
||
|
self:Open_file()
|
||
|
if (select('#',...) >= 1) then
|
||
|
local i = 0
|
||
|
local p = {...}
|
||
|
local function sr(a)
|
||
|
i = i + 1
|
||
|
if (type(p[i]) == 'userdata') then
|
||
|
if (p[i].x and p[i].y) then
|
||
|
return vec_to_str(p[i])
|
||
|
end
|
||
|
return 'userdata'
|
||
|
end
|
||
|
return tostring(p[i])
|
||
|
end
|
||
|
fmt = string_gsub(fmt,"%%s",sr)
|
||
|
end
|
||
|
|
||
|
local tc = time_continual()
|
||
|
write_log(files[self.fname], tc , self.prefix, fmt, self.continuous)
|
||
|
return tc
|
||
|
|
||
|
end
|
||
|
|
||
|
function MCM_Log:printf(fmt, ...)
|
||
|
if self.enabled then
|
||
|
local tc = self:log(fmt, ...) or time_continual()
|
||
|
last_console = tc
|
||
|
printf("%s|%s|%s||"..tostring(fmt), self.prefix, self.fname, tc, ...)
|
||
|
return tc
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function MCM_Log:log_table(tbl, name)
|
||
|
if not (self.enabled and logging_enabled )then return false end
|
||
|
if type(tbl) ~= "table" then return end
|
||
|
name = name or tostring(tbl)
|
||
|
local txt = utils_data.print_table(tbl, false, true)
|
||
|
return self:log("TABLE:%s \n%s", name, txt)
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
function new(prefix)
|
||
|
local temp = MCM_Log(prefix)
|
||
|
return temp
|
||
|
end
|
||
|
|
||
|
|
||
|
local function flush_logs()
|
||
|
flush_time = time_continual()
|
||
|
for _,file in pairs(files) do
|
||
|
file:flush()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function fsgame_append(str,ap)
|
||
|
path = getFS():update_path("$fs_root$","fsgame.ltx")
|
||
|
local fsg = io.open(path,"a+")
|
||
|
local data = fsg:read("*all")
|
||
|
if not (string.find(data,str)) then
|
||
|
fsg:write("\n"..ap)
|
||
|
fsg:close()
|
||
|
return false
|
||
|
end
|
||
|
fsg:close()
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
function close_logs()
|
||
|
fsgameupdated = fsgame_append("mcmlogs", "$mcmlogs$ = true | false | $logs$| mcm\\")
|
||
|
--printf("MCM_Log close fsgameupdated:%s",fsgameupdated)
|
||
|
if not fsgameupdated then return end
|
||
|
for fname,file in pairs(files) do
|
||
|
file:close()
|
||
|
local f = getFS()
|
||
|
local flist = f:file_list_open_ex("$mcmlogs$",bit_or(FS.FS_ListFiles,FS.FS_RootOnly),fname.."*")
|
||
|
local f_cnt = flist:Size()
|
||
|
flist:Sort(5)
|
||
|
for it=2, f_cnt-1 do
|
||
|
local file = flist:GetAt(it)
|
||
|
pcall(function() f:file_delete(f:update_path("$mcmlogs$",file:NameFull())) end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
function timed_flush()
|
||
|
if time_continual() - flush_time > LOG_SAVE_FREQUENCY then
|
||
|
flush_logs()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local pf = _G.printf
|
||
|
function _G.printf(...)
|
||
|
if (time_continual() - last_console > TIMESTAMP_FREQ) and logging_enabled then
|
||
|
last_console = time_continual()
|
||
|
pf("Time continual is:%s",last_console)
|
||
|
end
|
||
|
pf(...)
|
||
|
end
|
||
|
|
||
|
local function on_option_change(mcm)
|
||
|
if mcm then
|
||
|
NUMLOGS = axr_main.config:r_value("mcm", mcm_path.."numlogs", 2, 2)
|
||
|
LOG_SAVE_FREQUENCY = axr_main.config:r_value("mcm", mcm_path.."savefreq", 2, 2)
|
||
|
CONTINUOUS_ENABLED = axr_main.config:r_value("mcm", mcm_path.."continuous", 1, false)
|
||
|
TIMESTAMP_FREQ = axr_main.config:r_value("mcm", mcm_path.."timestamp", 2, 2)
|
||
|
logging_enabled = axr_main.config:r_value("mcm", mcm_path.."enable", 1, true)
|
||
|
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function on_game_start()
|
||
|
flush_logs()
|
||
|
RegisterScriptCallback("on_before_level_changing",flush_logs)
|
||
|
RegisterScriptCallback("actor_on_before_death",flush_logs)
|
||
|
RegisterScriptCallback("GUI_on_show",flush_logs)
|
||
|
RegisterScriptCallback("GUI_on_hide",flush_logs)
|
||
|
RegisterScriptCallback("save_state",flush_logs)
|
||
|
RegisterScriptCallback("main_menu_on_init",flush_logs)
|
||
|
RegisterScriptCallback("main_menu_on_quit",flush_logs)
|
||
|
RegisterScriptCallback("on_option_change",on_option_change)
|
||
|
AddUniqueCall(timed_flush)
|
||
|
end
|
||
|
|