1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
local fs = require 'bee.filesystem'
local log = {}
log.file = nil
log.start_time = os.time() - os.clock()
log.size = 0
log.max_size = 100 * 1024 * 1024
local function trim_src(src)
src = src:sub(log.prefix_len + 3, -5)
src = src:gsub('^[/\\]+', '')
src = src:gsub('[\\/]+', '.')
return src
end
local function init_log_file()
if not log.file then
log.file = io.open(log.path, 'w')
if not log.file then
return
end
log.file:write('')
log.file:close()
log.file = io.open(log.path, 'ab')
if not log.file then
return
end
log.file:setvbuf 'no'
end
end
local function pushLog(level, ...)
if not log.path then
return
end
if log.size > log.max_size then
return
end
local t = table.pack(...)
for i = 1, t.n do
t[i] = tostring(t[i])
end
local str = table.concat(t, '\t', 1, t.n)
if level == 'error' then
str = str .. '\n' .. debug.traceback(nil, 3)
io.stderr:write(str .. '\n')
end
init_log_file()
if not log.file then
return
end
local sec, ms = math.modf(log.start_time + os.clock())
local timestr = os.date('%Y-%m-%d %H:%M:%S', sec)
local info = debug.getinfo(3, 'Sl')
local buf
if info and info.currentline > 0 then
buf = ('[%s.%03.f][%s]: [%s:%s]%s\n'):format(timestr, ms * 1000, level, trim_src(info.source), info.currentline, str)
else
buf = ('[%s.%03.f][%s]: %s\n'):format(timestr, ms * 1000, level, str)
end
log.file:write(buf)
log.size = log.size + #buf
if log.size > log.max_size then
log.file:write('[REACH MAX SIZE]')
end
return str
end
function log.info(...)
pushLog('info', ...)
end
function log.debug(...)
pushLog('debug', ...)
end
function log.trace(...)
pushLog('trace', ...)
end
function log.warn(...)
pushLog('warn', ...)
end
function log.error(...)
pushLog('error', ...)
end
function log.init(root, path)
local lastBuf
if log.file then
log.file:close()
log.file = nil
local file = io.open(log.path, 'rb')
if file then
lastBuf = file:read 'a'
file:close()
end
end
log.path = path:string()
log.prefix_len = #root:string()
log.size = 0
if not fs.exists(path:parent_path()) then
fs.create_directories(path:parent_path())
end
if lastBuf then
init_log_file()
if log.file then
log.file:write(lastBuf)
log.size = log.size + #lastBuf
end
end
end
return log
|