local skynet = require "skynet" require "skynet.manager" local serverId = tonumber(skynet.getenv "serverId") local MAIN_LOG_NAME = "skynet" local ZERO_MOVE_TIME = 0 --second local DEFAULT_FILE_MODE = "a" local init = false local log_service = {} local service_file = {} local fileName = "" local log_service_no_change = {} local dir_path = {} local file_mode = {} local is_daemon = skynet.getenv("daemon") ~= nil is_daemon = true local log_path = skynet.getenv("logpath") local serverId = tonumber(skynet.getenv "serverId") local function check_exists(path) if not os.rename(path, path) then os.execute("mkdir " .. path) end end local function time_dir() local now = math.floor(skynet.time()) local curr_time = {} curr_time.year = os.date("%Y", now) curr_time.month = os.date("%m", now) curr_time.day = os.date("%d", now) log_path = skynet.getenv("logpath") check_exists(log_path) for _, path in pairs(dir_path) do check_exists(log_path..path) end log_path = string.format("log/Server_%d/%d-%d-%d/", serverId,curr_time.year,curr_time.month,curr_time.day) check_exists(log_path) for _, path in pairs(dir_path) do check_exists(log_path..path) end for source, file in pairs(service_file) do if not log_service_no_change[source] then service_file[source] = nil io.close(file) end end local tomorrow_zore_time = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day, hour=0,min=0,sec=0}) + 86400 + ZERO_MOVE_TIME skynet.timeout((tomorrow_zore_time-now)*100, function() time_dir() end ) end local function file_path(path_file) return log_path .. path_file .. ".log" end local function try_open_file(source) local now = math.floor(skynet.time()) local year = os.date("%Y", now) local month = os.date("%m", now) local day = os.date("%d", now) local hour = os.date("%H", now) local path_file = string.format("%d-%d-%d-%d-%d",serverId,year,month,day,hour) local opend_file = service_file[0] if log_service[source] then path_file = log_service[source] opend_file = service_file[source] end if opend_file and path_file == fileName then return opend_file end local args = DEFAULT_FILE_MODE if file_mode[source] then args = file_mode[source] end local f, e = io.open(file_path(path_file), args) if not f then print("error", path_file) return end fileName = path_file if log_service[source] then service_file[source] = f else service_file[0] = f end return f end local function log_time() local now = math.floor(skynet.time()) return string.format("%02d:%02d:%02d", tonumber(os.date("%H", now)), tonumber(os.date("%M", now)), tonumber(os.date("%S", now))) end local CMD = {} local logging_fun = function(str) print(str) end if is_daemon then logging_fun = function(str, source) local opend_file = try_open_file(source) opend_file:write(str .. '\n') opend_file:flush() end end function CMD.logging(source, type, str) str = string.format("[:%08x][%s][%s] %s", source, log_time(), type, str) print(str) logging_fun(str, source) end function CMD.separate(source, path, file, no_change_dir, mode) if is_daemon then file_mode[source] = mode or DEFAULT_FILE_MODE check_exists(log_path..path) dir_path[source] = path log_service[source] = path.."/"..file if no_change_dir then log_service_no_change[source] = true end end end function CMD.close(source) if is_daemon and log_service[source] and service_file[source] then io.close(service_file[source]) log_service[source] = nil service_file[source] = nil file_mode[source] = nil end end function CMD.forward(source, path, file, no_change_dir, mode) if is_daemon then if not path then CMD.close(source) else CMD.close(source) CMD.separate(source, path, file, no_change_dir) file_mode[source] = mode or DEFAULT_FILE_MODE end end end skynet.register_protocol { name = "text", id = skynet.PTYPE_TEXT, unpack = skynet.tostring, dispatch = function(session, source, msg) CMD.logging(source, "SKYNET", msg) end } skynet.register_protocol { name = "SYSTEM", id = skynet.PTYPE_SYSTEM, unpack = function(...) return ... end, dispatch = function(_, source) CMD.reopen(source, "SIGHUP", "SIGHUP") end } time_dir() skynet.start(function() skynet.register(".logger") skynet.dispatch("lua", function(session, source, cmd, ...) local f = assert(CMD[cmd], cmd .. " not found") if session > 0 then skynet.ret(skynet.pack(f(source, ...))) else f(source, ...) end end) end)