mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
lua logger
This commit is contained in:
87
lualib/log.lua
Normal file
87
lualib/log.lua
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
local Logger = require("logger")
|
||||||
|
|
||||||
|
local l = Logger:new()
|
||||||
|
l.stack_level = l.stack_level + 1
|
||||||
|
|
||||||
|
local logging = {}
|
||||||
|
|
||||||
|
logging.NOLOG = l.NOLOG
|
||||||
|
logging.DEBUG = l.DEBUG
|
||||||
|
logging.INFO = l.INFO
|
||||||
|
logging.WARNING = l.WARNING
|
||||||
|
logging.ERROR = l.ERROR
|
||||||
|
logging.CRITICAL = l.CRITICAL
|
||||||
|
logging.FATAL = l.FATAL
|
||||||
|
--
|
||||||
|
-- public interface
|
||||||
|
--
|
||||||
|
function logging.Debug(...)
|
||||||
|
l:Debug(...)
|
||||||
|
end
|
||||||
|
function logging.Debugf(format, ...)
|
||||||
|
l:Debugf(format, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Info(...)
|
||||||
|
l:Info(...)
|
||||||
|
end
|
||||||
|
function logging.Infof(format, ...)
|
||||||
|
l:Infof(format, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Warning(...)
|
||||||
|
l:Warning(...)
|
||||||
|
end
|
||||||
|
function logging.Warningf(format, ...)
|
||||||
|
l:Warningf(format, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Error(...)
|
||||||
|
l:Error(...)
|
||||||
|
end
|
||||||
|
function logging.Errorf(format, ...)
|
||||||
|
l:Errorf(format, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Critical(...)
|
||||||
|
l:Critical(...)
|
||||||
|
end
|
||||||
|
function logging.Criticalf(format, ...)
|
||||||
|
l:Criticalf(format, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Fatal(...)
|
||||||
|
l:Fatal(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Fatalf(format, ...)
|
||||||
|
l:Fatalf(format,...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Assert(v, message)
|
||||||
|
return l:Assert(v,message)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.SError(message, level)
|
||||||
|
level = level and level+1 or 2
|
||||||
|
return l:SError(message, level)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Tag(key, value)
|
||||||
|
l:Tag(key,value)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.Untag(key)
|
||||||
|
l:Untag(key)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.set_modname(name)
|
||||||
|
l:set_modname(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logging.config(t)
|
||||||
|
l:config(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
return logging
|
||||||
|
|
||||||
320
lualib/logger.lua
Normal file
320
lualib/logger.lua
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
local Skynet = require("skynet")
|
||||||
|
local assert = assert
|
||||||
|
local error = error
|
||||||
|
local print = print
|
||||||
|
local tconcat = table.concat
|
||||||
|
local tinsert = table.insert
|
||||||
|
local srep = string.rep
|
||||||
|
local type = type
|
||||||
|
local pairs = pairs
|
||||||
|
local tostring = tostring
|
||||||
|
local next = next
|
||||||
|
|
||||||
|
local logger = {}
|
||||||
|
|
||||||
|
-- public field
|
||||||
|
logger.NOLOG = 0
|
||||||
|
logger.DEBUG = 10
|
||||||
|
logger.INFO = 20
|
||||||
|
logger.WARNING = 30
|
||||||
|
logger.ERROR = 40
|
||||||
|
logger.CRITICAL = 50
|
||||||
|
logger.FATAL = 60
|
||||||
|
|
||||||
|
local function log_to_disk(...)
|
||||||
|
Skynet.send(".lualog" , Skynet.pack(...))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dump_log_to_disk(t)
|
||||||
|
for i=1,#t do
|
||||||
|
log_to_disk(table.unpack(t[i]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- log helper fun
|
||||||
|
--
|
||||||
|
|
||||||
|
local function get_log_src(level)
|
||||||
|
local info = debug.getinfo(level+1, "Sl")
|
||||||
|
local src = info.source
|
||||||
|
return src .. ":" .. info.currentline .. ":"
|
||||||
|
end
|
||||||
|
|
||||||
|
local starttime = Skynet.starttime()
|
||||||
|
|
||||||
|
local function log_timestamp(timestamp)
|
||||||
|
local sec = timestamp / 100
|
||||||
|
local ms = timestamp % 100
|
||||||
|
local f = os.date("%Y-%m-%d %H:%M:%S",starttime + sec)
|
||||||
|
f = string.format("%s.%02d",f,ms)
|
||||||
|
return f
|
||||||
|
end
|
||||||
|
|
||||||
|
local function table_serialize(root)
|
||||||
|
local cache = { [root] = "." }
|
||||||
|
local function _dump(t,space,name)
|
||||||
|
local temp = {}
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
local key = tostring(k)
|
||||||
|
if cache[v] then
|
||||||
|
tinsert(temp,"+" .. key .. " {" .. cache[v].."}")
|
||||||
|
elseif type(v) == "table" then
|
||||||
|
local new_key = name .. "." .. key
|
||||||
|
cache[v] = new_key
|
||||||
|
tinsert(temp,"+" .. key .. _dump(v,space .. (next(t,k) and "|" or " " ).. srep(" ",#key),new_key))
|
||||||
|
else
|
||||||
|
tinsert(temp,"+" .. key .. " [" .. tostring(v).."]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return tconcat(temp,"\n"..space)
|
||||||
|
end
|
||||||
|
return (_dump(root, "",""))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function log_format(level, ...)
|
||||||
|
local t = {...}
|
||||||
|
local out = ''
|
||||||
|
for _,v in pairs(t) do
|
||||||
|
if level <= logger.DEBUG and type(v) == "table" then
|
||||||
|
v_str = "table:" .. table_serialize(v)
|
||||||
|
else
|
||||||
|
v_str = tostring(v)
|
||||||
|
end
|
||||||
|
|
||||||
|
if out == '' then
|
||||||
|
out = v_str
|
||||||
|
else
|
||||||
|
out = out .. "\t" .. v_str
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tag_table_to_tags(tag_table)
|
||||||
|
if tag_table and next(tag_table) then
|
||||||
|
local tags = {}
|
||||||
|
for k,v in pairs(tag_table) do
|
||||||
|
tags[#tags + 1] = k..":"..v
|
||||||
|
end
|
||||||
|
return tags
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
-- end log helper fun
|
||||||
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- dump list mgr
|
||||||
|
--
|
||||||
|
local function _lnew(n)
|
||||||
|
local l = {}
|
||||||
|
l.tail = 1
|
||||||
|
l.len = n
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _lreset(l)
|
||||||
|
l.tail = 1
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _lpush(l,...)
|
||||||
|
l[l.tail] = {...}
|
||||||
|
l[l.tail - l.len] = nil
|
||||||
|
l.tail = l.tail + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _lempty(l)
|
||||||
|
return l.tail == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _lrange(l)
|
||||||
|
if l.tail <= l.len then
|
||||||
|
return 1, l.tail-1
|
||||||
|
end
|
||||||
|
|
||||||
|
return l.tail - l.len, l.tail-1
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- end dump list mgr
|
||||||
|
--
|
||||||
|
|
||||||
|
function logger:cache(...)
|
||||||
|
_lpush(self.dump_list,...)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 构造符合 lualog 次序的 message, 由 pack_log_message 使用
|
||||||
|
function logger:get_log_message(level, timestamp, src, ...)
|
||||||
|
local msg = log_format(level, ...)
|
||||||
|
local modname = self.module_name or self.default_module_name
|
||||||
|
local name = self.logger_name or modname
|
||||||
|
local timestamp = log_timestamp(timestamp)
|
||||||
|
return name, modname, level, timestamp,msg, src, tags
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:dump()
|
||||||
|
if _lempty(self.dump_list) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local head, tail = _lrange(self.dump_list)
|
||||||
|
|
||||||
|
local log_message_list = {}
|
||||||
|
for i= head,tail do
|
||||||
|
log_message_list[#log_message_list + 1] = {self:get_log_message(table.unpack(self.dump_list[i]))}
|
||||||
|
end
|
||||||
|
dump_log_to_disk(log_message_list)
|
||||||
|
_lreset(self.dump_list)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:log_i(...)
|
||||||
|
log_to_disk(self:get_log_message(...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:log(level, ...)
|
||||||
|
-- 过滤掉信息的条件:未设置dump_level,且level低于log_level
|
||||||
|
if self.dump_level == logger.NOLOG and level < self.log_level then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local timestamp = Skynet.now()
|
||||||
|
local src = self.log_src and get_log_src(self.stack_level) or ''
|
||||||
|
|
||||||
|
if level < self.log_level then -- 低于记录级别, 缓存
|
||||||
|
self:cache(level, timestamp, src, ...)
|
||||||
|
else
|
||||||
|
self:log_i(level, timestamp, src, ...) -- 低于dump级别,直接记录
|
||||||
|
if self.dump_level ~= logger.NOLOG and level >= self.dump_level then -- dump缓存
|
||||||
|
self:dump()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- public interface
|
||||||
|
--
|
||||||
|
function logger:Debug(...)
|
||||||
|
self:log(logger.DEBUG, ...)
|
||||||
|
end
|
||||||
|
function logger:Debugf(format, ...)
|
||||||
|
self:log(logger.DEBUG, string.format(format, ...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Info(...)
|
||||||
|
self:log(logger.INFO, ...)
|
||||||
|
end
|
||||||
|
function logger:Infof(format, ...)
|
||||||
|
self:log(logger.INFO, string.format(format, ...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Warning(...)
|
||||||
|
self:log(logger.WARNING, ...)
|
||||||
|
end
|
||||||
|
function logger:Warningf(format, ...)
|
||||||
|
self:log(logger.WARNING, string.format(format,...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Error(...)
|
||||||
|
self:log(logger.ERROR, ...)
|
||||||
|
end
|
||||||
|
function logger:Errorf(format, ...)
|
||||||
|
self:log(logger.ERROR, string.format(format,...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Critical(...)
|
||||||
|
self:log(logger.CRITICAL, ...)
|
||||||
|
end
|
||||||
|
function logger:Criticalf(format, ...)
|
||||||
|
self:log(logger.CRITICAL, string.format(format,...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Fatal(...)
|
||||||
|
self:log(logger.FATAL, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Fatalf(format, ...)
|
||||||
|
self:log(logger.FATAL, string.format(format,...))
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Assert(v, message)
|
||||||
|
if not v then
|
||||||
|
self:log(logger.ERROR, "assert:"..tostring(message))
|
||||||
|
end
|
||||||
|
return assert(v, message)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:SError(message, level)
|
||||||
|
level = level and level+1 or 2
|
||||||
|
self:log(logger.CRITICAL, "error:" .. tostring(message))
|
||||||
|
error(message, level)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Tag(key, value)
|
||||||
|
self.tag_table[key] = value
|
||||||
|
self.tags = tag_table_to_tags(tag_table)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:Untag(key)
|
||||||
|
self.tag_table[key]=nil
|
||||||
|
self.tags = tag_table_to_tags(self.tag_table)
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:set_modname(name)
|
||||||
|
self.module_name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:config(t)
|
||||||
|
if t["name"] ~= nil then
|
||||||
|
self.logger_name = t["name"]
|
||||||
|
end
|
||||||
|
|
||||||
|
if t["module_name"] ~= nil then
|
||||||
|
self.module_name = t["module_name"]
|
||||||
|
end
|
||||||
|
|
||||||
|
if t["to_screen"] ~= nil then
|
||||||
|
self.to_screen = t["to_screen"]
|
||||||
|
end
|
||||||
|
|
||||||
|
if t["level"] ~= nil then
|
||||||
|
self.log_level = t["level"]
|
||||||
|
end
|
||||||
|
|
||||||
|
if t["log_src"] ~= nil then
|
||||||
|
self.log_src = t["log_src"]
|
||||||
|
end
|
||||||
|
|
||||||
|
if t["dump_level"] ~= nil then
|
||||||
|
self.dump_level = t["dump_level"]
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.dump_level ~= logger.NOLOG then
|
||||||
|
assert(self.dump_level > self.log_level)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function logger:new()
|
||||||
|
-- private field
|
||||||
|
local obj = {}
|
||||||
|
obj.default_module_name = "skynet"
|
||||||
|
obj.logger_name = nil
|
||||||
|
obj.module_name = nil
|
||||||
|
obj.to_screen = true
|
||||||
|
obj.log_level = logger.DEBUG
|
||||||
|
obj.log_src = true
|
||||||
|
obj.dump_level = logger.NOLOG
|
||||||
|
obj.dump_num = 100
|
||||||
|
self.dump_list = _lnew(obj.dump_num)
|
||||||
|
obj.tag_table = {}
|
||||||
|
obj.tags = nil
|
||||||
|
obj.stack_level = 3
|
||||||
|
|
||||||
|
setmetatable(obj, logger)
|
||||||
|
logger.__index = logger
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
return logger
|
||||||
|
|
||||||
44
service/lualog.lua
Normal file
44
service/lualog.lua
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
|
||||||
|
local log_level_desc = {
|
||||||
|
[0] = "NOLOG",
|
||||||
|
[10] = "DEBUG",
|
||||||
|
[20] = "INFO",
|
||||||
|
[30] = "WARNING",
|
||||||
|
[40] = "ERROR",
|
||||||
|
[50] = "CRITICAL",
|
||||||
|
[60] = "FATAL",
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
-- log object
|
||||||
|
--
|
||||||
|
function log_format(self)
|
||||||
|
if self.tags and next(self.tags) then
|
||||||
|
return string.format("[%s %s *%s*] [%s]%s %s", self.timestamp,self.level,self.name,table.concat(self.tags, ","),self.src,self.msg)
|
||||||
|
else
|
||||||
|
return string.format("[%s %s *%s*]%s %s", self.timestamp,self.level,self.name,self.src,self.msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- end log object
|
||||||
|
--
|
||||||
|
|
||||||
|
local function log(name, modname, level, timestamp, msg, src, tags)
|
||||||
|
print(log_format {
|
||||||
|
name = name,
|
||||||
|
modname = modname,
|
||||||
|
level = log_level_desc[level],
|
||||||
|
timestamp = timestamp,
|
||||||
|
msg = msg,
|
||||||
|
src = src or '',
|
||||||
|
tags = tags,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
skynet.dispatch(function(msg, sz , session , from)
|
||||||
|
log(skynet.unpack(msg,sz))
|
||||||
|
end)
|
||||||
|
|
||||||
|
skynet.register ".lualog"
|
||||||
@@ -4,6 +4,8 @@ skynet.dispatch()
|
|||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
print("Server start")
|
print("Server start")
|
||||||
|
local lualog = skynet.launch("snlua","lualog")
|
||||||
|
print("lualog",lualog)
|
||||||
local launcher = skynet.launch("snlua","launcher")
|
local launcher = skynet.launch("snlua","launcher")
|
||||||
print("launcher", launcher)
|
print("launcher", launcher)
|
||||||
local console = skynet.launch("snlua","console")
|
local console = skynet.launch("snlua","console")
|
||||||
@@ -17,4 +19,4 @@ skynet.start(function()
|
|||||||
local redis = skynet.call(".launcher", "broker .redis snlua redis-cli 127.0.0.1:6379")
|
local redis = skynet.call(".launcher", "broker .redis snlua redis-cli 127.0.0.1:6379")
|
||||||
print("redis",redis)
|
print("redis",redis)
|
||||||
skynet.exit()
|
skynet.exit()
|
||||||
end)
|
end)
|
||||||
|
|||||||
7
service/testlog.lua
Normal file
7
service/testlog.lua
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local log = require "log"
|
||||||
|
|
||||||
|
skynet.dispatch()
|
||||||
|
|
||||||
|
log.Info("hello world")
|
||||||
|
|
||||||
Reference in New Issue
Block a user