简单在github.com/samuel/go-thrift/examples/scribe下对日志做了简单封装(欢迎大家吐槽),支持远程上报scribe和本地使用beego的日志系统,scribe日志支持同步和异步两张模式,后期再加上scribe不可用的记录本地日志,scribe可用后上报本地日志到scribe,上传完删除本地记录日志。
package main
import (
"fmt"
"net"
"os"
"runtime"
"sync"
"time"
"github.com/astaxie/beego/logs"
"github.com/samuel/go-thrift/examples/scribe"
"github.com/samuel/go-thrift/thrift"
)
type GoScribe struct {
log *logs.BeeLogger
scblog scribe.ScribeClient
bBlockMode bool //true 日志设置chan 模式 -- false 阻塞模式
bUserScribe bool //在false 模式下scribe异常使用beego日志系统
hostName string //服务器名,用于标记那台服务器上报日志
processName string //程序进程名
remoteAddress string //scribe 连接地址
cSendLog chan string //bBlockMode:true 时候使用
mutex sync.Mutex //日志锁
}
func GetHostName() string {
host, err := os.Hostname()
if err != nil {
return "defaul"
} else {
return host
}
}
func NewScribe(processName string, netAddr string, hostName string, bBlockMode bool) *GoScribe {
cSendLog := make(chan string, 1000)
doLog := &GoScribe{processName: processName, remoteAddress: netAddr, hostName: hostName, cSendLog: cSendLog, bBlockMode: bBlockMode}
doLog.InitLog()
return doLog
}
func (doLog *GoScribe) InitBeegoLog() {
err := os.Mkdir("log", 0755)
if err != nil && !os.IsExist(err) {
fmt.Println("create log ", err)
}
doLog.log = logs.NewLogger(100)
doLog.log.SetLogger("console", "")
filedata := "{\"filename\":\"" + doLog.processName + ".log" + "\"}"
doLog.log.SetLogger("file", filedata)
doLog.log.Debug("Init log over...")
}
func (doLog *GoScribe) InitLog() {
doLog.bUserScribe = doLog.ReConnectScribe()
if doLog.bUserScribe == true {
doLog.Info("%v", "success connect scribe server !")
}
if true == doLog.bBlockMode {
go doLog.StartLog()
} else {
doLog.InitBeegoLog()
}
}
func (doLog *GoScribe) ReConnectScribe() bool {
conn, err := net.Dial("tcp", doLog.remoteAddress)
if err != nil {
doLog.log.Error(err.Error())
doLog.bUserScribe = false
return false
}
fmt.Printf("%v \n", conn)
doLog.bUserScribe = true
t := thrift.NewTransport(thrift.NewFramedReadWriteCloser(conn, 0), thrift.BinaryProtocol)
client := thrift.NewClient(t, false)
doLog.scblog = scribe.ScribeClient{Client: client}
return doLog.bUserScribe
}
func (doLog *GoScribe) SetLogHead(s string) string {
now := time.Now()
year, mon, day := now.Date()
hour, min, sec := now.Clock()
pp, _, line, _ := runtime.Caller(2)
return fmt.Sprintf("[%v] %04d-%02d-%02d %02d:%02d:%02d [%v] [%v:%v] ",
doLog.hostName, year, mon, day, hour, min, sec, s, runtime.FuncForPC(pp).Name(), line)
}
func (doLog *GoScribe) WriteLog(msg string) {
if len(msg) > 0 {
_, err := doLog.scblog.Log([]*scribe.LogEntry{{doLog.processName, msg}})
if err != nil {
doLog.log.Info(err.Error(), msg)
doLog.bUserScribe = false
}
}
}
func (doLog *GoScribe) StartLog() {
doLog.Info("启动异步scribe 模式 ......")
for {
select {
case msg := <-doLog.cSendLog:
doLog.WriteLog(msg)
}
}
}
func (doLog *GoScribe) ExeLog(msg string) {
if true == doLog.bBlockMode {
doLog.cSendLog <- msg
return
}
_, err := doLog.scblog.Log([]*scribe.LogEntry{{doLog.processName, msg}})
if err != nil {
doLog.log.Info(err.Error(), msg)
doLog.bUserScribe = false
}
if false == doLog.bUserScribe {
if doLog.ReConnectScribe() == false {
doLog.log.Info("%v", msg)
return
}
}
}
func (doLog *GoScribe) Info(format string, v ...interface{}) {
msg := doLog.SetLogHead("info") + fmt.Sprintf(format, v...)
doLog.ExeLog(msg)
}
func (doLog *GoScribe) Warn(format string, v ...interface{}) {
msg := doLog.SetLogHead("Warn") + fmt.Sprintf(format, v...)
doLog.ExeLog(msg)
}
func (doLog *GoScribe) Error(format string, v ...interface{}) {
msg := doLog.SetLogHead("Error") + fmt.Sprintf(format, v...)
doLog.ExeLog(msg)
}
func RunTest(doLog *GoScribe) {
doLog.Info("test test %v", "1234556")
time.Sleep(1)
}
func main() {
doLog := NewScribe("test", "127.0.0.1:1463", GetHostName(), true)
num := 1
for i := 0; i < 20; i++ {
go RunTest(doLog)
}
for {
doLog.Info("do not come here %v", "tetetetet")
num++
time.Sleep(1 * time.Second)
}
}
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传