1Panel/plugins/openresty/waf/lib/logger.lua

148 lines
3.2 KiB
Lua

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