潇潇雨雨
http.Server有领域ErrorLog。您可以将其底层编写器替换为自定义编写器,该编写器会过滤掉包含“TLS 握手错误”的字符串下面是一个有两个服务器的简单示例。一台服务器监听8443端口,使用全量日志。另一台服务器使用过滤日志,监听8444端口。客户端连接到服务器。具有完整日志的服务器打印http: TLS handshake error from 127.0.0.1:xxxxx: remote error: tls: bad certificate. 带有过滤日志的服务器什么也没有。该示例演示了最简单的过滤记录器,它过滤掉具有固定子字符串的行。package mainimport ( "bytes" "context" "fmt" "io" "log" "net/http" "os" "sync" "time")// Filters out lines that contain substringtype FilteringWriter struct { writer io.Writer substring []byte}func (fw FilteringWriter) Write(b []byte) (n int, err error) { if bytes.Index(b, fw.substring) > -1 { // Filter out the line that matches the pattern return len(b), nil } return fw.writer.Write(b)}func NewFilteringWriter(writer io.Writer, pattern string) FilteringWriter { return FilteringWriter{ writer: writer, substring: []byte(pattern), }}// Server handler functionfunc HelloWorld(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Write([]byte("Hello, world!\n"))}// Trivial server executorfunc runServer(server *http.Server, wg *sync.WaitGroup) { server.ListenAndServeTLS("server.crt", "server.key") wg.Done()}// Shutdown serverfunc shutdownServer(server *http.Server) { ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2*time.Second)) server.Shutdown(ctx) cancel()}func main() { fullLogger := log.New( os.Stderr, "full: ", log.LstdFlags, ) // Log that filters "TLS handshake error" errorLogger := log.New( NewFilteringWriter( os.Stderr, "http: TLS handshake error", ), "filtered: ", log.LstdFlags, ) serverMux := http.NewServeMux() serverMux.HandleFunc("/hello", HelloWorld) server1 := &http.Server{ Addr: "localhost:8443", Handler: serverMux, ErrorLog: fullLogger, } server2 := &http.Server{ Addr: "localhost:8444", Handler: serverMux, ErrorLog: errorLogger, } wg := sync.WaitGroup{} wg.Add(2) go runServer(server1, &wg) go runServer(server2, &wg) // Test loggers // Client connects to the servers // The server with the full log prints // `http: TLS handshake error from 127.0.0.1:53182: remote error: tls: bad certificate` // the server with the filtering log pints nothing client := http.Client{} time.Sleep(100 * time.Millisecond) log.Println("Client connects to the server with full log") reponse, err := client.Get(fmt.Sprintf("https://%s/hello", server1.Addr)) if err != nil { log.Printf("Client failed: %v", err) } else { log.Printf("Server returned: %v", reponse) } time.Sleep(100 * time.Millisecond) log.Println("Client connects to the server with filtered log") reponse, err = client.Get(fmt.Sprintf("https://%s/hello", server2.Addr)) if err != nil { log.Printf("Client failed: %v", err) } else { log.Printf("Server returned: %v", reponse) } shutdownServer(server1) shutdownServer(server2) wg.Wait()}输出:2022/10/27 19:20:52 Client connects to the server with full log2022/10/27 19:20:52 Client failed: Get "https://localhost:8443/hello": x509: certificate is not valid for any names, but wanted to match localhostfull: 2022/10/27 19:20:52 http: TLS handshake error from 127.0.0.1:53182: remote error: tls: bad certificate2022/10/27 19:20:52 Client connects to the server with filtered log2022/10/27 19:20:52 Client failed: Get "https://localhost:8444/hello": x509: certificate is not valid for any names, but wanted to match localhost如您所见,服务器 1 有日志行,服务器 2 没有日志行。