一、功能
lua log方法能够自动发现同一网段下面的log服务器
lua log方法能够主动将log发给服务器
lua 客户端进程重启服务端不存在影响
二、实现
服务器使用python编写:
启动一个线程,用UDP监听特定端口,接受客户端的扫描,反馈日志的端口
启动一个线程,监听特定端口,接受TCP连接,分派新的日志线程处理log
客户端使用lua 编写:
打印log之前使用UDP套节字扫描服务器的日志端口,然后创建TCP套节字发送日志
三、源代码:
服务器:
import socket
import time
import re
import thread
udp_listen_port = 31500
tcp_listen_port = 31501
stop_udp_server = False
def getLocalIP():
myname = socket.getfqdn(socket.gethostname())
myaddr = socket.gethostbyname(myname)
return myaddr;
def getTime():
return time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
def Log(content):
print("[%s]: %s" % (getTime() ,content))
def startUDPServer():
address = (getLocalIP(), udp_listen_port)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(address)
print('listen broadcast %s:%s' % address)
Log('listen broadcast %s:%s' % address)
while not stop_udp_server:
data, addr = s.recvfrom(2048)
if not data:
Log("client not existed!")
continue
Log('received %s from %s' % (data, addr))
client_ip_port = '{0}:{1}'.format(addr[0],addr[1])
pat = re.compile("^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)$")
for ip,port in pat.findall(client_ip_port):
Log('Got iphone addr:port = %s %s' % (ip, port))
local_addr_port = (getLocalIP(), tcp_listen_port)
Log('Rsp server addr:port = %s %s' % local_addr_port)
rsp_data = '{0}'.format(local_addr_port[1])
s.sendto(rsp_data,addr)
break;
s.close()
def startTCPLogServer(sock,client):
while(True):
try:
data = sock.recv(4096)
if data:
pat = re.compile('\[(.*?)\]')
for log in pat.findall(data):
Log(log)
else:
break;
except socket.error:
sock.close()
break
Log('client (%s,%s) close' % client);
sock.close()
def startTCPListenServer():
#create tcp socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#bind local ip-port
server_addr = (getLocalIP(), tcp_listen_port)
Log('start tcp server on %s port %s' % server_addr)
sock.bind(server_addr)
sock.listen(5)
#print recv data
while(True):
ss,addr = sock.accept()
Log('Got log client from (%s,%s)' % addr)
thread.start_new_thread(startTCPLogServer,(ss,addr,))
sock.close()
if __name__ == '__main__':
t_udp = thread.start_new_thread(startUDPServer, ())
t_tcp = thread.start_new_thread(startTCPListenServer, ())
while (True):
time.sleep(1)
客户端:
udp_listen_port = 31500tcp_server_ip= ""tcp_server_port= 0
functiongetLocalIP()local socket = require("socket")local ip, v =socket.dns.toip(socket.dns.gethostname())for k,v in pairs(v.ip) do
returnvend
return nil
end
functiontryFindLogServer()local ip =getLocalIP();local ipTable ={}local socket = require("socket")local udp =socket.udp()if ip ~= nil then
for i in string.gmatch(ip, "%d+") do
print(i)table.insert(ipTable,i)end
end
local length =table.getn(ipTable)local findip = nil
local findport = nil
if length > 0 then
for i = 100, 255 do
local desIP = string.format("%s.%s.%s.%s",ipTable[1], ipTable[2], ipTable[3], tostring(i))print(desIP)
udp:setpeername(desIP, udp_listen_port)
udp:settimeout(0.5)
udp:send("Hello")
data=udp:receive()if data ~= nil then
print(string.format("find server %s:%s", desIP,data))
tcp_server_ip=desIP
tcp_server_port= tonumber(data)return true;end
end
end
return false
endtcp= nil
functionLog( content )--body
if tcp == nil then
local socket = require("socket")
tcp=socket.tcp()
tcp:connect(tcp_server_ip,tcp_server_port)endtcp:send(string.format("[%s]",tostring(content)))end
if tryFindLogServer() then
for i = 1,100 doLog("find server")end
end
四、客户端lua中加载luasocket的方式如下:
local sz = require("sz")local http = require("szocket.http")local res, code = http.request("http://www.baidu.com");if code == 200 thenLog("start")
Log(res)
dialog(res,0);
Log("end")end