Categorygithub.com/mwitkow/go-conntrack
modulepackage
0.0.0-20190716064945-2f068394615f
Repository: https://github.com/mwitkow/go-conntrack.git
Documentation: pkg.go.dev

# README

Go tracing and monitoring (Prometheus) for net.Conn

Travis Build Go Report Card GoDoc Apache 2.0 License

Prometheus monitoring and x/net/trace tracing wrappers net.Conn, both inbound (net.Listener) and outbound (net.Dialer).

Why?

Go standard library does a great job of doing "the right" things with your connections: http.Transport pools outbound ones, and http.Server sets good Keep Alive defaults. However, it is still easy to get it wrong, see the excellent The complete guide to Go net/http timeouts.

That's why you should be able to monitor (using Prometheus) how many connections your Go frontend servers have inbound, and how big are the connection pools to your backends. You should also be able to inspect your connection without ssh and netstat.

Events page with connections

How to use?

All of these examples can be found in example/server.go:

Conntrack Dialer for HTTP DefaultClient

Most often people use the default http.DefaultClient that uses http.DefaultTransport. The easiest way to make sure all your outbound connections monitored and trace is:

http.DefaultTransport.(*http.Transport).DialContext = conntrack.NewDialContextFunc(
    conntrack.DialWithTracing(),
    conntrack.DialWithDialer(&net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
    }),
)

Dialer Name

Tracked outbound connections are organised by dialer name (with default being default). The dialer name is used for monitoring (dialer_name label) and tracing (net.ClientConn.<dialer_name> family).

You can pass conntrack.WithDialerName() to NewDialContextFunc to set the name for the dialer. Moreover, you can set the dialer name per invocation of the dialer, by passing it in the Context. For example using the ctxhttp lib:

callCtx := conntrack.DialNameToContext(parentCtx, "google")
ctxhttp.Get(callCtx, http.DefaultClient, "https://www.google.com")

Conntrack Listener for HTTP Server

Tracked inbound connections are organised by listener name (with default being default). The listener name is used for monitoring (listener_name label) and tracing (net.ServerConn.<listener_name> family). For example, a simple http.Server can be instrumented like this:

listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
listener = conntrack.NewListener(listener, 
    conntrack.TrackWithName("http"), 
    conntrack.TrackWithTracing(),
    conntrack.TrackWithTcpKeepAlive(5 * time.Minutes))
httpServer.Serve(listener) 

Note, the TrackWithTcpKeepAlive. The default http.ListenAndServe adds a tcp keep alive wrapper to inbound TCP connections. conntrack.NewListener allows you to do that without another layer of wrapping.

TLS server example

The standard lobrary http.ListenAndServerTLS does a lot to bootstrap TLS connections, including supporting HTTP2 negotiation. Unfortunately, that is hard to do if you want to provide your own net.Listener. That's why this repo comes with connhelpers package, which takes care of configuring tls.Config for that use case. Here's an example of use:

listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
listener = conntrack.NewListener(listener, 
    conntrack.TrackWithName("https"), 
    conntrack.TrackWithTracing(),
    conntrack.TrackWithTcpKeepAlive(5 * time.Minutes))
tlsConfig, err := connhelpers.TlsConfigForServerCerts(*tlsCertFilePath, *tlsKeyFilePath)
tlsConfig, err = connhelpers.TlsConfigWithHttp2Enabled(tlsConfig)
tlsListener := tls.NewListener(listener, tlsConfig)
httpServer.Serve(listener) 

Status

This code is used by Improbable's HTTP frontending and proxying stack for debuging and monitoring of established user connections.

Additional tooling will be added if needed, and contributions are welcome.

#License

go-conntrack is released under the Apache 2.0 license. See the LICENSE file for details.

# Packages

No description provided by the author
No description provided by the author

# Functions

DialNameFromContext returns the name of the dialer from the context of the DialContext func, if any.
DialNameToContext returns a context that will contain a dialer name override.
DialWithDialContextFunc allows you to override func gets used for the actual dialing.
DialWithDialer allows you to override the `net.Dialer` instance used to actually conduct the dials.
DialWithName sets the name of the dialer for tracking and monitoring.
DialWithoutMonitoring turns *off* Prometheus monitoring for this dialer.
DialWithTracing turns *on* the /debug/events tracing of the dial calls.
NewDialContextFunc returns a `DialContext` function that tracks outbound connections.
NewDialFunc returns a `Dial` function that tracks outbound connections.
NewListener returns the given listener wrapped in connection tracking listener.
preRegisterDialerMetrics pre-populates Prometheus labels for the given dialer name, to avoid Prometheus missing labels issue.
TrackWithName sets the name of the Listener for use in tracking and monitoring.
TrackWithoutMonitoring turns *off* Prometheus monitoring for this listener.
TrackWithRetries enables retrying of temporary Accept() errors, with the given backoff between attempts.
TrackWithTcpKeepAlive makes sure that any `net.TCPConn` that get accepted have a keep-alive.
TrackWithTracing turns *on* the /debug/events tracing of the live listener connections.