You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
3.9 KiB
Lua

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)