mirror of https://github.com/1Panel-dev/1Panel
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
3.2 KiB
148 lines
3.2 KiB
local type = type
|
|
local concat_table = table.concat
|
|
local new_table = table.new
|
|
local tostring = tostring
|
|
local setmetatable = setmetatable
|
|
local open_file = io.open
|
|
local ngx_timer_at = ngx.timer.at
|
|
|
|
local _M = {}
|
|
|
|
local mt = { __index = _M }
|
|
|
|
function _M:new(log_path, host, rolling)
|
|
local t = {
|
|
flush_limit = 4096, -- 4kb
|
|
flush_timeout = 1,
|
|
|
|
buffered_size = 0,
|
|
buffer_index = 0,
|
|
buffer_data = new_table(20000, 0),
|
|
|
|
log_path = log_path,
|
|
prefix = log_path .. host .. '_',
|
|
rolling = rolling or false,
|
|
host = host,
|
|
timer = nil }
|
|
|
|
setmetatable(t, mt)
|
|
return t
|
|
end
|
|
|
|
local function needFlush(self)
|
|
if self.buffered_size > 0 then
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function flush_lock(self)
|
|
local dic_lock = ngx.shared.dict_locks
|
|
local locked = dic_lock:get(self.host)
|
|
if not locked then
|
|
local succ, err = dic_lock:set(self.host, true)
|
|
if not succ then
|
|
ngx.log(ngx.ERR, "failed to lock logfile " .. self.host .. ": ", err)
|
|
end
|
|
return succ
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function flush_unlock(self)
|
|
local dic_lock = ngx.shared.dict_locks
|
|
local success, err = dic_lock:set(self.host, false)
|
|
if not success then
|
|
ngx.log(ngx.ERR, "failed to unlock logfile " .. self.host .. ": ", err)
|
|
end
|
|
return success
|
|
end
|
|
|
|
local function write_file(self, value)
|
|
local file_name = ''
|
|
if self.rolling then
|
|
file_name = self.prefix .. ngx.today() .. ".log"
|
|
else
|
|
file_name = self.log_path
|
|
end
|
|
|
|
local file = open_file(file_name, "a+")
|
|
|
|
if file == nil or value == nil then
|
|
return
|
|
end
|
|
|
|
file:write(value)
|
|
file:flush()
|
|
file:close()
|
|
|
|
return
|
|
end
|
|
|
|
local function flushBuffer(self)
|
|
if not needFlush(self) then
|
|
return true
|
|
end
|
|
|
|
if not flush_lock(self) then
|
|
return true
|
|
end
|
|
|
|
local buffer = concat_table(self.buffer_data, "", 1, self.buffer_index)
|
|
write_file(self, buffer)
|
|
|
|
self.buffered_size = 0
|
|
self.buffer_index = 0
|
|
self.buffer_data = new_table(20000, 0)
|
|
|
|
flush_unlock(self)
|
|
end
|
|
|
|
local function flushPeriod(premature, self)
|
|
flushBuffer(self)
|
|
self.timer = false
|
|
end
|
|
|
|
local function writeBuffer(self, msg, msg_len)
|
|
self.buffer_index = self.buffer_index + 1
|
|
|
|
self.buffer_data[self.buffer_index] = msg
|
|
|
|
self.buffered_size = self.buffered_size + msg_len
|
|
|
|
return self.buffered_size
|
|
end
|
|
|
|
local function startTimer(self)
|
|
if not self.timer then
|
|
local ok, err = ngx_timer_at(self.flush_timeout, flushPeriod, self)
|
|
if not ok then
|
|
ngx.log(ngx.ERR, "failed to create the timer: ", err)
|
|
return
|
|
end
|
|
if ok then
|
|
self.timer = true
|
|
end
|
|
end
|
|
return self.timer
|
|
end
|
|
|
|
function _M:log(msg)
|
|
if type(msg) ~= "string" then
|
|
msg = tostring(msg)
|
|
end
|
|
|
|
local msg_len = #msg
|
|
local len = msg_len + self.buffered_size
|
|
|
|
if len < self.flush_limit then
|
|
writeBuffer(self, msg, msg_len)
|
|
startTimer(self)
|
|
elseif len >= self.flush_limit then
|
|
writeBuffer(self, msg, msg_len)
|
|
flushBuffer(self)
|
|
end
|
|
end
|
|
|
|
return _M |