zap 发送日志到 websocket
package wslog
import (
"log"
"os"
"time"
"github.com/gorilla/websocket"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var Logger *zap.Logger
type WebSocketLogSyncher struct {
conn *websocket.Conn
Address string
}
func (wsSync *WebSocketLogSyncher) Write(p []byte) (n int, err error) {
if wsSync.conn != nil {
err = wsSync.conn.WriteMessage(websocket.TextMessage, p)
}
if err == nil {
n = len(p)
}
return
}
func (wsSync *WebSocketLogSyncher) Sync() error {
// nothing to sync for websocket
return nil
}
func (wsSync *WebSocketLogSyncher) SetWSConn(conn *websocket.Conn) {
wsSync.conn = conn
}
func (wsSync *WebSocketLogSyncher) Connect() bool {
//建立 websocket 连接
if wsSync.conn == nil {
conn, _, err := websocket.DefaultDialer.Dial(wsSync.Address, nil)
if err != nil {
log.Println("WebSocket connection failed: ", err)
return false
}
wsSync.conn = conn
}
log.Println("WebSocket connection success")
return true
}
func (wsSync *WebSocketLogSyncher) OnTimer() {
go func() {
for {
if wsSync.conn != nil {
_, _, err := wsSync.conn.ReadMessage()
if err != nil {
log.Println("WebSocket connection closed")
wsSync.conn.Close()
wsSync.conn = nil
} else {
//log.Println("WebSocket message type: ", ty, " message: ", string(message))
}
} else {
time.Sleep(1 * time.Second)
log.Println("WebSocket connection is nil")
wsSync.Connect()
}
}
}()
}
func Init(addr string) {
var err error
Logger, err = zap.NewDevelopment()
if err != nil {
log.Print("Cannot initialize logging")
}
WSLogSync := &WebSocketLogSyncher{}
WSLogSync.Address = addr
bret := WSLogSync.Connect()
if bret {
Logger.Info("WebSocket connection success ", zap.String("address", WSLogSync.Address))
} else {
Logger.Error("WebSocket connection failed ", zap.String("address", WSLogSync.Address))
}
WSLogSync.OnTimer()
Logger = zap.New(zapcore.NewCore(zapcore.NewJSONEncoder(zapcore.EncoderConfig{
TimeKey: "ts",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
EncodeLevel: zapcore.LowercaseLevelEncoder,
EncodeTime: zapcore.EpochTimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
}), zapcore.NewMultiWriteSyncer(os.Stdout, WSLogSync), zap.NewAtomicLevel()))
Logger.Info("Logger initialized")
}
package main
import (
"time"
"wstest/wslog"
)
var addr = "ws://localhost:8080/echo"
func main() {
wslog.Init(addr)
Logger := wslog.Logger
Logger.Info("logger init success")
for {
time.Sleep(1 * time.Second)
Logger.Info("logger info")
Logger.Warn("logger warn")
Logger.Error("logger error")
}
}