diff options
Diffstat (limited to 'script-beta/log.lua')
-rw-r--r-- | script-beta/log.lua | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/script-beta/log.lua b/script-beta/log.lua new file mode 100644 index 00000000..1a66685a --- /dev/null +++ b/script-beta/log.lua @@ -0,0 +1,140 @@ +local fs = require 'bee.filesystem' + +local osTime = os.time +local osClock = os.clock +local osDate = os.date +local ioOpen = io.open +local tablePack = table.pack +local tableConcat = table.concat +local tostring = tostring +local debugTraceBack = debug.traceback +local mathModf = math.modf +local debugGetInfo = debug.getinfo +local ioStdErr = io.stderr + +_ENV = nil + +local m = {} + +m.file = nil +m.startTime = osTime() - osClock() +m.size = 0 +m.maxSize = 100 * 1024 * 1024 + +local function trimSrc(src) + src = src:sub(m.prefixLen + 3, -5) + src = src:gsub('^[/\\]+', '') + src = src:gsub('[\\/]+', '.') + return src +end + +local function init_log_file() + if not m.file then + m.file = ioOpen(m.path, 'w') + if not m.file then + return + end + m.file:write('') + m.file:close() + m.file = ioOpen(m.path, 'ab') + if not m.file then + return + end + m.file:setvbuf 'no' + end +end + +local function pushLog(level, ...) + if not m.path then + return + end + if m.size > m.maxSize then + return + end + local t = tablePack(...) + for i = 1, t.n do + t[i] = tostring(t[i]) + end + local str = tableConcat(t, '\t', 1, t.n) + if level == 'error' then + str = str .. '\n' .. debugTraceBack(nil, 3) + end + local info = debugGetInfo(3, 'Sl') + return m.raw(0, level, str, info.source, info.currentline) +end + +function m.info(...) + pushLog('info', ...) +end + +function m.debug(...) + pushLog('debug', ...) +end + +function m.trace(...) + pushLog('trace', ...) +end + +function m.warn(...) + pushLog('warn', ...) +end + +function m.error(...) + pushLog('error', ...) +end + +function m.raw(thd, level, msg, source, currentline) + if level == 'error' then + ioStdErr:write(msg .. '\n') + end + init_log_file() + if not m.file then + return + end + local sec, ms = mathModf(m.startTime + osClock()) + local timestr = osDate('%H:%M:%S', sec) + local agl = '' + if #level < 5 then + agl = (' '):rep(5 - #level) + end + local buf + if currentline == -1 then + buf = ('[%s.%03.f][%s]: %s[#%d]%s\n'):format(timestr, ms * 1000, level, agl, thd, msg) + else + buf = ('[%s.%03.f][%s]: %s[#%d:%s:%s]%s\n'):format(timestr, ms * 1000, level, agl, thd, trimSrc(source), currentline, msg) + end + m.file:write(buf) + m.size = m.size + #buf + if m.size > m.maxSize then + m.file:write('[REACH MAX SIZE]') + end + return +end + +function m.init(root, path) + local lastBuf + if m.file then + m.file:close() + m.file = nil + local file = ioOpen(m.path, 'rb') + if file then + lastBuf = file:read 'a' + file:close() + end + end + m.path = path:string() + m.prefixLen = #root:string() + m.size = 0 + if not fs.exists(path:parent_path()) then + fs.create_directories(path:parent_path()) + end + if lastBuf then + init_log_file() + if m.file then + m.file:write(lastBuf) + m.size = m.size + #lastBuf + end + end +end + +return m |