skynet框架应用——使用C编写的log服务

目录

  • 一、编译log.so
  • 二、自定义的日志服务
  • 三、参数说明
  • 四、测试
  • 五、全部代码

这个log库是从github上的开源框架中看到的,发现其挺好用,就单独摘出来,作为单独的模块。
该作者的github地址为:https://github.com/xiaozia/metoo

输出的日志格式方便自定义,比如是下面这样:

[INFO] 2020-07-13 05:40:22 [main] [./demo/main.lua:10] start main info test...
[ERROR] 2020-07-13 05:40:22 [main] [./demo/main.lua:11] start main error test...

一、编译log.so

大家可以把这个开源库clone下来
https://github.com/xiaozia/metoo.git

把lua-log.c单独复制出来,在其相同目录下新建一个makfile文件:
(文章的最后,我会这个demo的文件的下载地址放上来)

CC ?= gcc  
CFLAGS = -g -O2 -Wall -I$(LUA_INC)  
SHARED := -fPIC --shared  

TARGET = log.so  
LUA_CLIB_PATH = ./

#引入lua头文件(根据你安装Lua库时的目录而定)
LUA_INC ?= /home/moon/Documents/skynet_project/3rd/lua

start: $(TARGET)  

$(TARGET) : ./lua-log.c
	$(CC) $(CFLAGS) $(SHARED) $^ -o $@  

clean:  
	rm -fr $(TARGET)  

$(LUA_CLIB_PATH) :  
	mkdir $(LUA_CLIB_PATH)

其中LUA_INC ?=
这里的路径可以填skynet中lua的路径

make

就会看到生成了一个log.so,如果有报错,或者想更详细了解如何用C语言作为skynet的模块,可以看这篇博客:
Skynet服务器框架(七) Lua中调用自定义C库

二、自定义的日志服务

log.lua

local skynet = require "skynet"
require "skynet.manager"
local logger = require "log.core"
 
local CMD = {}

function CMD.start()
	logger.init(tonumber(skynet.getenv("log_level")) or 0,
		tonumber(skynet.getenv("log_rollsize")) or 1024,
		tonumber(skynet.getenv("log_flushinterval")) or 5,
		skynet.getenv("log_dirname") or "log",
		skynet.getenv("log_basename") or "test")
end

function CMD.stop( )
	logger.exit()
end

function CMD.debug(name, msg)
	logger.debug(string.format("%s [%s] %s",os.date("%Y-%m-%d %H:%M:%S"), name, msg))
end

function CMD.info(name, msg)
	logger.info(string.format("%s [%s] %s",os.date("%Y-%m-%d %H:%M:%S"), name, msg))
end

function CMD.warning(name, msg)
	logger.warning(string.format("%s [%s] %s",os.date("%Y-%m-%d %H:%M:%S"), name, msg))
end

function CMD.error(name, msg)
	logger.error(string.format("%s [%s] %s",os.date("%Y-%m-%d %H:%M:%S"), name, msg))
end

function CMD.fatal(name, msg)
	logger.fatal(string.format("%s [%s] %s",os.date("%Y-%m-%d %H:%M:%S"), name, msg))
end

skynet.start(function()
	skynet.dispatch("lua", function(session, source, cmd, ...)
		local f = assert(CMD[cmd], cmd .. "not found")
		if cmd == "start" or cmd == "stop" then
			skynet.retpack(f(...))
		else
			f(...)
		end
	end)

	skynet.register(SERVICE_NAME)
end)

再定义一个log_helper.lua

local skynet = require "skynet"

local M = {}

function M.LOG_DEBUG(fmt, ...)
	local msg = string.format(fmt, ...)
	local info = debug.getinfo(2)
	if info then
		msg = string.format("[%s:%d] %s", info.short_src, info.currentline, msg)
	end
	skynet.send("log", "lua", "debug", SERVICE_NAME, msg)
end

function M.LOG_INFO(fmt, ...)
	local msg = string.format(fmt, ...)
	local info = debug.getinfo(2)
	if info then
		msg = string.format("[%s:%d] %s", info.short_src, info.currentline, msg)
	end
	skynet.send("log", "lua", "info", SERVICE_NAME, msg)
end

function M.LOG_WARNING(fmt, ...)
	local msg = string.format(fmt, ...)
	local info = debug.getinfo(2)
	if info then
		msg = string.format("[%s:%d] %s", info.short_src, info.currentline, msg)
	end
	skynet.send("log", "lua", "warning", SERVICE_NAME, msg)
end

function M.LOG_ERROR(fmt, ...)
	local msg = string.format(fmt, ...)
	local info = debug.getinfo(2)
	if info then
		msg = string.format("[%s:%d] %s", info.short_src, info.currentline, msg)
	end
	skynet.send("log", "lua", "error", SERVICE_NAME, msg)
end

function M.LOG_FATAL(fmt, ...)
	local msg = string.format(fmt, ...)
	local info = debug.getinfo(2)
	if info then
		msg = string.format("[%s:%d] %s", info.short_src, info.currentline, msg)
	end
	skynet.send("log", "lua", "fatal", SERVICE_NAME, msg)
end

return M

三、参数说明

在log.lua文件中我们看到:

function CMD.start()
	logger.init(tonumber(skynet.getenv("log_level")) or 0,
		tonumber(skynet.getenv("log_rollsize")) or 1024,
		tonumber(skynet.getenv("log_flushinterval")) or 5,
		skynet.getenv("log_dirname") or "log",
		skynet.getenv("log_basename") or "test")
end

这些参数是留给我们配置的。

log_level 是日志级别,和这个枚举对应

enum logger_level
{
	DEBUG = 0,
	INFO = 1,
	WARNING = 2,
	ERROR = 3,
	FATAL = 4
};

日志级别默认是0,即DEBUG

log_rollsize 日志文件达该大小就滚动一个新文件,单位是MB,默认是1024,即默认日志文件1GB就自动创建一个新的日志文件

log_flushinterval 是日志同步到磁盘间隔时间,默认是5秒;

log_basename 是日志文件的前缀,log_test.20200713-0.log
我写的log_basename是log_test 那么刚才看到的前缀就是这个log_basename

log_dirname是目录名,是相对目录,比如我写成log,它就自动创建该文件夹,并将日志文件放到这里,该参数是存放日志的目录名

四、测试

将第一步中生成的log.so放到skynet可以找到的位置,比如在lua_cpath中添加路径,或者直接放到luaclib文件夹中。
刚才的两个lua文件,log.lua是lua服务文件,需要放到skynet可以找到的lua服务路径中,而log_helper.lua只是普通的lua文件,只需要将其路径添加到lua_path中。

main.lua

local skynet = require "skynet"
local log_helper = require "log_helper"

skynet.start(function()
	skynet.error("=======Server start=======")

    local log = skynet.uniqueservice("log")
    skynet.call(log, "lua", "start")

    log_helper.LOG_INFO("start main info test...")
    log_helper.LOG_ERROR("start main error test...")
    
    skynet.exit()
end)

conf中的参数:

log_dirname = "log"
log_basename = "log_test"

运行结果:
在这里插入图片描述

[INFO] 2020-07-13 05:40:22 [main] [./demo/main.lua:10] start main info test...
[ERROR] 2020-07-13 05:40:22 [main] [./demo/main.lua:11] start main error test...

五、全部代码

全部的代码我打包放到这里:
链接:https://pan.baidu.com/s/17wTACI-SJ309kuUyMLrolQ
提取码:ejyo

参考:
https://github.com/xiaozia/metoo

Skynet服务器框架(七) Lua中调用自定义C库

你可能感兴趣的:(skynet)