summaryrefslogtreecommitdiff
path: root/script-beta/log.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script-beta/log.lua')
-rw-r--r--script-beta/log.lua140
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