github.com/prebid/prebid-server/v2@v2.18.0/server/listener.go (about) 1 package server 2 3 import ( 4 "net" 5 "strings" 6 "time" 7 8 "github.com/golang/glog" 9 "github.com/prebid/prebid-server/v2/metrics" 10 ) 11 12 // monitorableListener tracks any opened connections in the metrics. 13 type monitorableListener struct { 14 net.Listener 15 metrics metrics.MetricsEngine 16 } 17 18 // monitorableConnection tracks any closed connections in the metrics. 19 type monitorableConnection struct { 20 net.Conn 21 metrics metrics.MetricsEngine 22 } 23 24 func (l *monitorableConnection) Close() error { 25 err := l.Conn.Close() 26 if err == nil { 27 l.metrics.RecordConnectionClose(true) 28 } else { 29 // If the connection was closed by the client, it's not a real/actionable error. 30 // Although there are no official APIs to detect this, this ridiculous workaround appears 31 // in the core Go libs: https://github.com/golang/go/issues/4373#issuecomment-347680321 32 errString := err.Error() 33 if !strings.Contains(errString, "use of closed network connection") { 34 glog.Errorf("Error closing connection: %s", errString) 35 } 36 l.metrics.RecordConnectionClose(false) 37 } 38 return err 39 } 40 41 func (ln *monitorableListener) Accept() (net.Conn, error) { 42 tc, err := ln.Listener.Accept() 43 if err != nil { 44 glog.Errorf("Error accepting connection: %v", err) 45 ln.metrics.RecordConnectionAccept(false) 46 return tc, err 47 } 48 ln.metrics.RecordConnectionAccept(true) 49 return &monitorableConnection{ 50 tc, 51 ln.metrics, 52 }, nil 53 } 54 55 // tcpKeepAliveListener is copy/pasted from the implementation here: https://golang.org/pkg/net/http/#Server.ListenAndServe 56 // Since it's not public, the best we can do is copy/paste it here. 57 // 58 // We should revisit this after Go 1.11. See also: 59 // - https://github.com/golang/go/issues/23378 60 // - https://github.com/golang/go/issues/23459 61 type tcpKeepAliveListener struct { 62 *net.TCPListener 63 } 64 65 func (ln tcpKeepAliveListener) Accept() (net.Conn, error) { 66 tc, err := ln.AcceptTCP() 67 if err != nil { 68 return nil, err 69 } 70 tc.SetKeepAlive(true) 71 tc.SetKeepAlivePeriod(3 * time.Minute) 72 return tc, nil 73 } 74 75 type unixListener struct{ *net.UnixListener } 76 77 func (ln unixListener) Accept() (net.Conn, error) { return ln.AcceptUnix() }