在Linux环境下,使用Golang进行日志远程传输可以通过多种方式实现。以下是一些常见的方法:
你可以将日志发送到远程服务器的TCP或UDP端口。
客户端(发送日志):
package main import ( "log" "net" ) func main() { conn, err := net.Dial("tcp", "remote-server:port") if err != nil { log.Fatal(err) } defer conn.Close() logger := log.New(conn, "", log.LstdFlags) logger.Println("This is a log message") } 服务器(接收日志):
package main import ( "bufio" "fmt" "log" "net" ) func main() { listener, err := net.Listen("tcp", ":port") if err != nil { log.Fatal(err) } defer listener.Close() for { conn, err := listener.Accept() if err != nil { log.Println(err) continue } go handleConnection(conn) } } func handleConnection(conn net.Conn) { defer conn.Close() reader := bufio.NewReader(conn) for { line, err := reader.ReadString('\n') if err != nil { break } fmt.Print(line) } } 客户端(发送日志):
package main import ( "log" "net" ) func main() { conn, err := net.Dial("udp", "remote-server:port") if err != nil { log.Fatal(err) } defer conn.Close() logger := log.New(conn, "", log.LstdFlags) logger.Println("This is a log message") } 服务器(接收日志):
package main import ( "bufio" "fmt" "log" "net" ) func main() { addr, err := net.ResolveUDPAddr("udp", ":port") if err != nil { log.Fatal(err) } conn, err := net.ListenUDP("udp", addr) if err != nil { log.Fatal(err) } defer conn.Close() buf := make([]byte, 1024) for { n, addr, err := conn.ReadFromUDP(buf) if err != nil { log.Println(err) continue } fmt.Printf("Received %s from %s\n", string(buf[:n]), addr.String()) } } 你可以将日志发送到远程服务器的HTTP或HTTPS端点。
客户端(发送日志):
package main import ( "bytes" "log" "net/http" ) func main() { url := "http://remote-server/log" logMessage := "This is a log message" resp, err := http.Post(url, "application/json", bytes.NewBuffer([]byte(logMessage))) if err != nil { log.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { log.Fatalf("Server returned non-OK status: %s", resp.Status) } } 服务器(接收日志):
package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" ) type LogMessage struct { Message string `json:"message"` } func logHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Only POST method is allowed", http.StatusMethodNotAllowed) return } body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Failed to read request body", http.StatusBadRequest) return } defer r.Body.Close() var logMsg LogMessage err = json.Unmarshal(body, &logMsg) if err != nil { http.Error(w, "Failed to parse JSON", http.StatusBadRequest) return } fmt.Printf("Received log: %s\n", logMsg.Message) w.WriteHeader(http.StatusOK) } func main() { http.HandleFunc("/log", logHandler) log.Fatal(http.ListenAndServe(":port", nil)) } 你可以使用消息队列(如Kafka、RabbitMQ)来传输日志。
客户端(发送日志):
package main import ( "log" "github.com/Shopify/sarama" ) func main() { config := sarama.NewConfig() config.Producer.RequiredAcks = sarama.WaitForAll config.Producer.Retry.Max = 5 config.Producer.Return.Successes = true producer, err := sarama.NewSyncProducer([]string{"kafka-broker:9092"}, config) if err != nil { log.Fatal(err) } defer producer.Close() logMessage := &sarama.ProducerMessage{ Topic: sarama.StringEncoder("log-topic"), Value: sarama.ByteEncoder("This is a log message"), } partition, offset, err := producer.SendMessage(logMessage) if err != nil { log.Fatal(err) } log.Printf("Message is stored in topic(%s)/partition(%d)/offset(%d)\n", "log-topic", partition, offset) } 服务器(接收日志):
package main import ( "fmt" "log" "github.com/Shopify/sarama" ) func main() { config := sarama.NewConfig() config.Consumer.Return.Errors = true consumer, err := sarama.NewConsumer([]string{"kafka-broker:9092"}, config) if err != nil { log.Fatal(err) } defer consumer.Close() partitionConsumer, err := consumer.ConsumePartition("log-topic", 0, sarama.OffsetNewest) if err != nil { log.Fatal(err) } defer partitionConsumer.Close() for msg := range partitionConsumer.Messages() { fmt.Printf("Received message: %s\n", string(msg.Value)) } } 选择哪种方法取决于你的具体需求,例如日志的实时性、可靠性、安全性等。