1 回答

TA贡献1833条经验 获得超4个赞
http.Server有领域ErrorLog。您可以将其底层编写器替换为自定义编写器,该编写器会过滤掉包含“TLS 握手错误”的字符串
下面是一个有两个服务器的简单示例。一台服务器监听8443端口,使用全量日志。另一台服务器使用过滤日志,监听8444端口。
客户端连接到服务器。具有完整日志的服务器打印http: TLS handshake error from 127.0.0.1:xxxxx: remote error: tls: bad certificate. 带有过滤日志的服务器什么也没有。
该示例演示了最简单的过滤记录器,它过滤掉具有固定子字符串的行。
package main
import (
"bytes"
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"sync"
"time"
)
// Filters out lines that contain substring
type 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 function
func HelloWorld(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("Hello, world!\n"))
}
// Trivial server executor
func runServer(server *http.Server, wg *sync.WaitGroup) {
server.ListenAndServeTLS("server.crt", "server.key")
wg.Done()
}
// Shutdown server
func 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 log
2022/10/27 19:20:52 Client failed: Get "https://localhost:8443/hello": x509: certificate is not valid for any names, but wanted to match localhost
full: 2022/10/27 19:20:52 http: TLS handshake error from 127.0.0.1:53182: remote error: tls: bad certificate
2022/10/27 19:20:52 Client connects to the server with filtered log
2022/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 没有日志行。
- 1 回答
- 0 关注
- 138 浏览
添加回答
举报