Lua非阻塞写日志

用nginx-lua搭的服务需要写日志,一般采用nginx自带的accesslog加logrotate脚本来实现,但是无法满足一次请求需要写多条日志的需求

之前用C和GO实现过类似的代码,思路是主进程写管道,子进程读管道并交由apache-rotatelogs写日志

这里用Lua也实现了一下--

-- Rlog is an non-blocking logging based on pipe.
-- Rotatelogs of Apache is recommanded to be the output of pipe.
-- Before using Rlog, you should install luaposix.
-- local posix = require("posix") local os = require("os") -- input of pipe local pipe_in -- init rlog -- @param pipe_cmd pipe operator and the reveiver command. -- e.g. "| rotatelogs -l %Y%m%d%H.logfile 3600" -- @return true when success, false when fail local function init(pipe_cmd) -- if already inited, do nothing if pipe_in then return true end -- if pipe_cmd is not start with pipe operator, return false if string.sub(pipe_cmd, 1, 1) ~= "|" then return false end -- create pipe local pout, pin = posix.pipe() -- fork process to execute cmd if posix.fork() == 0 then -- close stdin io.close(io.stdin) -- set output of pipe as stdin posix.dup2(pout, posix.fileno(io.stdin)) -- close input and output of pipe posix.close(pout) posix.close(pin) -- execute cmd os.execute(string.sub(pipe_cmd, 2, -1)) end -- get input of pipe pipe_in = pin -- close output of pipe posix.close(pout) return true end -- write log local function log(log_str) -- write log into pipe posix.write(pipe_in, log_str .. "\n") end return { init = init, log = log }

下边是它的测试程序

local rlog = require("rlog")

-- init
ret = rlog.init("| rotatelogs -l %Y%m%d%H.log 3600")
if not ret then
    print("init fail")
end

-- log
rlog.log("Hello Rlog")

由于posix.write写管道是原子的,所以无须担心多进程或多线程写混乱的问题

不过这段代码依赖luaposix库,使用前需要安装一下

posted @ 2015-05-06 17:59  叶落十七  阅读(2002)  评论(0编辑  收藏  举报