diff --git a/extend/lualog/lualog/lualog.cpp b/extend/lualog/lualog/lualog.cpp index f360386d..a3beb03e 100644 --- a/extend/lualog/lualog/lualog.cpp +++ b/extend/lualog/lualog/lualog.cpp @@ -8,36 +8,44 @@ using namespace luakit; namespace logger { thread_local luabuf buf; - string read_args(lua_State* L, int index) { + string read_args(lua_State* L, int flag, int index) { switch (lua_type(L, index)) { case LUA_TNIL: return "nil"; case LUA_TTHREAD: return "thread"; case LUA_TFUNCTION: return "function"; case LUA_TUSERDATA: return "userdata"; case LUA_TLIGHTUSERDATA: return "userdata"; - case LUA_TBOOLEAN: return (lua_tointeger(L, index) == 1) ? "true" : "false"; case LUA_TSTRING: return lua_tostring(L, index); - case LUA_TTABLE: { - buf.clean(); - serialize_one(L, &buf, index, 1, false); - return (char*)buf.head(); - } - case LUA_TNUMBER: { - return lua_isinteger(L, index) ? to_string(lua_tointeger(L, index)) : to_string(lua_tonumber(L, index)); - } + case LUA_TBOOLEAN: return (lua_tointeger(L, index) == 1) ? "true" : "false"; + case LUA_TTABLE: + if ((flag & 0x01) == 0x01) { + buf.clean(); + serialize_one(L, &buf, index, 1, (flag & 0x02) == 0x02); + return (char*)buf.head(); + } + return luaL_tolstring(L, index, nullptr); + case LUA_TNUMBER: + if (lua_isinteger(L, index)) { + return fmt::format("{}", lua_tointeger(L, index)); + } + return fmt::format("{}", lua_tonumber(L, index)); } return "unsuppert data type"; } - template - string vvformat(vstring vfmt, Args... args) { - return fmt::format(vfmt, args...); - } - - template - void tformat(lua_State* L, string& msg, vstring vfmt, std::index_sequence&&) { - msg = vvformat(vfmt, read_args(L, integers + 3)...); + int tformat(lua_State* L, log_level lvl, vstring tag, vstring feature, int flag, vstring vfmt, std::index_sequence&&) { + try { + auto msg = fmt::format(vfmt, read_args(L, flag, integers + 6)...); + get_logger()->output(lvl, msg, tag, feature); + if (lvl == log_level::LOG_LEVEL_FATAL) { + lua_pushlstring(L, msg.c_str(), msg.size()); + return 1; + } + } catch (const exception& e) { + luaL_error(L, "log format failed: %s!", e.what()); + } + return 0; } luakit::lua_table open_lualog(lua_State* L) { @@ -52,23 +60,27 @@ namespace logger { "FATAL", log_level::LOG_LEVEL_FATAL ); - lualog.set_function("test", [](lua_State* L, vstring vfmt, bool perty) { - std::string msg; - int arg_num = lua_gettop(L) - 2; + lualog.set_function("print", [](lua_State* L) { + log_level lvl = (log_level)lua_tointeger(L, 1); + if (get_logger()->is_filter(lvl)) return 0; + size_t flag = lua_tointeger(L, 2); + vstring tag = lua_to_native(L, 3); + vstring feature = lua_to_native(L, 4); + vstring vfmt = lua_to_native(L, 5); + int arg_num = lua_gettop(L) - 5; switch (arg_num) { - case 0: tformat(L, msg, vfmt, make_index_sequence<0>{}); break; - case 1: tformat(L, msg, vfmt, make_index_sequence<1>{}); break; - case 2: tformat(L, msg, vfmt, make_index_sequence<2>{}); break; - case 3: tformat(L, msg, vfmt, make_index_sequence<3>{}); break; - case 4: tformat(L, msg, vfmt, make_index_sequence<4>{}); break; - case 5: tformat(L, msg, vfmt, make_index_sequence<5>{}); break; - case 6: tformat(L, msg, vfmt, make_index_sequence<6>{}); break; - case 7: tformat(L, msg, vfmt, make_index_sequence<7>{}); break; - case 8: tformat(L, msg, vfmt, make_index_sequence<8>{}); break; + case 0: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<0>{}); + case 1: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<1>{}); + case 2: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<2>{}); + case 3: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<3>{}); + case 4: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<4>{}); + case 5: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<5>{}); + case 6: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<6>{}); + case 7: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<7>{}); + case 8: return tformat(L, lvl, tag, feature, flag, vfmt, make_index_sequence<8>{}); default: luaL_error(L, "test args is more than 8!"); break; } - lua_pushlstring(L, msg.c_str(), msg.size()); - return 1; + return 0; }); lualog.set_function("daemon", [](bool status) { get_logger()->daemon(status); }); @@ -85,12 +97,6 @@ namespace logger { lualog.set_function("add_dest", [](vstring feature, vstring log_path) { return get_logger()->add_dest(feature, log_path); }); lualog.set_function("add_file_dest", [](vstring feature, vstring fname) { return get_logger()->add_file_dest(feature, fname); }); lualog.set_function("set_dest_clean_time", [](vstring feature, size_t time) { get_logger()->set_dest_clean_time(feature, time); }); - lualog.set_function("info", [](vstring msg, vstring tag, vstring feature) { get_logger()->output(log_level::LOG_LEVEL_INFO, msg, tag, feature); }); - lualog.set_function("warn", [](vstring msg, vstring tag, vstring feature) { get_logger()->output(log_level::LOG_LEVEL_WARN, msg, tag, feature); }); - lualog.set_function("dump", [](vstring msg, vstring tag, vstring feature) { get_logger()->output(log_level::LOG_LEVEL_DUMP, msg, tag, feature); }); - lualog.set_function("debug", [](vstring msg, vstring tag, vstring feature) { get_logger()->output(log_level::LOG_LEVEL_DEBUG, msg, tag, feature); }); - lualog.set_function("error", [](vstring msg, vstring tag, vstring feature) { get_logger()->output(log_level::LOG_LEVEL_ERROR, msg, tag, feature); }); - lualog.set_function("fatal", [](vstring msg, vstring tag, vstring feature) { get_logger()->output(log_level::LOG_LEVEL_FATAL, msg, tag, feature); }); lualog.set_function("option", [](vstring log_path, vstring service, vstring index) { get_logger()->option(log_path, service, index); }); return lualog; } diff --git a/script/agent/monitor_agent.lua b/script/agent/monitor_agent.lua index 028b91e5..6be228cd 100644 --- a/script/agent/monitor_agent.lua +++ b/script/agent/monitor_agent.lua @@ -1,7 +1,6 @@ --monitor_agent.lua local RpcClient = import("network/rpc_client.lua") -local odate = os.date local tunpack = table.unpack local signal_quit = signal.quit local env_addr = environ.addr @@ -12,25 +11,17 @@ local log_debug = logger.debug local log_filter = logger.filter local qfailed = quanta.failed -local sfind = string.find -local sformat = string.format -local ssplit = qstring.split local shotfix = signal.hotfix -local event_mgr = quanta.get("event_mgr") -local update_mgr = quanta.get("update_mgr") -local thread_mgr = quanta.get("thread_mgr") +local event_mgr = quanta.get("event_mgr") +local update_mgr = quanta.get("update_mgr") -local PULL_CNT_MAX = 10 -local ROUTER = quanta.enum("QuantaMode", "ROUTER") -local SUCCESS = quanta.enum("KernCode", "SUCCESS") -local RPC_FAILED = quanta.enum("KernCode", "RPC_FAILED") -local RECONNECT_TIME = quanta.enum("NetwkTime", "RECONNECT_TIME") +local ROUTER = quanta.enum("QuantaMode", "ROUTER") +local RPC_FAILED = quanta.enum("KernCode", "RPC_FAILED") local MonitorAgent = singleton() local prop = property(MonitorAgent) prop:reader("client", nil) -prop:reader("sessions", {}) prop:reader("ready_watchers", {}) prop:reader("close_watchers", {}) @@ -39,7 +30,6 @@ function MonitorAgent:__init() local ip, port = env_addr("QUANTA_MONITOR_ADDR") self.client = RpcClient(self, ip, port) --注册事件 - event_mgr:add_listener(self, "rpc_remote_log") event_mgr:add_listener(self, "rpc_remote_message") event_mgr:add_listener(self, "rpc_service_changed") event_mgr:add_listener(self, "rpc_service_hotfix") @@ -51,16 +41,6 @@ function MonitorAgent:__init() update_mgr:attach_second5(self) end -function MonitorAgent:on_second5() - local now = quanta.now - for session_id, session in pairs(self.sessions) do - if now - session.active_time > RECONNECT_TIME then - log_debug("[RemoteLog][on_timer]->overdue->session_id:%s", session_id) - self:close_session(session_id) - end - end -end - function MonitorAgent:on_router_connected() self.client:register() event_mgr:notify_trigger("on_service_startup") @@ -146,80 +126,6 @@ function MonitorAgent:rpc_set_logger_level(level) log_filter(level) end ---日志监控 ----------------------------------------------- -function MonitorAgent:open_session(data) - local session_id = data.session_id - if not session_id then - session_id = thread_mgr:build_session_id() - end - local session = self.sessions[session_id] - if not session then - session = { - pull_index = 0, - cache_logs = {}, - filters = {}, - session_id = session_id, - } - self.sessions[session_id] = session - end - if data.filters then - session.filters = ssplit(data.filters, " ") - end - session.active_time = quanta.now - return session -end - -function MonitorAgent:close_session(session_id) - self.sessions[session_id] = nil - if not next(self.sessions) then - logger.remove_monitor(self) - end -end - -function MonitorAgent:dispatch_log(content, lvl_name) - for _, session in pairs(self.sessions) do - local cache = false - if #session.filters == 0 then - cache = true - goto docache - end - for _, filter in pairs(session.filters) do - if sfind(content, filter) then - cache = true - goto docache - end - end - :: docache :: - if cache then - local cache_logs = session.cache_logs - cache_logs[#cache_logs + 1] = sformat("[%s][%s]%s", odate("%Y-%m-%d %H:%M:%S"), lvl_name, content) - end - end -end - -function MonitorAgent:rpc_remote_log(data) - if not next(self.sessions) then - logger.add_monitor(self) - end - local show_logs = {} - local session = self:open_session(data) - local log_size = #(session.cache_logs) - local log_cnt = log_size - session.pull_index - if log_cnt > 0 then - local count = log_cnt > PULL_CNT_MAX and PULL_CNT_MAX or log_cnt - for idx = 1, count do - show_logs[#show_logs + 1] = session.cache_logs[session.pull_index + idx] - end - session.pull_index = session.pull_index + count - if session.pull_index >= log_size then - session.cache_logs = {} - session.pull_index = 0 - end - end - return SUCCESS, { logs = show_logs, session_id = session.session_id } -end - quanta.monitor = MonitorAgent() return MonitorAgent diff --git a/script/basic/logger.lua b/script/basic/logger.lua index f93d93ae..462c85a6 100644 --- a/script/basic/logger.lua +++ b/script/basic/logger.lua @@ -3,18 +3,14 @@ local pcall = pcall local pairs = pairs -local tpack = table.pack local tunpack = table.unpack local dgetinfo = debug.getinfo local sformat = string.format -local lwarn = log.warn +local lprint = log.print local lfilter = log.filter -local lis_filter = log.is_filter -local serialize = luakit.serialize local LOG_LEVEL = log.LOG_LEVEL -local dispatching = false local title = quanta.title local monitors = _ENV.monitors or {} @@ -54,59 +50,53 @@ function logger.filter(level) end end -local function logger_output(feature, notify, lvl, lvl_name, fmt, log_conf, ...) - if lis_filter(lvl) then +local function logger_format(flag, feature, lvl, lvl_name, fmt, ...) + local ok, msg = pcall(sformat, fmt, ...) + if not ok then + local info = dgetinfo(4, "S") + local wfmt = "[logger][{}] format failed: {}, source({}:{})" + lprint(LOG_LEVEL.WARN, 0, title, feature, wfmt, lvl_name, msg, info.short_src, info.linedefined) return end - local content - local lvl_func, extend, swline = tunpack(log_conf) - if extend then - local args = tpack(...) - for i, arg in pairs(args) do - if type(arg) == "table" then - args[i] = serialize(arg, swline and 1 or 0) - end - end - content = sformat(fmt, tunpack(args, 1, args.n)) - else - content = sformat(fmt, ...) + lprint(lvl, flag, title, feature, msg) +end + +local function logger_output(flag, feature, lvl, lvl_name, fmt, ...) + if not fmt:find("{") then + return logger_format(flag, feature, lvl, lvl_name, fmt, ...) end - lvl_func(content, title, feature) - if notify and not dispatching then - --防止重入 - dispatching = true - for monitor, mlvl in pairs(monitors) do - if lvl >= mlvl then - monitor:dispatch_log(content, lvl_name) - end - end - dispatching = false + local ok, msg = pcall(lprint, lvl, flag, title, feature, fmt, ...) + if not ok then + local info = dgetinfo(3, "S") + local wfmt = "[logger][{}] format failed: {}, source({}:{})" + lprint(LOG_LEVEL.WARN, 0, title, feature, wfmt, lvl_name, msg, info.short_src, info.linedefined) + return end + return msg end local LOG_LEVEL_OPTIONS = { - [LOG_LEVEL.INFO] = { "info", { log.info, false, false } }, - [LOG_LEVEL.WARN] = { "warn", { log.warn, true, false } }, - [LOG_LEVEL.DUMP] = { "dump", { log.dump, true, true } }, - [LOG_LEVEL.DEBUG] = { "debug", { log.debug, true, false } }, - [LOG_LEVEL.ERROR] = { "err", { log.error, true, false } }, - [LOG_LEVEL.FATAL] = { "fatal", { log.fatal, true, false } } + [LOG_LEVEL.INFO] = { "info", 0x00 }, + [LOG_LEVEL.WARN] = { "warn", 0x01 }, + [LOG_LEVEL.DEBUG] = { "debug", 0x01 }, + [LOG_LEVEL.ERROR] = { "err", 0x01 }, + [LOG_LEVEL.FATAL] = { "fatal", 0x01 }, + [LOG_LEVEL.DUMP] = { "dump", 0x01 | 0x02 }, } for lvl, conf in pairs(LOG_LEVEL_OPTIONS) do - local lvl_name, log_conf = tunpack(conf) + local lvl_name, flag = tunpack(conf) logger[lvl_name] = function(fmt, ...) - local ok, res = pcall(logger_output, "", true, lvl, lvl_name, fmt, log_conf, ...) - if not ok then - local info = dgetinfo(2, "S") - lwarn(sformat("[logger][%s] format failed: %s, source(%s:%s)", lvl_name, res, info.short_src, info.linedefined)) - return false + local msg = logger_output(flag, "", lvl, lvl_name, fmt, ...) + if msg then + for monitor in pairs(monitors) do + monitor:dispatch_log(msg, lvl_name) + end end - return res end end for lvl, conf in pairs(LOG_LEVEL_OPTIONS) do - local lvl_name, log_conf = tunpack(conf) + local lvl_name, flag = tunpack(conf) logfeature[lvl_name] = function(feature, path, prefix, clean_time) log.add_dest(feature, path) log.ignore_prefix(feature, prefix) @@ -114,13 +104,7 @@ for lvl, conf in pairs(LOG_LEVEL_OPTIONS) do log.set_dest_clean_time(feature, clean_time) end return function(fmt, ...) - local ok, res = pcall(logger_output, feature, false, lvl, lvl_name, fmt, log_conf, ...) - if not ok then - local info = dgetinfo(2, "S") - lwarn(sformat("[logfeature][%s] format failed: %s, source(%s:%s)", lvl_name, res, info.short_src, info.linedefined)) - return false - end - return res + logger_output(flag, feature, lvl, lvl_name, fmt, ...) end end end \ No newline at end of file