github.com/Axway/agent-sdk@v1.1.101/pkg/util/log/trace.go (about)

     1  package log
     2  
     3  import (
     4  	"crypto/tls"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptrace"
     8  
     9  	"github.com/sirupsen/logrus"
    10  )
    11  
    12  type httpTrace struct {
    13  	reqID  string
    14  	logger FieldLogger
    15  }
    16  
    17  // NewRequestWithTraceContext - New request trace context
    18  func NewRequestWithTraceContext(id string, req *http.Request) *http.Request {
    19  	logger := NewFieldLogger()
    20  	trace := &httpTrace{reqID: id, logger: logger.WithField("component", "httpTrace")}
    21  
    22  	clientTrace := &httptrace.ClientTrace{
    23  		GetConn:              trace.logConnection,
    24  		DNSStart:             trace.logDNSStart,
    25  		DNSDone:              trace.logDNSDone,
    26  		ConnectStart:         trace.logConnectStart,
    27  		ConnectDone:          trace.logConnectDone,
    28  		GotConn:              trace.logGotConn,
    29  		WroteHeaderField:     trace.logWroteHeaderField,
    30  		WroteRequest:         trace.logWroteRequest,
    31  		GotFirstResponseByte: trace.logGotFirstResponseByte,
    32  		TLSHandshakeStart:    trace.logTLSHandshakeStart,
    33  		TLSHandshakeDone:     trace.logTLSHandshakeDone,
    34  	}
    35  	clientTraceCtx := httptrace.WithClientTrace(req.Context(), clientTrace)
    36  	return req.WithContext(clientTraceCtx)
    37  }
    38  
    39  func (t *httpTrace) logConnection(hostPort string) {
    40  	t.logger.
    41  		WithField("id", t.reqID).
    42  		WithField("port", hostPort).
    43  		Trace("getting connection")
    44  }
    45  
    46  func (t *httpTrace) logDNSStart(info httptrace.DNSStartInfo) {
    47  	t.logger.
    48  		WithField("id", t.reqID).
    49  		WithField("host", info.Host).
    50  		Trace("dns lookup start")
    51  }
    52  
    53  func (t *httpTrace) logDNSDone(info httptrace.DNSDoneInfo) {
    54  	if info.Err != nil {
    55  		t.logger.
    56  			WithField("id", t.reqID).
    57  			WithError(info.Err).
    58  			Trace("dns lookup failure")
    59  		return
    60  	}
    61  	resolvedIPs := ""
    62  	for _, ip := range info.Addrs {
    63  		if resolvedIPs != "" {
    64  			resolvedIPs += ","
    65  		}
    66  		resolvedIPs += ip.String()
    67  	}
    68  	if resolvedIPs == "" {
    69  		resolvedIPs = "none"
    70  	}
    71  	t.logger.
    72  		WithField("id", t.reqID).
    73  		WithField("ips", resolvedIPs).
    74  		Trace("dns lookup completed, resolved IPs")
    75  }
    76  
    77  func (t *httpTrace) logConnectStart(network, addr string) {
    78  	t.logger.
    79  		WithField("id", t.reqID).
    80  		WithField("network", network).
    81  		WithField("addr", addr).
    82  		Trace("creating connection")
    83  }
    84  
    85  func (t *httpTrace) logConnectDone(network, addr string, err error) {
    86  	if err != nil {
    87  		t.logger.
    88  			WithField("id", t.reqID).
    89  			WithField("network", network).
    90  			WithField("addr", addr).
    91  			WithError(err).
    92  			Trace("connection creation failure")
    93  		return
    94  	}
    95  	t.logger.
    96  		WithField("id", t.reqID).
    97  		WithField("network", network).
    98  		WithField("addr", addr).
    99  		Trace("connection created")
   100  }
   101  
   102  func (t *httpTrace) logWroteHeaderField(key string, value []string) {
   103  	if _, ok := networkTraceIgnoreHeaders[key]; !ok {
   104  		t.logger.
   105  			WithField("id", t.reqID).
   106  			WithField("key", key).
   107  			WithField("value", value).
   108  			Trace("writing header")
   109  	} else {
   110  		t.logger.
   111  			WithField("id", t.reqID).
   112  			WithField("key", key).
   113  			WithField("value", "***").
   114  			Trace("writing header")
   115  	}
   116  }
   117  
   118  func (t *httpTrace) logGotConn(info httptrace.GotConnInfo) {
   119  	t.logger.
   120  		WithField("id", t.reqID).
   121  		WithField("local-addr", fmt.Sprintf("%s:%s", info.Conn.LocalAddr().Network(), info.Conn.RemoteAddr().String())).
   122  		WithField("remote-addr", fmt.Sprintf("%s:%s", info.Conn.RemoteAddr().Network(), info.Conn.RemoteAddr().String())).
   123  		Trace("connection established")
   124  }
   125  
   126  func (t *httpTrace) logTLSHandshakeStart() {
   127  	t.logger.
   128  		WithField("id", t.reqID).
   129  		Trace("TLS handshake start")
   130  }
   131  
   132  func (t *httpTrace) logTLSHandshakeDone(state tls.ConnectionState, err error) {
   133  	if err != nil {
   134  		t.logger.
   135  			WithError(err).
   136  			Trace("TLS handshake failure")
   137  		return
   138  	}
   139  	t.logger.
   140  		WithField("id", t.reqID).
   141  		WithField("protocol", state.NegotiatedProtocol).
   142  		WithField("server-name", state.ServerName).
   143  		Trace("TLS handshake completed")
   144  }
   145  
   146  func (t *httpTrace) logGotFirstResponseByte() {
   147  	t.logger.
   148  		WithField("id", t.reqID).
   149  		Trace("reading response")
   150  }
   151  
   152  func (t *httpTrace) logWroteRequest(info httptrace.WroteRequestInfo) {
   153  	if info.Err != nil {
   154  		t.logger.
   155  			WithField("id", t.reqID).
   156  			WithError(info.Err).
   157  			Trace("failed to write request")
   158  	}
   159  	t.logger.
   160  		WithField("id", t.reqID).
   161  		Trace("writing request completed")
   162  }
   163  
   164  // IsHTTPLogTraceEnabled -
   165  func IsHTTPLogTraceEnabled() bool {
   166  	return logHTTPTrace && log.GetLevel() == logrus.TraceLevel
   167  }