目前小项目,在多个vps上都有日志。之前的做法是,mstsc到每个vps,查看log。非常麻烦。
看了网上有些人的用ELK收集,又觉得那个部署太繁琐。所以想还是自己写一个轻量级的吧。
思路就是:
公网服务器跑一个server程序,监听某个socket端口。
其他vps打开client程序,tail某个log文件,把最新的一行log,通过socket传到server端。
1. server端代码:
功能,监听某端口,等待客户端连接,并从socket中读取客户端传上来的数据,写入log,server.log中
package main
import (
"flag"
"github.com/astaxie/beego/logs"
"net"
)
var port string
func init(){
flag.StringVar(&port,"port",":80",":port")
}
func main() {
logs.SetLogger(logs.AdapterFile, `{"filename":"server.log","color":true}`)
logs.EnableFuncCallDepth(true)
logs.SetLogFuncCallDepth(2)
flag.Parse()
listener,err:=net.Listen("tcp",port); if err!=nil{
panic(err)
}
for{
conn,err:=listener.Accept();if err!=nil{
logs.Debug("err at accept:%v",err)
continue
}
go handle(conn)
}
}
func handle(conn net.Conn) {
defer conn.Close()
buffer:=make([]byte,1024)
for{
n,err:=conn.Read(buffer);if err!=nil{
return
}
logs.Debug(string(buffer[:n]))
}
}
2. 客户端代码:
功能:tail某个本地log文件,将新增加的一行,发送至服务器端
package main
import (
"flag"
"fmt"
"github.com/hpcloud/tail"
"net"
"time"
)
var addr string
var filename string
var msgChan chan string
func init(){
flag.StringVar(&addr,"a","x.x.x.x:80",":addr")
flag.StringVar(&filename,"f","./test.log",":filename")
}
func main() {
flag.Parse()
msgChan=make(chan string,10000)
go startClient()
tails,err := tail.TailFile(filename,tail.Config{
ReOpen:true,
Follow:true,
Location:&tail.SeekInfo{Offset:0,Whence:2},
MustExist:false,
Poll:true,
})
if err !=nil{
fmt.Println("tail file err:",err)
return
}
var msg *tail.Line
var ok bool
for{
msg,ok = <-tails.Lines
if !ok{
fmt.Printf("tail file close reopen,filenam:%s\n",tails,filename)
time.Sleep(100*time.Millisecond)
continue
}
fmt.Println("msg:",msg.Text)
msgChan<-msg.Text
}
}
func startClient() {
conn,err:=net.Dial("tcp",addr);if err!=nil{
panic(err)
}
defer conn.Close()
for{
msg:=<-msgChan
_,err=conn.Write([]byte(msg));if err!=nil{
panic(err)
}
}
}
感觉比ELK简单直接,个人项目足够。