package remotelogs import ( "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeDNS/internal/configs" teaconst "github.com/TeaOSLab/EdgeDNS/internal/const" "github.com/TeaOSLab/EdgeDNS/internal/rpc" "github.com/iwind/TeaGo/logs" "strings" "time" ) var logChan = make(chan *pb.NodeLog, 64) // 队列数量不需要太长,因为日志通常仅仅为调试用 func init() { if !teaconst.IsMain { return } // 定期上传日志 var ticker = time.NewTicker(60 * time.Second) go func() { defer func() { if r := recover(); r != nil { logs.Println("[LOG]goroutine panic:", r) } }() for range ticker.C { err := uploadLogs() if err != nil { logs.Println("[LOG]" + err.Error()) } } }() } // Debug 打印本地调试信息 // 不需要上传到API节点 func Debug(tag string, description string) { logs.Println("[" + tag + "]" + description) } // Println 打印普通信息 func Println(tag string, description string) { logs.Println("[" + tag + "]" + description) apiConfig, _ := configs.SharedAPIConfig() if apiConfig == nil { return } select { case logChan <- &pb.NodeLog{ Role: teaconst.Role, Tag: tag, Description: description, Level: "info", NodeId: apiConfig.NumberId, CreatedAt: time.Now().Unix(), }: default: } } // Warn 打印警告信息 func Warn(tag string, description string) { logs.Println("[" + tag + "]" + description) apiConfig, _ := configs.SharedAPIConfig() if apiConfig == nil { return } select { case logChan <- &pb.NodeLog{ Role: teaconst.Role, Tag: tag, Description: description, Level: "warning", NodeId: apiConfig.NumberId, CreatedAt: time.Now().Unix(), }: default: } } // Error 打印错误信息 func Error(tag string, description string) { logs.Println("[" + tag + "]" + description) apiConfig, _ := configs.SharedAPIConfig() if apiConfig == nil { return } // 忽略RPC连接错误 var level = "error" if strings.Contains(description, "code = Unavailable desc") { level = "warning" } select { case logChan <- &pb.NodeLog{ Role: teaconst.Role, Tag: tag, Description: description, Level: level, NodeId: apiConfig.NumberId, CreatedAt: time.Now().Unix(), }: default: } } // ErrorObject 打印错误对象 func ErrorObject(tag string, err error) { if err == nil { return } if rpc.IsConnError(err) { Warn(tag, err.Error()) } else { Error(tag, err.Error()) } } // 上传日志 func uploadLogs() error { var logList = []*pb.NodeLog{} Loop: for { select { case log := <-logChan: if log.NodeId <= 0 { continue } logList = append(logList, log) default: break Loop } } if len(logList) == 0 { return nil } rpcClient, err := rpc.SharedRPC() if err != nil { return err } _, err = rpcClient.NodeLogRPC.CreateNodeLogs(rpcClient.Context(), &pb.CreateNodeLogsRequest{NodeLogs: logList}) return err }