diff --git a/framework/lualib/zeus/skynet/lockable.lua b/framework/lualib/zeus/skynet/lockable.lua new file mode 100644 index 0000000..25f492e --- /dev/null +++ b/framework/lualib/zeus/skynet/lockable.lua @@ -0,0 +1,83 @@ +local skynet = require "skynet" +local coroutine = coroutine +local xpcall = xpcall +local traceback = debug.traceback + +--- Parent queue, and where lock the parent +function skynet.lockable_queue(parent_queue, parent_lock) + local current_thread = nil + local ref = 0 + local thread_queue = {} + local parent_queue = parent_queue + local parent_lock = parent_lock + local locked_by = nil + + local function xpcall_ret(ok, ...) + ref = ref - 1 + if ref == 0 then + if locked_by == current_thread then + locked_by = nil + end + current_thread = table.remove(thread_queue, 1) + if current_thread then + skynet.wakeup(current_thread) + end + end + if not ok then + return nil, ... + end + -- assert(ok, (...)) + return ... + end + + local lockable_queue = function(f, lock, ...) + local thread = coroutine.running() + --- If queue is locked and current thread is not the running one + if locked_by and current_thread ~= thread then + return nil, "Queue is locked" + end + + --- Set the locked flag even current task is not running for avoid any new task comming + if lock then + locked_by = thread + end + + --- If not in recursive lock, and current is running, wait for previous one finished + if current_thread and current_thread ~= thread then + table.insert(thread_queue, thread) + skynet.wait() + assert(ref == 0) -- current_thread == thread + end + + --- Set the current running thread + current_thread = thread + + --- Increase the ref + ref = ref + 1 + + --- Execute the function + return xpcall_ret(xpcall(f, traceback, ...)) + end + + if parent_queue then + return function(f, lock, ...) + return parent_queue(lockable_queue, parent_lock, f, lock, ...) + --[[ + return parent_queue(function(...) + return lockable_queue(f, lock, ...) + end, parent_lock, ...) + ]] -- + end + else + return lockable_queue + end +end + +--- +-- Lockable queue +-- @tparam function f The function to execute in this queue +-- @tparam boolean lock Lock current queue until current task exeucted completely or task cloud be queued for execution +-- @param ... +-- @return false if queue is lock, or the first value from your function f +-- @returns +return skynet.lockable_queue diff --git a/framework/lualib/zeus/zenv/init.lua b/framework/lualib/zeus/zenv/init.lua index 1a2d37a..ac4ae38 100644 --- a/framework/lualib/zeus/zenv/init.lua +++ b/framework/lualib/zeus/zenv/init.lua @@ -5,25 +5,31 @@ local M = { M.Nodes = { [1] = { nodeid = 1, - name = "login", + name = "login_1", }, [50] = { nodeid = 50, - name = "center", + name = "center_1", }, [100] = { nodeid = 100, - name = "game", + name = "game_1", }, [110] = { nodeid = 110, - name = "storage", + name = "storage_1", }, } +M.Logger = { + log_root = "logs/", -- 日志目录 + log_console = true, -- 输出终端 + log_level = 1, -- 日志等级 1~5 +} + function M.get_node_conf(nodeid) return M.Nodes[nodeid] end diff --git a/framework/lualib/zeus/zlog/formatter/concat.lua b/framework/lualib/zeus/zlog/formatter/concat.lua deleted file mode 100644 index c18b204..0000000 --- a/framework/lualib/zeus/zlog/formatter/concat.lua +++ /dev/null @@ -1,16 +0,0 @@ -local M = {} - -function M.new(sep) - sep = sep or ' ' - - return function(...) - local argc, argv = select('#', ...), {...} - for i = 1, argc do - argv[i] = tostring(argv[i]) - end - return (table.concat(argv, sep)) - end -end - -return M - diff --git a/framework/lualib/zeus/zlog/formatter/default.lua b/framework/lualib/zeus/zlog/formatter/default.lua deleted file mode 100644 index 268c456..0000000 --- a/framework/lualib/zeus/zlog/formatter/default.lua +++ /dev/null @@ -1,9 +0,0 @@ -local M = {} - -function M.new() - return function(msg) - return msg - end -end - -return M diff --git a/framework/lualib/zeus/zlog/formatter/format.lua b/framework/lualib/zeus/zlog/formatter/format.lua deleted file mode 100644 index 41340aa..0000000 --- a/framework/lualib/zeus/zlog/formatter/format.lua +++ /dev/null @@ -1,9 +0,0 @@ -local string = require "string" - -local M = {} - -function M.new() - return string.format -end - -return M diff --git a/framework/lualib/zeus/zlog/formatter/mix.lua b/framework/lualib/zeus/zlog/formatter/mix.lua deleted file mode 100644 index 76177ab..0000000 --- a/framework/lualib/zeus/zlog/formatter/mix.lua +++ /dev/null @@ -1,24 +0,0 @@ ---- --- compatiable with lualogging --- -local M = {} - -function M.new(default) - if not default then - default = require"log.formatter.format".new() - end - - return function(...) - if type((...)) == 'function' then - return (...)(select(2, ...)) - end - - if select('#', ...) < 2 then - return tostring((...)) - end - - return default(...) - end -end - -return M diff --git a/framework/lualib/zeus/zlog/formatter/pformat.lua b/framework/lualib/zeus/zlog/formatter/pformat.lua deleted file mode 100644 index 452c40b..0000000 --- a/framework/lualib/zeus/zlog/formatter/pformat.lua +++ /dev/null @@ -1,93 +0,0 @@ -local lpeg = require "lpeg" -local table = require "table" -local string = require "string" - -local unpack = unpack or table.unpack - -local HAS_A_FORMAT = pcall(string.format, '%a', 10) - -local P, C, Cs, Ct, Cp, S, R = lpeg.P, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cp, lpeg.S, lpeg.R - -local any = P(1) -local empty = P(0) - -local esc = P '%%' -local flags = S '-+ #0' -local digit = R '09' - -local fsym = S('cdiouxXeEfgGqs' .. (HAS_A_FORMAT and 'aA' or '')) -local width = digit * digit + digit -local precision = P '.' * (digit * digit + digit) -local format = (flags + empty) * (width + empty) * (precision + empty) * (P '.' + empty) -local valid_format = P '%' * format * fsym -local valid_format_capture = Cs(valid_format) - -local any_fsym = any - (flags + digit + P '.') -local any_format = P '%' * (flags + digit + P '.') ^ 0 * any_fsym - -local types = { - c = 'number', - d = 'number', - i = 'number', - o = 'number', - u = 'number', - x = 'number', - X = 'number', - a = 'number', - A = 'number', - e = 'number', - E = 'number', - f = 'number', - g = 'number', - G = 'number', - q = 'string', - s = 'string', -} - -local function safe_format(protect_only_args, fmt, ...) - local n, args = 0, {...} - - local function fix_fmt(f) - local fmt = valid_format_capture:match(f) - - if not fmt then - if protect_only_args then - return - end - return '%' .. f - end - - local typ = string.sub(fmt, -1) - - n = n + 1 - - if types[typ] ~= type(args[n]) then - args[n], fmt = tostring(args[n]), '%s' - end - - return fmt - end - - local pattern = Cs((esc + any_format / fix_fmt + any) ^ 0) - fmt = pattern:match(fmt) - - return string.format(fmt, unpack(args, 1, n)) -end - -local function buld_formatter(protect_only_args, no_warning) - return function(...) - local ok, msg = pcall(string.format, ...) - if not ok then - local err = msg - msg = safe_format(protect_only_args, ...) - if not no_warning then - msg = msg .. ' - ' .. 'WARNING: Error formatting log message: ' .. err - end - end - return msg - end -end - -return { - new = buld_formatter, -} diff --git a/framework/lualib/zeus/zlog/inspect.lua b/framework/lualib/zeus/zlog/inspect.lua deleted file mode 100644 index c88e0e8..0000000 --- a/framework/lualib/zeus/zlog/inspect.lua +++ /dev/null @@ -1,377 +0,0 @@ -local inspect = { - _VERSION = "inspect.lua 3.1.0", - _URL = "http://github.com/kikito/inspect.lua", - _DESCRIPTION = "human-readable representations of tables", - _LICENSE = [[ - MIT LICENSE - - Copyright (c) 2013 Enrique García Cota - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ]], -} - -local tostring = tostring -local setmetatable = setmetatable -local next = next -local type = type -local rawget = rawget -local getmetatable = getmetatable - -inspect.KEY = setmetatable({}, { - __tostring = function() - return "inspect.KEY" - end, -}) -inspect.METATABLE = setmetatable({}, { - __tostring = function() - return "inspect.METATABLE" - end, -}) - -local function rawpairs(t) - return next, t, nil -end - --- Apostrophizes the string if it has quotes, but not aphostrophes --- Otherwise, it returns a regular quoted string -local function smartQuote(str) - if str:match('"') and not str:match("'") then - return "'" .. str .. "'" - end - return '"' .. str:gsub('"', '\\"') .. '"' -end - --- \a => '\\a', \0 => '\\0', 31 => '\31' -local shortControlCharEscapes = { - ["\a"] = "\\a", - ["\b"] = "\\b", - ["\f"] = "\\f", - ["\n"] = "\\n", - ["\r"] = "\\r", - ["\t"] = "\\t", - ["\v"] = "\\v", -} -local longControlCharEscapes = {} -- \a => nil, \0 => \000, 31 => \031 -for i = 0, 31 do - local ch = string.char(i) - if not shortControlCharEscapes[ch] then - shortControlCharEscapes[ch] = "\\" .. i - longControlCharEscapes[ch] = string.format("\\%03d", i) - end -end - -local function escape(str) - return (str:gsub("\\", "\\\\"):gsub("(%c)%f[0-9]", longControlCharEscapes):gsub("%c", shortControlCharEscapes)) -end - -local function isIdentifier(str) - return type(str) == "string" and str:match("^[_%a][_%a%d]*$") -end - -local function isSequenceKey(k, sequenceLength) - return type(k) == "number" and 1 <= k and k <= sequenceLength and math.floor(k) == k -end - -local defaultTypeOrders = { - ["number"] = 1, - ["boolean"] = 2, - ["string"] = 3, - ["table"] = 4, - ["function"] = 5, - ["userdata"] = 6, - ["thread"] = 7, -} - -local function sortKeys(a, b) - local ta, tb = type(a), type(b) - - -- strings and numbers are sorted numerically/alphabetically - if ta == tb and (ta == "string" or ta == "number") then - return a < b - end - - local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb] - -- Two default types are compared according to the defaultTypeOrders table - if dta and dtb then - return defaultTypeOrders[ta] < defaultTypeOrders[tb] - elseif dta then - return true -- default types before custom ones - elseif dtb then - return false -- custom types after default ones - end - - -- custom types are sorted out alphabetically - return ta < tb -end - --- For implementation reasons, the behavior of rawlen & # is "undefined" when --- tables aren't pure sequences. So we implement our own # operator. -local function getSequenceLength(t) - local len = 1 - local v = rawget(t, len) - while v ~= nil do - len = len + 1 - v = rawget(t, len) - end - return len - 1 -end - -local function getNonSequentialKeys(t) - local keys, keysLength = {}, 0 - local sequenceLength = getSequenceLength(t) - for k, _ in rawpairs(t) do - if not isSequenceKey(k, sequenceLength) then - keysLength = keysLength + 1 - keys[keysLength] = k - end - end - table.sort(keys, sortKeys) - return keys, keysLength, sequenceLength -end - -local function countTableAppearances(t, tableAppearances) - tableAppearances = tableAppearances or {} - - if type(t) == "table" then - if not tableAppearances[t] then - tableAppearances[t] = 1 - for k, v in rawpairs(t) do - countTableAppearances(k, tableAppearances) - countTableAppearances(v, tableAppearances) - end - countTableAppearances(getmetatable(t), tableAppearances) - else - tableAppearances[t] = tableAppearances[t] + 1 - end - end - - return tableAppearances -end - -local copySequence = function(s) - local copy, len = {}, #s - for i = 1, len do - copy[i] = s[i] - end - return copy, len -end - -local function makePath(path, ...) - local keys = {...} - local newPath, len = copySequence(path) - for i = 1, #keys do - newPath[len + i] = keys[i] - end - return newPath -end - -local function processRecursive(process, item, path, visited) - if item == nil then - return nil - end - if visited[item] then - return visited[item] - end - - local processed = process(item, path) - if type(processed) == "table" then - local processedCopy = {} - visited[item] = processedCopy - local processedKey - - for k, v in rawpairs(processed) do - processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited) - if processedKey ~= nil then - processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited) - end - end - - local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited) - if type(mt) ~= "table" then - mt = nil - end -- ignore not nil/table __metatable field - setmetatable(processedCopy, mt) - processed = processedCopy - end - return processed -end - -------------------------------------------------------------------- - -local Inspector = {} -local Inspector_mt = { - __index = Inspector, -} - -function Inspector:puts(...) - local args = {...} - local buffer = self.buffer - local len = #buffer - for i = 1, #args do - len = len + 1 - buffer[len] = args[i] - end -end - -function Inspector:down(f) - self.level = self.level + 1 - f() - self.level = self.level - 1 -end - -function Inspector:tabify() - self:puts(self.newline, string.rep(self.indent, self.level)) -end - -function Inspector:alreadyVisited(v) - return self.ids[v] ~= nil -end - -function Inspector:getId(v) - local id = self.ids[v] - if not id then - local tv = type(v) - id = (self.maxIds[tv] or 0) + 1 - self.maxIds[tv] = id - self.ids[v] = id - end - return tostring(id) -end - -function Inspector:putKey(k) - if isIdentifier(k) then - return self:puts(k) - end - self:puts("[") - self:putValue(k) - self:puts("]") -end - -function Inspector:putTable(t) - if t == inspect.KEY or t == inspect.METATABLE then - self:puts(tostring(t)) - elseif self:alreadyVisited(t) then - self:puts("") - elseif self.level >= self.depth then - self:puts("{...}") - else - if self.tableAppearances[t] > 1 then - self:puts("<", self:getId(t), ">") - end - - local nonSequentialKeys, nonSequentialKeysLength, sequenceLength = getNonSequentialKeys(t) - local mt = getmetatable(t) - - self:puts("{") - self:down(function() - local count = 0 - for i = 1, sequenceLength do - if count > 0 then - self:puts(",") - end - self:puts(" ") - self:putValue(t[i]) - count = count + 1 - end - - for i = 1, nonSequentialKeysLength do - local k = nonSequentialKeys[i] - if count > 0 then - self:puts(",") - end - self:tabify() - self:putKey(k) - self:puts(" = ") - self:putValue(t[k]) - count = count + 1 - end - - if type(mt) == "table" then - if count > 0 then - self:puts(",") - end - self:tabify() - self:puts(" = ") - self:putValue(mt) - end - end) - - if nonSequentialKeysLength > 0 or type(mt) == "table" then -- result is multi-lined. Justify closing } - self:tabify() - elseif sequenceLength > 0 then -- array tables have one extra space before closing } - self:puts(" ") - end - - self:puts("}") - end -end - -function Inspector:putValue(v) - local tv = type(v) - - if tv == "string" then - self:puts(smartQuote(escape(v))) - elseif tv == "number" or tv == "boolean" or tv == "nil" or tv == "cdata" or tv == "ctype" then - self:puts(tostring(v)) - elseif tv == "table" then - self:putTable(v) - else - self:puts("<", tv, " ", self:getId(v), ">") - end -end - -------------------------------------------------------------------- - -function inspect.inspect(root, options) - options = options or {} - - local depth = options.depth or math.huge - local newline = options.newline or "\n" - local indent = options.indent or " " - local process = options.process - - if process then - root = processRecursive(process, root, {}, {}) - end - - local inspector = setmetatable({ - depth = depth, - level = 0, - buffer = {}, - ids = {}, - maxIds = {}, - newline = newline, - indent = indent, - tableAppearances = countTableAppearances(root), - }, Inspector_mt) - - inspector:putValue(root) - - return table.concat(inspector.buffer) -end - -setmetatable(inspect, { - __call = function(_, ...) - return inspect.inspect(...) - end, -}) - -return inspect diff --git a/framework/lualib/zeus/zlog/log.lua b/framework/lualib/zeus/zlog/log.lua index 83668a7..c462610 100644 --- a/framework/lualib/zeus/zlog/log.lua +++ b/framework/lualib/zeus/zlog/log.lua @@ -1,223 +1,76 @@ ---- --- @module log --- -local _COPYRIGHT = "Copyright (C) 2013-2016 Alexey Melnichuk"; -local _VERSION = "0.1.7-dev" - -local table = require "table" -local date = require "date" - -local destroy_list = {} -local loggers_list = setmetatable({}, { - __mode = 'k', -}) -local emptyfn = function() -end - -local LOG_LVL = { - EMERG = 1, - ALERT = 2, - FATAL = 3, - ERROR = 4, - WARNING = 5, - NOTICE = 6, - INFO = 7, - DEBUG = 8, - TRACE = 9, -} - -local writer_names = {} -local LOG_LVL_NAMES = {} -for k, v in pairs(LOG_LVL) do - LOG_LVL_NAMES[v] = k - writer_names[v] = k:lower() -end - -local LOG_LVL_COUNT = #LOG_LVL_NAMES - -local function lvl2number(lvl) - if type(lvl) == 'number' then - return lvl - end - if type(lvl) == 'string' then - lvl = lvl:upper() - local n - if lvl == 'NONE' then - n = 0 - else - n = LOG_LVL[lvl] - end - if not n then - return nil, "unknown log level: '" .. lvl .. "'" - end - return n - end - - return nil, 'unsupported log leve type: ' .. type(lvl) -end - -local Log = {} -Log._COPYRIGHT = _COPYRIGHT -Log._NAME = "log" -Log._VERSION = _VERSION -Log._LICENSE = "MIT" - -Log.LVL = LOG_LVL -Log.LVL_NAMES = LOG_LVL_NAMES - -Log.lvl2number = lvl2number - -function Log.new(max_lvl, writer, formatter, logformat) - if max_lvl and type(max_lvl) ~= 'number' and type(max_lvl) ~= 'string' then - max_lvl, writer, formatter, logformat = nil, max_lvl, writer, formatter - end - - max_lvl = assert(lvl2number(max_lvl or LOG_LVL.INFO)) - - if not writer then - writer = require"log.writer.stdout".new() - end - - if not formatter then - formatter = require"log.formatter.default".new() - end - - if not logformat then - logformat = require"log.logformat.default".new() - end - - local write = function(lvl, ...) - local now = date() - writer(logformat, formatter(...), lvl, now) - end; +local skynet = require "skynet" +local log_define = require "zlog.log_define" - local dump = function(lvl, fn, ...) - local now = date() - writer(logformat, (fn(...) or ''), lvl, now) - end - - local logger = {} +local getinfo = debug.getinfo +local LOG_LEVEL = log_define.LOG_LEVEL +local DEFAULT_CATEGORY = log_define.DEFAULT_CATEGORY +local log_format = log_define.format - function logger.writer() - return writer - end +local category_addr = {} - function logger.formatter() - return formatter +local function get_service(category) + local addr = category_addr[category] + if addr then + return addr end - function logger.format() - return logformat + local root_addr = skynet.localname(".logger") + if not root_addr then + -- no logger config + root_addr = skynet.uniqueservice("logger") end - function logger.lvl() - return max_lvl - end + addr = skynet.call(root_addr, "lua", "get_service", category) + category_addr[category] = addr + return addr +end - function logger.set_writer(value) - assert(value) - writer, value = value, writer - return value - end +local function sendlog(category, level, ...) + local di = getinfo(3, "Sl") + local msg = log_format(skynet.self(), level, di, ...) + skynet.call(get_service(category), "lua", "log", level, msg) +end - function logger.set_formatter(value) - assert(value) - formatter, value = value, formatter - return value - end +local M = {} - function logger.set_format(value) - assert(value) - logformat, value = value, logformat - return value - end +function M.d(...) + sendlog(DEFAULT_CATEGORY, LOG_LEVEL.DEBUG, ...) +end - function logger.log(lvl, ...) - local err - lvl, err = lvl2number(lvl) - if not lvl then - return nil, err - end - return write(lvl, ...) - end +function M.d2(category, ...) + sendlog(category, LOG_LEVEL.DEBUG, ...) +end - function logger.dump(lvl, ...) - local err - lvl, err = lvl2number(lvl) - if not lvl then - return nil, err - end - return dump(lvl, ...) - end +function M.i(...) + sendlog(DEFAULT_CATEGORY, LOG_LEVEL.INFO, ...) +end - function logger.set_lvl(lvl) - local err - lvl, err = lvl2number(lvl) - if not lvl then - return nil, err - end - max_lvl = lvl - for i = 1, max_lvl do - logger[writer_names[i]] = function(...) - write(i, ...) - end - end - for i = 1, max_lvl do - logger[writer_names[i] .. '_dump'] = function(...) - dump(i, ...) - end - end - for i = max_lvl + 1, LOG_LVL_COUNT do - logger[writer_names[i]] = emptyfn - end - for i = max_lvl + 1, LOG_LVL_COUNT do - logger[writer_names[i] .. '_dump'] = emptyfn - end - return true - end +function M.i2(category, ...) + sendlog(category, LOG_LEVEL.INFO, ...) +end - assert(logger.set_lvl(max_lvl)) +function M.w(...) + sendlog(DEFAULT_CATEGORY, LOG_LEVEL.WARN, ...) +end - loggers_list[logger] = true; +function M.w2(category, ...) + sendlog(category, LOG_LEVEL.WARN, ...) +end - return logger +function M.e(...) + sendlog(DEFAULT_CATEGORY, LOG_LEVEL.ERROR, ...) end -function Log.add_cleanup(fn) - assert(type(fn) == 'function') - for k, v in ipairs(destroy_list) do - if v == fn then - return - end - end - table.insert(destroy_list, 1, fn) - return fn +function M.e2(category, ...) + sendlog(category, LOG_LEVEL.ERROR, ...) end -function Log.remove_cleanup(fn) - for k, v in ipairs(destroy_list) do - if v == fn then - table.remove(destroy_list, k) - break - end - end +function M.f(...) + sendlog(DEFAULT_CATEGORY, LOG_LEVEL.FATAL, ...) end -function Log.close() - for _, fn in ipairs(destroy_list) do - pcall(fn) - end - for logger in pairs(loggers_list) do - logger.fotal = emptyfn; - logger.error = emptyfn; - logger.warning = emptyfn; - logger.info = emptyfn; - logger.notice = emptyfn; - logger.debug = emptyfn; - logger.closed = true; - loggers_list[logger] = nil - end - destroy_list = {} +function M.f2(category, ...) + sendlog(category, LOG_LEVEL.FATAL, ...) end -return Log +return M diff --git a/framework/lualib/zeus/zlog/log_define.lua b/framework/lualib/zeus/zlog/log_define.lua new file mode 100644 index 0000000..523977e --- /dev/null +++ b/framework/lualib/zeus/zlog/log_define.lua @@ -0,0 +1,77 @@ +local string_format = string.format +local tconcat = table.concat +local os_date = os.date +local string_sub = string.sub +local os_clock = os.clock + +local ESC = string.char(27, 91) +local RESET = ESC .. '0m' + +local M = {} + +M.LOG_LEVEL = { + DEBUG = 1, + INFO = 2, + WARN = 3, + ERROR = 4, + FATAL = 5, +} + +M.LOG_LEVEL_NAME = { + [1] = "DEBUG", + [2] = "INFO ", + [3] = "WARN ", + [4] = "ERROR", + [5] = "FATAL", +} + +M.LOG_COLOR = { + [1] = ESC .. '34m', + [2] = ESC .. '32m', + [3] = ESC .. '33m', + [4] = ESC .. '31m', + [5] = ESC .. '35m', +} + +M.DEFAULT_CATEGORY = "root" + +function M.log_dir(log_root, date) + return string_format("%s/%04d-%02d-%02d", log_root or ".", date.year, date.month, date.day) +end + +function M.log_path(dir, prefix, category, date) + return string_format("%s/%s%s_%04d-%02d-%02d.log", dir or ".", prefix or "", category or M.DEFAULT_CATEGORY, + date.year, date.month, date.day) +end + +function M.format(addr, level, di, ...) + local param = {...} + local date = os_date("*t") + local ms = string_sub(os_clock(), 3, 6) + + local time = string_format("%02d:%02d:%02d.%02d", date.hour, date.min, date.sec, ms) + + local fileline = "" + if di then + fileline = (" [%s:%d]"):format(di.short_src, di.currentline) + end + + for k, v in pairs(param) do + param[k] = tostring(v) + end + + local msg = + string_format("[:%08x][%s][%s] %s%s", addr, M.LOG_LEVEL_NAME[level], time, tconcat(param, " "), fileline) + + return msg +end + +function M.color(level, msg) + local c = M.LOG_COLOR[level] + if not c then + return msg + end + return c .. msg .. RESET +end + +return M diff --git a/framework/lualib/zeus/zlog/logformat/default.lua b/framework/lualib/zeus/zlog/logformat/default.lua deleted file mode 100644 index 34e15ab..0000000 --- a/framework/lualib/zeus/zlog/logformat/default.lua +++ /dev/null @@ -1,18 +0,0 @@ -local string = require "string" -local Log = require "log" - -local sformat = string.format -local function date_fmt(now) - local Y, M, D = now:getdate() - return sformat("%.4d-%.2d-%.2d %.2d:%.2d:%.2d", Y, M, D, now:gettime()) -end - -local M = {} - -function M.new() - return function(msg, lvl, now) - return date_fmt(now) .. ' [' .. Log.LVL_NAMES[lvl] .. '] ' .. msg - end -end - -return M diff --git a/framework/lualib/zeus/zlog/logformat/proxy.lua b/framework/lualib/zeus/zlog/logformat/proxy.lua deleted file mode 100644 index a24931b..0000000 --- a/framework/lualib/zeus/zlog/logformat/proxy.lua +++ /dev/null @@ -1,11 +0,0 @@ -local packer = require "log.logformat.proxy.pack" - -local M = {} - -function M.new() - return function(now, lvl, msg) - return packer.pack(now, lvl, msg) - end -end - -return M diff --git a/framework/lualib/zeus/zlog/logformat/proxy/pack.lua b/framework/lualib/zeus/zlog/logformat/proxy/pack.lua deleted file mode 100644 index d43066b..0000000 --- a/framework/lualib/zeus/zlog/logformat/proxy/pack.lua +++ /dev/null @@ -1,36 +0,0 @@ -local Log = require "log" -local date = require "date" -local string = require "string" -local schar = string.char -local sbyte = string.byte -local sformat = string.format -local ssub = string.sub -local tn = tonumber - -local M = {} - -function M.pack(msg, lvl, now) - local Y, M, D = now:getdate() - local h, m, s = now:gettime() - local now_s = sformat("%.4d-%.2d-%.2d %.2d:%.2d:%.2d", Y, M, D, h, m, s) - - return schar(lvl) .. now_s .. msg -end - -function M.unpack(str) - local lvl = sbyte(ssub(str, 1, 1)) - if not Log.LVL_NAMES[lvl] then - return - end - local now_s = ssub(str, 2, 20) - local Y, M, D = ssub(str, 2, 5), ssub(str, 7, 8), ssub(str, 10, 11) - local h, m, s = ssub(str, 13, 14), ssub(str, 16, 17), ssub(str, 19, 20) - Y, M, D, h, m, s = tn(Y), tn(M), tn(D), tn(h), tn(m), tn(s) - if not (Y and M and D and h and m and s) then - return - end - - return ssub(str, 21), lvl, date(Y, M, D, h, m, s) -end - -return M diff --git a/framework/lualib/zeus/zlog/logformat/syslog.lua b/framework/lualib/zeus/zlog/logformat/syslog.lua deleted file mode 100644 index b06845d..0000000 --- a/framework/lualib/zeus/zlog/logformat/syslog.lua +++ /dev/null @@ -1,148 +0,0 @@ -local string = require "string" -local math = require "math" -local Log = require "log" - -local mod, floor, ceil, abs, pow = math.fmod, math.floor, math.ceil, math.abs, math.pow -local fmt = string.format - --- removes the decimal part of a number -local function fix(n) - n = tonumber(n) - return n and ((n > 0 and floor or ceil)(n)) -end - -local function lshift(a, b) - if math.pow then - return a * math.pow(2, b) - else - return a << b - end -end - ---[[ RFC5424 - 0 Emergency: system is unusable - 1 Alert: action must be taken immediately - 2 Critical: critical conditions - 3 Error: error conditions - 4 Warning: warning conditions - 5 Notice: normal but significant condition - 6 Informational: informational messages - 7 Debug: debug-level messages ---]] -local SEVERITY = { - EMERG = 0, - ALERT = 1, - CRIT = 2, - ERR = 3, - WARNING = 4, - NOTICE = 5, - INFO = 6, - DEBUG = 7, -} - ---[[ RFC5424 - 0 kernel messages - 1 user-level messages - 2 mail system - 3 system daemons - 4 security/authorization messages - 5 messages generated internally by syslogd - 6 line printer subsystem - 7 network news subsystem - 8 UUCP subsystem - 9 clock daemon - 10 security/authorization messages - 11 FTP daemon - 12 NTP subsystem - 13 log audit - 14 log alert - 15 clock daemon (note 2) - 16 local use 0 (local0) - 17 local use 1 (local1) - 18 local use 2 (local2) - 19 local use 3 (local3) - 20 local use 4 (local4) - 21 local use 5 (local5) - 22 local use 6 (local6) - 23 local use 7 (local7) ---]] -local FACILITY = { - KERN = lshift(0, 3), - USER = lshift(1, 3), - MAIL = lshift(2, 3), - DAEMON = lshift(3, 3), - AUTH = lshift(4, 3), - SYSLOG = lshift(5, 3), - LPR = lshift(6, 3), - NEWS = lshift(7, 3), - UUCP = lshift(8, 3), - CRON = lshift(9, 3), - CLKD = lshift(9, 3), - AUTHPRIV = lshift(10, 3), - FTP = lshift(11, 3), - NTP = lshift(12, 3), - SECURITY = lshift(13, 3), - AUDIT = lshift(13, 3), - CONSOLE = lshift(14, 3), - ALERT = lshift(14, 3), - CLKD2 = lshift(15, 3), - LOCAL0 = lshift(16, 3), - LOCAL1 = lshift(17, 3), - LOCAL2 = lshift(18, 3), - LOCAL3 = lshift(19, 3), - LOCAL4 = lshift(20, 3), - LOCAL5 = lshift(21, 3), - LOCAL6 = lshift(22, 3), - LOCAL7 = lshift(23, 3), -} - -local LVL2SYSLOG = { - [Log.LVL.EMERG] = SEVERITY.EMERG, - [Log.LVL.ALERT] = SEVERITY.ALERT, - [Log.LVL.FATAL] = SEVERITY.CRIT, - [Log.LVL.ERROR] = SEVERITY.ERR, - [Log.LVL.WARNING] = SEVERITY.WARNING, - [Log.LVL.NOTICE] = SEVERITY.NOTICE, - [Log.LVL.INFO] = SEVERITY.INFO, - [Log.LVL.DEBUG] = SEVERITY.DEBUG, - [Log.LVL.TRACE] = SEVERITY.DEBUG, -} - -local function Date2SysLog(now) - local Y, M, D = now:getdate() - local h, m, s = now:gettime() - - local b = -now:getbias(); - local x = abs(b); - - return fmt("%.4d-%.2d-%.2dT%.2d:%.2d:%.2d%s%.2d:%.2d", Y, M, D, h, m, s, b < 0 and "-" or "+", fix(x / 60), - floor(mod(x, 60))) -end - -local M = {} - -function M.new(facility, host_name, app_name, procid, msgid) - if not facility then - facility = FACILITY.USER - else - facility = FACILITY[facility:upper()] - end - host_name = host_name or '-' - app_name = app_name or '-' - procid = procid or '-' - msgid = msgid or '-' - - -- HOSTNAME APP-NAME PROCID MSGID - local header = host_name .. ' ' .. app_name .. ' ' .. procid .. ' ' .. msgid - - return function(msg, lvl, now) - local slvl = assert(LVL2SYSLOG[lvl]) - return -- HEADER - -- PRI VERSION TIMESTAMP - '<' .. slvl + facility .. '>1 ' .. Date2SysLog(now) .. ' ' .. -- HEADER STRUCTURED-DATA MSG - header .. ' - ' .. msg - - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/async/_private/server.lua b/framework/lualib/zeus/zlog/writer/async/_private/server.lua deleted file mode 100644 index c20687a..0000000 --- a/framework/lualib/zeus/zlog/writer/async/_private/server.lua +++ /dev/null @@ -1,101 +0,0 @@ -local function prequire(...) - local ok, mod = pcall(require, ...) - return ok and mod, mod or nil -end - -local llthreads = prequire "llthreads2" -if not llthreads then - llthreads = require "llthreads" -end - -local runstring = function(code, ...) - code = [[do - local string = require "string" - local os = require "os" - local loadstring = loadstring or load - local lua_init = os.getenv("lua_init") - if lua_init and #lua_init > 0 then - if lua_init:sub(1,1) == '@' then dofile((lua_init:sub(2))) - else assert(loadstring(lua_init))() end - end - end;]] .. code - return llthreads.new(code, ...) -end - -local sleep -do - repeat - local socket = prequire "socket" - if socket then - sleep = function(ms) - socket.sleep(ms / 1000) - end - break - end - - local ztimer = prequire "lzmq.timer" - if ztimer then - sleep = ztimer.sleep - break - end - - -- @todo find another way (use os.execute("sleep " .. ms)) on *nix - - sleep = function() - end - break - until true -end - -local Worker = [=[ -(function(server, maker, logformat, ...) - local Log = require "log" - local logformat = require(logformat).new() - - local loadstring = loadstring or load - local writer = assert(loadstring(maker))() - - require(server).run(writer, Log.close, logformat, ...) -end)(...) -]=] - -local function run_server(server, maker, logformat, ...) - if type(maker) == 'function' then - maker = string.dump(maker) - end - - assert(type(server) == 'string') - assert(type(maker) == 'string') - assert(type(logformat) == 'string') - - local child_thread = assert(runstring(Worker, server, maker, logformat, ...)) - child_thread:start(true, true) - sleep(500) - return -end - -local Z -local function run_zserver(server, maker, logformat, ctx, ...) - Z = Z or require "log.writer.net.zmq._private.compat" - - if type(maker) == 'function' then - maker = string.dump(maker) - end - - assert(type(server) == 'string') - assert(type(maker) == 'string') - assert(type(logformat) == 'string') - assert(Z.is_ctx(ctx)) - - local zthreads = assert(Z.threads) - local child_thread = assert((zthreads.run or zthreads.runstring)(ctx, Worker, server, maker, logformat, ...)) - child_thread:start(true) - return -end - -local M = {} - -M.run = run_server -M.zrun = run_zserver - -return M diff --git a/framework/lualib/zeus/zlog/writer/async/lane.lua b/framework/lualib/zeus/zlog/writer/async/lane.lua deleted file mode 100644 index be1516e..0000000 --- a/framework/lualib/zeus/zlog/writer/async/lane.lua +++ /dev/null @@ -1,22 +0,0 @@ -local server = require "log.writer.async.server.lane" -local packer = require "log.logformat.proxy.pack" - -local function create_writer(channel, maker) - if maker then - server.run(channel, maker, "log.logformat.default") - end - - local queue = server.channel() - local pack = packer.pack - - return function(fmt, ...) - local msg = pack(...) - queue:send(channel, msg) - end -end - -local M = {} - -M.new = create_writer - -return M diff --git a/framework/lualib/zeus/zlog/writer/async/server/lane.lua b/framework/lualib/zeus/zlog/writer/async/server/lane.lua deleted file mode 100644 index d9b21ae..0000000 --- a/framework/lualib/zeus/zlog/writer/async/server/lane.lua +++ /dev/null @@ -1,71 +0,0 @@ -local on_lane_create = function() - local loadstring = loadstring or load - local lua_init = os.getenv("lua_init") - if lua_init and #lua_init > 0 then - if lua_init:sub(1, 1) == '@' then - dofile(lua_init:sub(2)) - else - assert(loadstring(lua_init))() - end - end -end - -local LOG = require "log" -local lanes = require"lanes".configure { - with_timers = false, - on_state_create = on_lane_create, -} -local pack = require"log.logformat.proxy.pack".pack - -local queue - -local function context() - queue = queue or assert(lanes.linda()) - return queue -end - -local function log_thread_fn(maker, logformat, channel) - local log_packer = require "log.logformat.proxy.pack" - local logformat = require(logformat).new() - local unpack = log_packer.unpack - - local loadstring = loadstring or load - local writer = assert(assert(loadstring(maker))()) - while (true) do - local key, val = queue:receive(1.0, channel) - -- print(maker, channel, key, val) - if not (key and val) then - key, val = nil, 'timeout' - end - if key then - local msg, lvl, now = unpack(val) - if msg and lvl and now then - writer(logformat, msg, lvl, now) - end - else - if val ~= 'timeout' then - io.stderror:write('lane_logger: ', val) - end - end - end -end - -local function start_log_thread(...) - local fn = assert(lanes.gen("*", log_thread_fn)) - return assert(fn(...)) -end - -local M = {} - -M.run = function(channel, maker, logformat) - logformat = logformat or "log.logformat.default" - context() -- init context - local child_thread = start_log_thread(maker, logformat, channel) - LOG.add_cleanup(function() - child_thread:cancel(60) - end) -end - -M.channel = context - -return M diff --git a/framework/lualib/zeus/zlog/writer/async/server/udp.lua b/framework/lualib/zeus/zlog/writer/async/server/udp.lua deleted file mode 100644 index 88d8aac..0000000 --- a/framework/lualib/zeus/zlog/writer/async/server/udp.lua +++ /dev/null @@ -1,10 +0,0 @@ -local server = require "log.writer.async._private.server" - -local M = {} - -M.run = function(host, port, maker, logformat) - logformat = logformat or "log.logformat.default" - server.run("log.writer.net.server.udp", maker, logformat, host, port) -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/async/server/zmq.lua b/framework/lualib/zeus/zlog/writer/async/server/zmq.lua deleted file mode 100644 index 3a42277..0000000 --- a/framework/lualib/zeus/zlog/writer/async/server/zmq.lua +++ /dev/null @@ -1,42 +0,0 @@ -local Z = require "log.writer.net.zmq._private.compat" -local IMPL = require "log.writer.net.zmq._private.impl" -local server = require "log.writer.async._private.server" - -local zmq, ETERM, zstrerror, zassert, zrecv = Z.zmq, Z.ETERM, Z.strerror, Z.assert, Z.recv - -local function rand_str(n) - math.randomseed(os.time()) - local str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' - local res = '' - for i = 1, n do - local n = math.random(1, #str) - res = res .. str:sub(n, n) - end - return res -end - -local function create_server(ctx, addr, maker, logformat) - if ctx and not Z.is_ctx(ctx) then - ctx, addr, maker, logformat = nil, ctx, addr, maker - end - logformat = logformat or "log.logformat.default" - - ctx = IMPL.context(ctx) - - if maker then - local addr_sync = 'inproc://' .. rand_str(15) - local skt_sync = zassert(ctx:socket(zmq.PAIR)) - zassert(skt_sync:bind(addr_sync)) - server.zrun("log.writer.net.server.zmq", maker, logformat, ctx, false, 'PULL', addr, addr_sync) - zassert(skt_sync:recv()) - skt_sync:close() - end -end - -local M = {} - -M.run = create_server - -M.context = IMPL.context - -return M diff --git a/framework/lualib/zeus/zlog/writer/async/udp.lua b/framework/lualib/zeus/zlog/writer/async/udp.lua deleted file mode 100644 index a1f0c72..0000000 --- a/framework/lualib/zeus/zlog/writer/async/udp.lua +++ /dev/null @@ -1,18 +0,0 @@ -local server = require "log.writer.async.server.udp" - -local function create_writer(host, port, maker) - if maker then - server.run(host, port, maker, "log.logformat.default") - end - - local writer = require"log.writer.format".new(require"log.logformat.proxy".new(), - require"log.writer.net.udp".new(host, port)) - - return writer -end - -local M = {} - -M.new = create_writer - -return M diff --git a/framework/lualib/zeus/zlog/writer/async/zmq.lua b/framework/lualib/zeus/zlog/writer/async/zmq.lua deleted file mode 100644 index 785223a..0000000 --- a/framework/lualib/zeus/zlog/writer/async/zmq.lua +++ /dev/null @@ -1,21 +0,0 @@ -local Z = require "log.writer.net.zmq._private.compat" -local server = require "log.writer.async.server.zmq" - -local function create_writer(ctx, addr, maker) - if ctx and not Z.is_ctx(ctx) then - ctx, addr, maker = nil, ctx, addr - end - - if maker then - server.run(ctx, addr, maker, "log.logformat.default") - end - - return require"log.writer.format".new(require"log.logformat.proxy".new(), - require"log.writer.net.zmq.push".new(ctx, addr)) -end - -local M = {} - -M.new = create_writer - -return M diff --git a/framework/lualib/zeus/zlog/writer/console.lua b/framework/lualib/zeus/zlog/writer/console.lua deleted file mode 100644 index 09a6aa0..0000000 --- a/framework/lualib/zeus/zlog/writer/console.lua +++ /dev/null @@ -1 +0,0 @@ -return require "log.writer.stdout" diff --git a/framework/lualib/zeus/zlog/writer/console/color.lua b/framework/lualib/zeus/zlog/writer/console/color.lua deleted file mode 100644 index fc18bcb..0000000 --- a/framework/lualib/zeus/zlog/writer/console/color.lua +++ /dev/null @@ -1,334 +0,0 @@ -local io = require "io" -local os = require "os" -local Log = require "log" - -local make_attr, color_writeln, COLORS - -if not COLORS then -- afx cio - local ok, cio = pcall(require, "cio") - if ok then - COLORS = { - BLACK = 'n', - BLUE = 'b', - GREEN = 'g', - CYAN = 'c', - RED = 'r', - MAGENTA = 'm', - BROWN = 'y', - LIGHTGRAY = 'w', - DARKGRAY = 'n+', - LIGHTBLUE = 'b+', - LIGHTGREEN = 'g+', - LIGHTCYAN = 'c+', - LIGHTRED = 'r+', - LIGHTMAGENTA = 'm+', - YELLOW = 'y+', - WHITE = 'w+', - } - make_attr = function(F, B) - return F .. '/' .. B - end - color_writeln = function(attr, text) - cio.textattr(attr) - cio.writeln(text or "") - end - end -end - -if not COLORS then -- conio - local ok, conio = pcall(require, "conio") - if ok then - COLORS = { - BLACK = conio.COLOR_BLACK, - BLUE = conio.COLOR_BLUE, - GREEN = conio.COLOR_GREEN, - CYAN = conio.COLOR_CYAN, - RED = conio.COLOR_RED, - MAGENTA = conio.COLOR_MAGENTA, - BROWN = conio.COLOR_BROWN, - LIGHTGRAY = conio.COLOR_LIGHTGRAY, - DARKGRAY = conio.COLOR_DARKGRAY, - LIGHTBLUE = conio.COLOR_LIGHTBLUE, - LIGHTGREEN = conio.COLOR_LIGHTGREEN, - LIGHTCYAN = conio.COLOR_LIGHTCYAN, - LIGHTRED = conio.COLOR_LIGHTRED, - LIGHTMAGENTA = conio.COLOR_LIGHTMAGENTA, - YELLOW = conio.COLOR_YELLOW, - WHITE = conio.COLOR_WHITE, - } - make_attr = function(F, B) - return {F, B} - end - color_writeln = function(attr, text) - conio.textcolor(attr[1]) - conio.textbackground(attr[2]) - conio.cputs((text or "") .. '\n') - end - end -end - -if not COLORS then -- ansicolors - local IS_WINDOWS = (package.config:sub(1, 1) == '\\') - if IS_WINDOWS and os.getenv("ANSICON") then - IS_WINDOWS = nil - end - local ok, c - if not IS_WINDOWS then - ok, c = pcall(require, "ansicolors") - end - if ok and (type(c) == 'table') then - if c.black then -- version above 1.0.2 - COLORS = { - BLACK = 1, - BLUE = 2, - GREEN = 3, - CYAN = 4, - RED = 5, - MAGENTA = 6, - BROWN = 7, - LIGHTGRAY = 8, - DARKGRAY = 9, - LIGHTBLUE = 10, - LIGHTGREEN = 11, - LIGHTCYAN = 12, - LIGHTRED = 13, - LIGHTMAGENTA = 14, - YELLOW = 15, - WHITE = 16, - } - local reset = tostring(c.reset) - local fore = { - [COLORS.BLACK] = c.black, - [COLORS.BLUE] = c.blue, - [COLORS.GREEN] = c.green, - [COLORS.CYAN] = c.cyan, - [COLORS.RED] = c.red, - [COLORS.MAGENTA] = c.magenta, - [COLORS.BROWN] = c.yellow, - [COLORS.LIGHTGRAY] = c.white, - [COLORS.DARKGRAY] = c.black .. c.bright, - [COLORS.LIGHTBLUE] = c.blue .. c.bright, - [COLORS.LIGHTGREEN] = c.green .. c.bright, - [COLORS.LIGHTCYAN] = c.cyan .. c.bright, - [COLORS.LIGHTRED] = c.red .. c.bright, - [COLORS.LIGHTMAGENTA] = c.magenta .. c.bright, - [COLORS.YELLOW] = c.yellow .. c.bright, - [COLORS.WHITE] = c.white .. c.bright, - } - - local back = { - [COLORS.BLACK] = c.onblack, - [COLORS.BLUE] = c.onblue, - [COLORS.GREEN] = c.ongreen, - [COLORS.CYAN] = c.oncyan, - [COLORS.RED] = c.onred, - [COLORS.MAGENTA] = c.onmagenta, - [COLORS.BROWN] = c.onyellow, - [COLORS.LIGHTGRAY] = c.onwhite, - [COLORS.DARKGRAY] = c.onblack .. c.bright, - [COLORS.LIGHTBLUE] = c.onblue .. c.bright, - [COLORS.LIGHTGREEN] = c.ongreen .. c.bright, - [COLORS.LIGHTCYAN] = c.oncyan .. c.bright, - [COLORS.LIGHTRED] = c.onred .. c.bright, - [COLORS.LIGHTMAGENTA] = c.onmagenta .. c.bright, - [COLORS.YELLOW] = c.onyellow .. c.bright, - [COLORS.WHITE] = c.onwhite .. c.bright, - } - - make_attr = function(F, B) - return fore[F] .. back[B] - end - color_writeln = function(attr, text) - io.write(attr, text, reset, '\n') - end - elseif c.noReset then -- 1.0.2 - COLORS = { - BLACK = 'black', - BLUE = 'blue', - GREEN = 'green', - CYAN = 'cyan', - RED = 'red', - MAGENTA = 'magenta', - BROWN = 'yellow', - LIGHTGRAY = 'white', - DARKGRAY = 'bright black', - LIGHTBLUE = 'bright blue', - LIGHTGREEN = 'bright green', - LIGHTCYAN = 'bright cyan', - LIGHTRED = 'bright red', - LIGHTMAGENTA = 'bright magenta', - YELLOW = 'bright yellow', - WHITE = 'bright white', - } - - make_attr = function(F, B) - return c.noReset("%{" .. F .. " " .. B .. "bg}") - end - local RESET = c.noReset("%{reset}") - color_writeln = function(attr, text) - io.write(attr, (text), RESET, '\n') - end - end - end - if ok and (type(c) == 'function') then - COLORS = { - BLACK = 1, - BLUE = 2, - GREEN = 3, - CYAN = 4, - RED = 5, - MAGENTA = 6, - BROWN = 7, - LIGHTGRAY = 8, - DARKGRAY = 9, - LIGHTBLUE = 10, - LIGHTGREEN = 11, - LIGHTCYAN = 12, - LIGHTRED = 13, - LIGHTMAGENTA = 14, - YELLOW = 15, - WHITE = 16, - } - local fore = { - [COLORS.BLACK] = "%{black}", - [COLORS.BLUE] = "%{blue}", - [COLORS.GREEN] = "%{green}", - [COLORS.CYAN] = "%{cyan}", - [COLORS.RED] = "%{red}", - [COLORS.MAGENTA] = "%{magenta}", - [COLORS.BROWN] = "%{yellow}", - [COLORS.LIGHTGRAY] = "%{white}", - [COLORS.DARKGRAY] = "%{black}" .. "%{bright}", - [COLORS.LIGHTBLUE] = "%{blue}" .. "%{bright}", - [COLORS.LIGHTGREEN] = "%{green}" .. "%{bright}", - [COLORS.LIGHTCYAN] = "%{cyan}" .. "%{bright}", - [COLORS.LIGHTRED] = "%{red}" .. "%{bright}", - [COLORS.LIGHTMAGENTA] = "%{magenta}" .. "%{bright}", - [COLORS.YELLOW] = "%{yellow}" .. "%{bright}", - [COLORS.WHITE] = "%{white}" .. "%{bright}", - } - local back = { - [COLORS.BLACK] = "%{blackbg}", - [COLORS.BLUE] = "%{bluebg}", - [COLORS.GREEN] = "%{greenbg}", - [COLORS.CYAN] = "%{cyanbg}", - [COLORS.RED] = "%{redbg}", - [COLORS.MAGENTA] = "%{magentabg}", - [COLORS.BROWN] = "%{yellowbg}", - [COLORS.LIGHTGRAY] = "%{whitebg}", - [COLORS.DARKGRAY] = "%{blackbg}" .. "%{bright}", - [COLORS.LIGHTBLUE] = "%{bluebg}" .. "%{bright}", - [COLORS.LIGHTGREEN] = "%{greenbg}" .. "%{bright}", - [COLORS.LIGHTCYAN] = "%{cyanbg}" .. "%{bright}", - [COLORS.LIGHTRED] = "%{redbg}" .. "%{bright}", - [COLORS.LIGHTMAGENTA] = "%{magentabg}" .. "%{bright}", - [COLORS.YELLOW] = "%{yellowbg}" .. "%{bright}", - [COLORS.WHITE] = "%{whitebg}" .. "%{bright}", - } - make_attr = function(F, B) - return fore[F] .. back[B] - end - color_writeln = function(attr, text) - io.write(c(attr .. text), '\n') - end - end -end - -if not COLORS then - local ok, term = pcall(require, "term") - if ok then - COLORS = { - BLACK = 1, - BLUE = 2, - GREEN = 3, - CYAN = 4, - RED = 5, - MAGENTA = 6, - BROWN = 7, - LIGHTGRAY = 8, - DARKGRAY = 9, - LIGHTBLUE = 10, - LIGHTGREEN = 11, - LIGHTCYAN = 12, - LIGHTRED = 13, - LIGHTMAGENTA = 14, - YELLOW = 15, - WHITE = 16, - } - - local c = term.colors - local reset = c.reset - local fore = { - [COLORS.BLACK] = c.black, - [COLORS.BLUE] = c.blue, - [COLORS.GREEN] = c.green, - [COLORS.CYAN] = c.cyan, - [COLORS.RED] = c.red, - [COLORS.MAGENTA] = c.magenta, - [COLORS.BROWN] = c.yellow, - [COLORS.LIGHTGRAY] = c.white, - [COLORS.DARKGRAY] = c.black .. c.bright, - [COLORS.LIGHTBLUE] = c.blue .. c.bright, - [COLORS.LIGHTGREEN] = c.green .. c.bright, - [COLORS.LIGHTCYAN] = c.cyan .. c.bright, - [COLORS.LIGHTRED] = c.red .. c.bright, - [COLORS.LIGHTMAGENTA] = c.magenta .. c.bright, - [COLORS.YELLOW] = c.yellow .. c.bright, - [COLORS.WHITE] = c.white .. c.bright, - } - - local back = { - [COLORS.BLACK] = c.onblack, - [COLORS.BLUE] = c.onblue, - [COLORS.GREEN] = c.ongreen, - [COLORS.CYAN] = c.oncyan, - [COLORS.RED] = c.onred, - [COLORS.MAGENTA] = c.onmagenta, - [COLORS.BROWN] = c.onyellow, - [COLORS.LIGHTGRAY] = c.onwhite, - [COLORS.DARKGRAY] = c.onblack .. c.bright, - [COLORS.LIGHTBLUE] = c.onblue .. c.bright, - [COLORS.LIGHTGREEN] = c.ongreen .. c.bright, - [COLORS.LIGHTCYAN] = c.oncyan .. c.bright, - [COLORS.LIGHTRED] = c.onred .. c.bright, - [COLORS.LIGHTMAGENTA] = c.onmagenta .. c.bright, - [COLORS.YELLOW] = c.onyellow .. c.bright, - [COLORS.WHITE] = c.onwhite .. c.bright, - } - - make_attr = function(F, B) - return fore[F] .. back[B] - end - color_writeln = function(attr, text) - io.write(attr .. text .. reset, '\n') - end - end -end - -if not COLORS then -- fallback to console - return require "log.writer.console" -end - -local colors = { - [Log.LVL.EMERG] = make_attr(COLORS.WHITE, COLORS.LIGHTRED), - [Log.LVL.ALERT] = make_attr(COLORS.BLUE, COLORS.LIGHTRED), - [Log.LVL.FATAL] = make_attr(COLORS.BLACK, COLORS.LIGHTRED), - [Log.LVL.ERROR] = make_attr(COLORS.LIGHTRED, COLORS.BLACK), - [Log.LVL.WARNING] = make_attr(COLORS.LIGHTMAGENTA, COLORS.BLACK), - [Log.LVL.NOTICE] = make_attr(COLORS.LIGHTCYAN, COLORS.BLACK), - [Log.LVL.INFO] = make_attr(COLORS.WHITE, COLORS.BLACK), - [Log.LVL.DEBUG] = make_attr(COLORS.YELLOW, COLORS.BLACK), - [Log.LVL.TRACE] = make_attr(COLORS.LIGHTGREEN, COLORS.BLACK), -} - -local function console_writer(fmt, msg, lvl, now) - color_writeln(colors[lvl], fmt(msg, lvl, now)) -end - -local M = {} - -function M.new() - return console_writer -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/file.lua b/framework/lualib/zeus/zlog/writer/file.lua deleted file mode 100644 index c8ad509..0000000 --- a/framework/lualib/zeus/zlog/writer/file.lua +++ /dev/null @@ -1,17 +0,0 @@ -local LOG = require "log" -local file_logger = require "log.writer.file.private.impl" - -local M = {} - -function M.new(opt) - local logger = file_logger:new(opt) - LOG.add_cleanup(function() - logger:close() - end) - - return function(fmt, msg, lvl, now) - logger:write((fmt(msg, lvl, now))) - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/file/by_day.lua b/framework/lualib/zeus/zlog/writer/file/by_day.lua deleted file mode 100644 index 10fb3f1..0000000 --- a/framework/lualib/zeus/zlog/writer/file/by_day.lua +++ /dev/null @@ -1,17 +0,0 @@ -local file = require "log.writer.file" - -local M = {} - -function M.new(log_dir, log_name, max_rows) - return file.new { - log_dir = log_dir, - log_name = log_name, - max_rows = max_rows, - by_day = true, - close_file = false, - flush_interval = 1, - } -end - -return M - diff --git a/framework/lualib/zeus/zlog/writer/file/private/impl.lua b/framework/lualib/zeus/zlog/writer/file/private/impl.lua deleted file mode 100644 index 714a6c7..0000000 --- a/framework/lualib/zeus/zlog/writer/file/private/impl.lua +++ /dev/null @@ -1,484 +0,0 @@ -local Log = require "log" -local io = require "io" -local os = require "os" -local string = require "string" -local date = require "date" -local lfs = require "lfs" - -local DIR_SEP = package.config:sub(1, 1) -local IS_WINDOWS = DIR_SEP == '\\' - -local function remove_dir_end(str) - return (string.gsub(str, '[\\/]+$', '')) -end - -local function ensure_dir_end(str) - return remove_dir_end(str) .. DIR_SEP -end - -local function path_normolize_sep(P) - return (string.gsub(P, '\\', DIR_SEP):gsub('/', DIR_SEP)) -end - -local function path_fullpath(P) - P = path_normolize_sep(P) - local ch1, ch2 = P:sub(1, 1), P:sub(2, 2) - if IS_WINDOWS then - if ch1 == DIR_SEP then -- \temp => c:\temp - local cwd = lfs.currentdir() - local disk = cwd:sub(1, 2) - P = disk .. P - elseif ch1 == '~' then -- ~\temp - local base = os.getenv('USERPROFILE') or (os.getenv('HOMEDRIVE') .. os.getenv('HOMEPATH')) - P = ((ch2 == DIR_SEP) and remove_dir_end(base) or ensure_dir_end(base)) .. string.sub(P, 2) - elseif ch2 ~= ':' then - P = ensure_dir_end(lfs.currentdir()) .. P - end - else - if ch1 == '~' then -- ~/temp - local base = os.getenv('HOME') - P = ((ch2 == DIR_SEP) and remove_dir_end(base) or ensure_dir_end(base)) .. string.sub(P, 2) - else - if P:sub(1, 1) ~= '/' then - P = ensure_dir_end(lfs.currentdir()) .. P - end - end - end - - P = string.gsub(P, DIR_SEP .. '%.' .. DIR_SEP, DIR_SEP):gsub(DIR_SEP .. DIR_SEP, DIR_SEP) - while true do - local first, last = string.find(P, DIR_SEP .. "[^" .. DIR_SEP .. "]+" .. DIR_SEP .. '%.%.' .. DIR_SEP) - if not first then - break - end - P = string.sub(P, 1, first) .. string.sub(P, last + 1) - end - - return P -end - -local function attrib(P, ...) - if IS_WINDOWS then - if #P < 4 and P:sub(2, 2) == ':' then - P = ensure_dir_end(P) -- c: => c:\ - else - P = remove_dir_end(P) -- c:\temp\ => c:\temp - end - end - return lfs.attributes(P, ...) -end - -local function path_exists(P) - return attrib(P, 'mode') ~= nil and P -end - -local function path_isdir(P) - return attrib(P, 'mode') == 'directory' and P -end - -local function path_mkdir(P) - local P = path_fullpath(P) - local p = '' - - for str in string.gmatch(ensure_dir_end(P), '.-' .. DIR_SEP) do - p = p .. str - if path_exists(p) then - if not path_isdir(p) then - return nil, 'can not create ' .. p - end - else - local ok, err = lfs.mkdir(remove_dir_end(p)) - if not ok then - return nil, err .. ' ' .. p - end - end - end - - return true -end - -local function path_getctime(P) - return attrib(P, 'change') -end - -local function path_getmtime(P) - return attrib(P, 'modification') -end - -local function path_getatime(P) - return attrib(P, 'access') -end - -local function path_getsize(P) - return attrib(P, 'size') -end - -local function path_getrows(P) - local f, err = io.open(P, "r") - if not f then - return 0 - end - local count = 0 - for _ in f:lines() do - count = count + 1 - end - f:close() - return count -end - -local function path_remove(P) - return os.remove(P) -end - -local function path_rename(from, to) - path_remove(to) - return os.rename(from, to) -end - -local function reset_out(FileName, rewrite) - local END_OF_LINE = '\n' - local FILE_APPEND = 'a' - - if rewrite then - local FILE_REWRITE = 'w+' - local f, err = io.open(FileName, FILE_REWRITE); - if not f then - return nil, err - end - f:close(); - end - - return function(msg) - local f, err = io.open(FileName, FILE_APPEND) - if not f then - return nil, err - end - f:write(msg, END_OF_LINE) - f:close() - end -end - -local function make_no_close_reset(flush_interval) - return function(FileName, rewrite) - local END_OF_LINE = '\n' - local FILE_APPEND = 'a' - - if rewrite then - local FILE_REWRITE = 'w+' - local f, err = io.open(FileName, FILE_REWRITE); - if not f then - return nil, err - end - f:close() - end - - local f, err = io.open(FileName, FILE_APPEND); - if not f then - return nil, err - end - - local writer - if flush_interval then - local flush_interval, counter = flush_interval, 0 - writer = function(msg) - f:write(msg, END_OF_LINE) - counter = counter + 1 - if counter >= flush_interval then - f:flush() - counter = 0 - end - end - else - writer = function(msg) - f:write(msg, END_OF_LINE) - end - end - return writer, function() - f:close() - end - end -end - -local function split_ext(fname) - local s1, s2 = string.match(fname, '([^\\/]*)([.][^.\\/]*)$') - if s1 then - return s1, s2 - end - s1 = string.match(fname, '([^\\/]+)$') - if s1 then - return s1, '' - end -end - -local function assert_2(f1, f2, v1, v2) - assert(f1 == v1, string.format("Expected '%s' got '%s'", tostring(f1), tostring(v1))) - assert(f2 == v2, string.format("Expected '%s' got '%s'", tostring(f2), tostring(v2))) -end - -assert_2("events", ".log", split_ext("events.log")) -assert_2("events", '', split_ext("events")) -assert_2(nil, nil, split_ext("events\\")) -assert_2('', '.log', split_ext("events\\.log")) -assert_2('log', '', split_ext("events\\log")) - -local file_logger = {} - -local FILE_LOG_DATE_FMT = "%Y%m%d" -local EOL_SIZE = IS_WINDOWS and 2 or 1 - -local function get_file_date(fname) - local mdate = path_getmtime(fname) - if mdate then - mdate = date(mdate):tolocal() - else - mdate = date() - end - return mdate:fmt(FILE_LOG_DATE_FMT) -end - -function file_logger:close() - if self.private_.logger and self.private_.logger_close then - self.private_.logger_close() - end - self.private_.logger = nil - self.private_.logger_close = nil -end - -function file_logger:open() - local full_name = self:current_name() - - local logger, err = self.private_.reset_out(full_name) - if not logger then - return nil, string.format("can not create logger for file '%s':", full_name, err) - end - - self.private_.logger = logger - self.private_.logger_close = err - self.private_.log_date = os.date(FILE_LOG_DATE_FMT) - self.private_.log_rows = 0 - self.private_.log_size = 0 - - return true -end - -function file_logger:current_name() - return self.private_.log_dir .. self.private_.log_name -end - -function file_logger:archive_roll_name(i) - return self.private_.log_dir .. string.format("%s.%.5d.log", self.private_.arc_pfx, i) -end - -function file_logger:archive_date_name(d, i) - return self.private_.log_dir .. string.format("%s.%s.%.5d.log", self.private_.arc_pfx, d, i) -end - -function file_logger:reset_log_by_roll() - self:close() - - local full_name = self:current_name() - local first_name = self:archive_roll_name(1) - - -- we must "free" space for current file - if path_exists(first_name) then - for i = self.private_.roll_count - 1, 1, -1 do - local fname1 = self:archive_roll_name(i) - local fname2 = self:archive_roll_name(i + 1) - path_rename(fname1, fname2) - end - end - - if path_exists(full_name) then - local ok, err = path_rename(full_name, first_name) - if not ok then - return nil, string.format("can not rename '%s' to '%s' : %s", full_name, first_name, err or '') - end - end - - return self:open() -end - -function file_logger:next_date_name(log_date) - local id = self.private_.id - - local fname = self:archive_date_name(log_date, id) - while path_exists(fname) do - id = id + 1 - fname = self:archive_date_name(log_date, id) - end - - self.private_.id = id - return fname -end - -function file_logger:reset_log_by_date(log_date) - self:close() - - local full_name = self:current_name() - if path_exists(full_name) then -- previews file - log_date = log_date or get_file_date(full_name) - local next_fname = self:next_date_name(log_date) - local ok, err = path_rename(full_name, next_fname) - if not ok then - return nil, string.format("can not rename '%s' to '%s' : ", full_name, next_fname, err or '') - end - end - - return self:open() -end - -function file_logger:reset_log(...) - if self.private_.roll_count then - return self:reset_log_by_roll(...) - end - return self:reset_log_by_date(...) -end - -function file_logger:check() - if self.private_.by_day then - local now = os.date(FILE_LOG_DATE_FMT) - if self.private_.log_date ~= now then - local ok, err = self:reset_log_by_date(self.private_.log_date) - self.private_.id = 1 - return ok, err - end - end - - if self.private_.max_rows and (self.private_.log_rows >= self.private_.max_rows) then - return self:reset_log() - end - - if self.private_.max_size and (self.private_.log_size >= self.private_.max_size) then - return self:reset_log() - end - - return true -end - -function file_logger:write(msg) - local ok, err = self:check() - if not ok then - io.stderr:write("logger error: ", err, '\n') - return - end - - self.private_.logger(msg) - self.private_.log_rows = self.private_.log_rows + 1 - self.private_.log_size = self.private_.log_size + #msg + EOL_SIZE -end - -function file_logger:init(opt) - - if (opt.by_day or opt.roll_count) then - assert(not (opt.by_day and opt.roll_count), "Can not set 'by_day' and 'roll_count' fields at the same time!") - end - assert(opt.log_name, 'field log_name is required') - - local log_dir = path_fullpath(opt.log_dir or '.') - - if path_exists(log_dir) then - assert(path_isdir(log_dir)) - else - assert(path_mkdir(log_dir)) - end - - local log_name, log_ext = string.match(opt.log_name, '([^\\/]+)([.][^.\\/]+)$') - assert(log_name and log_ext) - - log_dir = ensure_dir_end(log_dir) - local full_name = log_dir .. log_name .. log_ext - local current_size = path_getsize(full_name) - if 0 == current_size then - -- prevent rename zero size logfile - path_remove(full_name) - end - - local flush_interval = opt.flush_interval and - assert(tonumber(opt.flush_interval), 'flush_interval must be a number') or 1 - self.private_ = { - -- options - log_dir = log_dir, - log_name = log_name .. log_ext, - max_rows = opt.max_rows or math.huge, - max_size = opt.max_size or math.huge, - reset_out = opt.close_file and reset_out or make_no_close_reset(flush_interval), - arc_pfx = opt.archive_prefix or log_name, - roll_count = opt.roll_count and assert(tonumber(opt.roll_count), 'roll_count must be a number'), - by_day = not not opt.by_day, - - -- state - -- log_date = ; -- date when current log file was create - -- log_rows = 0; -- how many lines in current log file - -- log_size = 0; - id = 1, -- numbers of file in current log_date - } - if self.private_.roll_count then - assert(self.private_.roll_count > 0) - end - - local reuse_log = opt.reuse - - if reuse_log and current_size and (current_size > 0) then - self.private_.log_date = get_file_date(full_name) - - if opt.max_rows then - self.private_.log_rows = path_getrows(full_name) or 0 - else - self.private_.log_rows = 0 - end - - if opt.max_size then - self.private_.log_size = path_getsize(full_name) or 0 - else - self.private_.log_size = 0 - end - - local logger, err = self.private_.reset_out(full_name) - if not logger then - error(string.format("can not create logger for file '%s':", full_name, err)) - end - - self.private_.logger = logger - self.private_.logger_close = err - - else - assert(self:reset_log()) - end - - return self -end - -function file_logger:new(...) - local o = setmetatable({}, { - __index = self, - }):init(...) - Log.add_cleanup(function() - o:close() - end) - return o -end - -local function do_profile() - require"profiler".start() - - local logger = file_logger:new{ - log_dir = './logs', - log_name = "events.log", - max_rows = 1000, - max_size = 70, - roll_count = 11, - -- by_day = true; - close_file = false, - flush_interval = 1, - reuse = true, - } - - for i = 1, 10000 do - local msg = string.format("%5d", i) - logger:write(msg) - end - - logger:close() -end - -return file_logger diff --git a/framework/lualib/zeus/zlog/writer/file/roll.lua b/framework/lualib/zeus/zlog/writer/file/roll.lua deleted file mode 100644 index 91f706a..0000000 --- a/framework/lualib/zeus/zlog/writer/file/roll.lua +++ /dev/null @@ -1,18 +0,0 @@ -local file = require "log.writer.file" - -local M = {} - -function M.new(log_dir, log_name, roll_count, max_size) - return file.new { - log_dir = log_dir, - log_name = log_name, - max_size = max_size or 10 * 1024 * 1024, - roll_count = assert(roll_count), - close_file = false, - flush_interval = 1, - reuse = true, - } -end - -return M - diff --git a/framework/lualib/zeus/zlog/writer/filter.lua b/framework/lualib/zeus/zlog/writer/filter.lua deleted file mode 100644 index 0400f10..0000000 --- a/framework/lualib/zeus/zlog/writer/filter.lua +++ /dev/null @@ -1 +0,0 @@ -return require "log.writer.filter.lvl.le" diff --git a/framework/lualib/zeus/zlog/writer/filter/lvl/eq.lua b/framework/lualib/zeus/zlog/writer/filter/lvl/eq.lua deleted file mode 100644 index 53b8abc..0000000 --- a/framework/lualib/zeus/zlog/writer/filter/lvl/eq.lua +++ /dev/null @@ -1,14 +0,0 @@ -local Log = require "log" - -local M = {} - -function M.new(max_lvl, writer) - max_lvl = assert(Log.lvl2number(max_lvl)) - return function(fmt, msg, lvl, now) - if lvl == max_lvl then - writer(fmt, msg, lvl, now) - end - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/filter/lvl/le.lua b/framework/lualib/zeus/zlog/writer/filter/lvl/le.lua deleted file mode 100644 index 599b012..0000000 --- a/framework/lualib/zeus/zlog/writer/filter/lvl/le.lua +++ /dev/null @@ -1,14 +0,0 @@ -local Log = require "log" - -local M = {} - -function M.new(max_lvl, writer) - max_lvl = assert(Log.lvl2number(max_lvl)) - return function(fmt, msg, lvl, now) - if lvl <= max_lvl then - writer(fmt, msg, lvl, now) - end - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/format.lua b/framework/lualib/zeus/zlog/writer/format.lua deleted file mode 100644 index 50a7572..0000000 --- a/framework/lualib/zeus/zlog/writer/format.lua +++ /dev/null @@ -1,9 +0,0 @@ -local M = {} - -function M.new(newfmt, writer) - return function(oldfmt, msg, lvl, now) - writer(newfmt, msg, lvl, now) - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/freeswitch.lua b/framework/lualib/zeus/zlog/writer/freeswitch.lua deleted file mode 100644 index 025a1a8..0000000 --- a/framework/lualib/zeus/zlog/writer/freeswitch.lua +++ /dev/null @@ -1,42 +0,0 @@ -local log = require "log" - -local freeswitch = assert(freeswitch) - -local FS_LVL = { - console = 0, - alert = 1, - crit = 2, - err = 3, - warning = 4, - notice = 5, - info = 6, - debug = 7, -} - -local LOG2FS = { - [log.LVL.EMERG] = FS_LVL.alert, - [log.LVL.ALERT] = FS_LVL.alert, - [log.LVL.FATAL] = FS_LVL.crit, - [log.LVL.ERROR] = FS_LVL.err, - [log.LVL.WARNING] = FS_LVL.warning, - [log.LVL.NOTICE] = FS_LVL.notice, - [log.LVL.INFO] = FS_LVL.info, - [log.LVL.DEBUG] = FS_LVL.debug, - [log.LVL.TRACE] = FS_LVL.debug, -} - -local M = {} - -function M.new(session) - if session then - return function(fmt, msg, lvl, now) - session:consoleLog(LOG2FS[lvl], msg .. '\n') - end - else - return function(fmt, msg, lvl, now) - freeswitch.consoleLog(LOG2FS[lvl], msg .. '\n') - end - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/list.lua b/framework/lualib/zeus/zlog/writer/list.lua deleted file mode 100644 index 77147d4..0000000 --- a/framework/lualib/zeus/zlog/writer/list.lua +++ /dev/null @@ -1,13 +0,0 @@ -local M = {} - -function M.new(...) - local writers = {...} - return function(...) - for i = 1, #writers do - writers[i](...) - end - end -end - -return M - diff --git a/framework/lualib/zeus/zlog/writer/net/server/udp.lua b/framework/lualib/zeus/zlog/writer/net/server/udp.lua deleted file mode 100644 index 9e9ce59..0000000 --- a/framework/lualib/zeus/zlog/writer/net/server/udp.lua +++ /dev/null @@ -1,29 +0,0 @@ -local socket = require "socket" -local log_packer = require "log.logformat.proxy.pack" - -local _M = {} - -function _M.run(writer, final, logformat, host, port) - local uskt = assert(socket.udp()) - assert(uskt:setsockname(host, port)) - local unpack = log_packer.unpack - - while true do - local msg, err = uskt:receivefrom() - if msg then - local msg, lvl, now = unpack(msg) - if msg and lvl and now then - writer(logformat, msg, lvl, now) - end - else - if err ~= 'timeout' then - io.stderr:write('log.writer.net.udp.server: ', err, '\n') - end - end - end - - -- @todo - -- if final then final() end -end - -return _M diff --git a/framework/lualib/zeus/zlog/writer/net/server/zmq.lua b/framework/lualib/zeus/zlog/writer/net/server/zmq.lua deleted file mode 100644 index 24c0855..0000000 --- a/framework/lualib/zeus/zlog/writer/net/server/zmq.lua +++ /dev/null @@ -1,55 +0,0 @@ -local Z = require "log.writer.net.zmq._private.compat" -local IMPL = require "log.writer.net.zmq._private.impl" - -local zmq, ETERM, zstrerror, zassert, zrecv = Z.zmq, Z.ETERM, Z.strerror, Z.assert, Z.recv -local zerrcode = Z.errcode - -local log_packer = require "log.logformat.proxy.pack" - -local _M = {} - -function _M.run(writer, final, logformat, ctx, stype, address, addr_sync) - -- print(writer, logformat, ctx, stype, address, addr_sync) - local stypes = { - SUB = zmq.SUB, - PULL = zmq.PULL, - } - stype = assert(stypes[stype], 'Unsupported socket type') - - ctx = IMPL.context(ctx) - - local skt = zassert(ctx:socket(stype)) - zassert(skt:bind(address)) - - if addr_sync then - local skt_sync = zassert(ctx:socket(zmq.PAIR)) - zassert(skt_sync:connect(addr_sync)) - skt_sync:send("") - skt_sync:close() - end - - local unpack = log_packer.unpack - - while (true) do - local msg, err = zrecv(skt) - if msg then - local msg, lvl, now = unpack(msg) - if msg and lvl and now then - writer(logformat, msg, lvl, now) - end - else - if zerrcode(err) == ETERM then - break - end - io.stderr:write('log.writer.net.zmq.server: ', tostring(err), zstrerror(err), '\n') - end - end - - if final then - final() - end - - skt:close() -end - -return _M diff --git a/framework/lualib/zeus/zlog/writer/net/smtp.lua b/framework/lualib/zeus/zlog/writer/net/smtp.lua deleted file mode 100644 index 994adea..0000000 --- a/framework/lualib/zeus/zlog/writer/net/smtp.lua +++ /dev/null @@ -1,26 +0,0 @@ -local Log = require "log" -local sendmail = require "sendmail" - -local M = {} - -function M.new(from, to, server, subject) - assert(to, "'to' parameter is required") - assert(from, "'from' parameter is required") - assert(server, "'server' parameter is required") - - subject = subject or '' - - return function(fmt, msg, lvl, now) - msg = fmt(msg, lvl, now) - sendmail(from, to, server, { - subject = now:fmt("%F %T") .. ' [' .. Log.LVL_NAMES[lvl] .. '] ' .. subject, - file = { - name = 'message.txt', - data = msg, - }, - text = msg, - }) - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/net/udp.lua b/framework/lualib/zeus/zlog/writer/net/udp.lua deleted file mode 100644 index faf9561..0000000 --- a/framework/lualib/zeus/zlog/writer/net/udp.lua +++ /dev/null @@ -1,19 +0,0 @@ -local socket = require("socket") - -local function create_socket(host, port, timeout) - local skt = assert(socket.udp()) - assert(skt:settimeout(timeout or 0.1)) - assert(skt:setpeername(host, port)) - return skt -end - -local M = {} - -function M.new(host, port, timeout) - local skt = create_socket(host, port, timeout) - return function(fmt, ...) - skt:send((fmt(...))) - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/net/zmq.lua b/framework/lualib/zeus/zlog/writer/net/zmq.lua deleted file mode 100644 index 19e6715..0000000 --- a/framework/lualib/zeus/zlog/writer/net/zmq.lua +++ /dev/null @@ -1 +0,0 @@ -return require "log.writer.net.zmq.pub" diff --git a/framework/lualib/zeus/zlog/writer/net/zmq/_private/compat.lua b/framework/lualib/zeus/zlog/writer/net/zmq/_private/compat.lua deleted file mode 100644 index 24a0e33..0000000 --- a/framework/lualib/zeus/zlog/writer/net/zmq/_private/compat.lua +++ /dev/null @@ -1,150 +0,0 @@ -local function prequire(...) - local ok, mod = pcall(require, ...) - return ok and mod, mod or nil -end - -local zmq, zthreads, zpoller -local zstrerror, zassert, ETERM -local zconnect, zbind -local zrecv_all, zrecv -local zerrcode - -local function has_member(t, key) - local ok, has - if type(key) == "table" then - ok, has = pcall(function() - for _, k in ipairs(key) do - if nil == t[k] then - return false - end - end - return true - end) - else - ok, has = pcall(function() - return nil ~= t[key] - end) - end - return ok and has -end - -local function is_ctx(ctx) - local tname = type(ctx) - if (tname ~= 'table') and (tname ~= 'userdata') then - return false - end - return has_member(ctx, {'socket', 'term'}) -end - -zmq = prequire "lzmq" -if zmq then - zpoller = prequire "lzmq.poller" - zthreads = prequire "lzmq.threads" - ETERM = zmq.errors.ETERM - zstrerror = function(err) - if type(err) == "number" then - return zmq.strerror(err) - end - if type(err) == "string" then - return err - end - return err:msg() - end - zerrcode = function(err) - if type(err) == "number" then - return err - end - if type(err) == "string" then - return err - end -- @todo extract no from string - return err:no() - end - zassert = zmq.assert - zrecv_all = function(skt) - return skt:recv_all() - end - zconnect = function(skt, addr) - return skt:connect(addr) - end - zbind = function(skt, addr) - return skt:bind(addr) - end -else - zmq = require "zmq" - zpoller = require "zmq.poller" - zthreads = prequire "zmq.threads" - ETERM = 'closed' - zstrerror = function(err) - return err - end - zerrcode = function(err) - return err - end - zassert = assert - zrecv_all = function(skt) - local t = {} - local r, err = skt:recv() - if not r then - return nil, err - end - table.insert(t, r) - while skt:rcvmore() == 1 do - r, err = skt:recv() - if not r then - return nil, err, t - end - table.insert(t, r) - end - return t - end - zconnect = function(skt, addr) - if type(addr) == 'table' then - for i, a in ipairs(addr) do - local ok, err = skt:connect(a) - if not ok then - return nil, err, i - end - end - return true - end - return skt:connect(addr) - end - zbind = function(skt, addr) - if type(addr) == 'table' then - for i, a in ipairs(addr) do - local ok, err = skt:bind(a) - if not ok then - return nil, err, i - end - end - return true - end - return skt:bind(addr) - end -end - -zrecv = function(skt) - local ok, err, t = zrecv_all(skt) - if not ok then - if t and t[1] then - return t[1] - end - return nil, err - end - return ok[1] -end - -return { - zmq = zmq, - threads = zthreads, - poller = zpoller, - connect = zconnect, - bind = zbind, - recv_all = zrecv_all, - recv = zrecv, - strerror = zstrerror, - errcode = zerrcode, - assert = zassert, - ETERM = ETERM, - is_ctx = is_ctx, -} diff --git a/framework/lualib/zeus/zlog/writer/net/zmq/_private/impl.lua b/framework/lualib/zeus/zlog/writer/net/zmq/_private/impl.lua deleted file mode 100644 index a7a2cd2..0000000 --- a/framework/lualib/zeus/zlog/writer/net/zmq/_private/impl.lua +++ /dev/null @@ -1,74 +0,0 @@ -local Log = require "log" -local Z = require "log.writer.net.zmq._private.compat" - -local zmq, zthreads = Z.zmq, Z.threads -local zstrerror, zassert = Z.strerror, Z.assert -local ETERM = Z.ETERM -local zconnect, zbind = Z.connect, Z.bind - -local log_ctx - -local function context(ctx) - -- we have to use same context for all writers - if ctx and log_ctx then - assert(ctx == log_ctx) - end - - if log_ctx then - return log_ctx - end - - log_ctx = ctx or (zthreads and zthreads.get_parent_ctx()) or zassert(zmq.init(1)) - - return log_ctx -end - -local function socket(ctx, stype, is_srv, addr, timeout) - local stypes = { - PUSH = zmq.PUSH, - PUB = zmq.PUB, - } - stype = assert(stypes[stype], 'Unsupported socket type') - timeout = timeout or 100 - ctx = context(ctx) - - local skt = ctx:socket(stype) - if ctx.autoclose then - ctx:autoclose(skt) - end - skt:set_sndtimeo(timeout) - skt:set_linger(timeout) - if is_srv then - zassert(zbind(skt, addr)) - else - zassert(zconnect(skt, addr)) - end - if not ctx.autoclose then - Log.add_cleanup(function() - skt:close() - end) - end - return skt -end - -local function init(stype, is_srv) - local M = {} - - function M.new(ctx, addr, timeout) - if ctx and not Z.is_ctx(ctx) then - ctx, addr, timeout = nil, ctx, addr - end - - local skt = socket(ctx, stype, is_srv, addr, timeout) - return function(fmt, ...) - skt:send((fmt(...))) - end - end - - return M -end - -return { - init = init, - context = context, -} diff --git a/framework/lualib/zeus/zlog/writer/net/zmq/pub.lua b/framework/lualib/zeus/zlog/writer/net/zmq/pub.lua deleted file mode 100644 index e365d7d..0000000 --- a/framework/lualib/zeus/zlog/writer/net/zmq/pub.lua +++ /dev/null @@ -1 +0,0 @@ -return require"log.writer.net.zmq._private.impl".init('PUB', false) diff --git a/framework/lualib/zeus/zlog/writer/net/zmq/push.lua b/framework/lualib/zeus/zlog/writer/net/zmq/push.lua deleted file mode 100644 index 517fc43..0000000 --- a/framework/lualib/zeus/zlog/writer/net/zmq/push.lua +++ /dev/null @@ -1 +0,0 @@ -return require"log.writer.net.zmq._private.impl".init('PUSH', false) diff --git a/framework/lualib/zeus/zlog/writer/net/zmq/srv/pub.lua b/framework/lualib/zeus/zlog/writer/net/zmq/srv/pub.lua deleted file mode 100644 index 0ca1db8..0000000 --- a/framework/lualib/zeus/zlog/writer/net/zmq/srv/pub.lua +++ /dev/null @@ -1 +0,0 @@ -return require"log.writer.net.zmq._private.impl".init('PUB', true) diff --git a/framework/lualib/zeus/zlog/writer/prefix.lua b/framework/lualib/zeus/zlog/writer/prefix.lua deleted file mode 100644 index 9fb4202..0000000 --- a/framework/lualib/zeus/zlog/writer/prefix.lua +++ /dev/null @@ -1,9 +0,0 @@ -local M = {} - -function M.new(prefix, writer) - return function(fmt, msg, lvl, now) - writer(fmt, prefix .. msg, lvl, now) - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/stderr.lua b/framework/lualib/zeus/zlog/writer/stderr.lua deleted file mode 100644 index 34a7ba1..0000000 --- a/framework/lualib/zeus/zlog/writer/stderr.lua +++ /dev/null @@ -1,11 +0,0 @@ -local io = require "io" - -local M = {} - -function M.new() - return function(fmt, ...) - io.stderr:write(fmt(...), '\n') - end -end - -return M diff --git a/framework/lualib/zeus/zlog/writer/stdout.lua b/framework/lualib/zeus/zlog/writer/stdout.lua deleted file mode 100644 index f2a5f99..0000000 --- a/framework/lualib/zeus/zlog/writer/stdout.lua +++ /dev/null @@ -1,11 +0,0 @@ -local io = require "io" - -local M = {} - -function M.new() - return function(fmt, ...) - io.stdout:write(fmt(...), '\n') - end -end - -return M diff --git a/framework/service/zlogd.lua b/framework/service/zlogd.lua new file mode 100644 index 0000000..ed5b6e0 --- /dev/null +++ b/framework/service/zlogd.lua @@ -0,0 +1,177 @@ +local skynet = require "skynet" +local log_define = require "zlog.log_define" +local queue = require "skynet.queue" +require "skynet.manager" + +local LOG_LEVEL = log_define.LOG_LEVEL +local DEFAULT_CATEGORY = log_define.DEFAULT_CATEGORY +local log_format = log_define.format +local color = log_define.color +local string_match = string.match + +local skynet_env = require("skynet.env") +local nodeid = skynet_env.get("nodeid") + +local zenv = require("zenv.init") +local define = zenv.Logger + +local log_root = define.log_root +local log_level = define.log_level or LOG_LEVEL.INFO +local log_console = define.log_console + +local name = zenv.get_node_conf(nodeid).name +local log_prefix = name .. "_" + +local last_day = -1 +local category = ... +local is_master = not category +local category_addr = {} +local lock = queue() +local file + +local function close_file() + if not file then + return + end + file:close() + file = nil +end + +local function open_file(date) + date = date or os.date("*t") + + local dir = log_define.log_dir(log_root, date) + if not os.rename(dir, dir) then + os.execute("mkdir -p " .. dir) + end + + if file then + close_file() + end + + local path = log_define.log_path(dir, log_prefix, category, date) + local f, e = io.open(path, "a") + if not f then + print("logger error:", tostring(e)) + return + end + + file = f + last_day = date.day +end + +local CMD = {} + +function CMD.console(level, msg) + print(color(level, msg)) +end + +function CMD.log(level, msg) + if level < log_level then + return + end + + msg = msg or "" + local date = os.date("*t") + if not file or date.day ~= last_day then + open_file(date) + end + + file:write(msg .. '\n') + file:flush() + + if log_console then + if is_master then + CMD.console(level, msg) + else + skynet.call(".logger", "lua", "console", level, msg) + end + end +end + +function CMD.set_console(is_open) + log_console = is_open + if is_master then + for _, addr in pairs(category_addr) do + skynet.call(addr, "lua", "set_console", is_open) + end + end +end + +function CMD.set_level(level) + log_level = level + if is_master then + for _, addr in pairs(category_addr) do + skynet.call(addr, "lua", "set_level", level) + end + end +end + +function CMD.get_service(cate) + if not is_master then + return + end + + local addr + lock(function() + addr = category_addr[cate] + if not addr then + addr = skynet.newservice("logger", cate) + category_addr[cate] = addr + end + end) + return addr +end + +if is_master then + + skynet.info_func(function() + return { + log_console = log_console, + log_level = log_level, + } + end) + + skynet.register_protocol { + name = "text", + id = skynet.PTYPE_TEXT, + unpack = skynet.tostring, + dispatch = function(_, addr, msg) + local level = LOG_LEVEL.INFO + if string_match(msg, "maybe in an endless loop") then + level = LOG_LEVEL.WARN + end + if string_match(msg, "stack traceback:") then + level = LOG_LEVEL.ERROR + end + msg = log_format(addr, level, nil, msg) + CMD.log(level, msg) + end, + } + + skynet.register_protocol { + name = "SYSTEM", + id = skynet.PTYPE_SYSTEM, + unpack = function(...) + return ... + end, + dispatch = function(_, addr) + local level = LOG_LEVEL.FATAL + local msg = log_format(addr, level, nil, "SIGHUP") + CMD.log(level, msg) + end, + } + + category_addr[DEFAULT_CATEGORY] = skynet.self() + skynet.register(".logger") +end + +open_file() + +skynet.start(function() + skynet.dispatch("lua", function(_, _, cmd, ...) + local f = CMD[cmd] + assert(f, cmd) + return skynet.retpack(f(...)) + end) +end)