github.com/xmidt-org/webpa-common@v1.11.9/logging/logginghttp/setLogger.go (about)

     1  package logginghttp
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/textproto"
     7  
     8  	"github.com/go-kit/kit/log"
     9  	"github.com/gorilla/mux"
    10  	"github.com/xmidt-org/webpa-common/logging"
    11  )
    12  
    13  var (
    14  	requestMethodKey interface{} = "requestMethod"
    15  	requestURIKey    interface{} = "requestURI"
    16  	remoteAddrKey    interface{} = "remoteAddr"
    17  )
    18  
    19  // RequestMethodKey returns the contextual logging key for an HTTP request's method
    20  func RequestMethodKey() interface{} {
    21  	return requestMethodKey
    22  }
    23  
    24  // RequestURIKey returns the contextual logging key for an HTTP request's unmodified URI
    25  func RequestURIKey() interface{} {
    26  	return requestURIKey
    27  }
    28  
    29  // RemoteAddr returns the contextual logging key for an HTTP request's remote address,
    30  // as filled in by the enclosing http.Server.
    31  func RemoteAddrKey() interface{} {
    32  	return remoteAddrKey
    33  }
    34  
    35  // LoggerFunc is a strategy for adding key/value pairs (possibly) based on an HTTP request.
    36  // Functions of this type must append key/value pairs to the supplied slice and then return
    37  // the new slice.
    38  type LoggerFunc func([]interface{}, *http.Request) []interface{}
    39  
    40  // RequestInfo is a LoggerFunc that adds the request information described by logging keys in this package.
    41  func RequestInfo(kv []interface{}, request *http.Request) []interface{} {
    42  	return append(kv,
    43  		requestMethodKey, request.Method,
    44  		requestURIKey, request.RequestURI,
    45  		remoteAddrKey, request.RemoteAddr,
    46  	)
    47  
    48  }
    49  
    50  // Header returns a logger func that extracts the value of a header and inserts it as the
    51  // value of a logging key.  If the header is not present in the request, a blank string
    52  // is set as the logging key's value.
    53  func Header(headerName, keyName string) LoggerFunc {
    54  	headerName = textproto.CanonicalMIMEHeaderKey(headerName)
    55  
    56  	return func(kv []interface{}, request *http.Request) []interface{} {
    57  		values := request.Header[headerName]
    58  		switch len(values) {
    59  		case 0:
    60  			return append(kv, keyName, "")
    61  		case 1:
    62  			return append(kv, keyName, values[0])
    63  		default:
    64  			return append(kv, keyName, values)
    65  		}
    66  	}
    67  }
    68  
    69  // PathVariable returns a LoggerFunc that extracts the value of a gorilla/mux path variable and inserts
    70  // it into the value of a logging key.  If the variable is not present, a blank string is
    71  // set as the logging key's value.
    72  func PathVariable(variableName, keyName string) LoggerFunc {
    73  	return func(kv []interface{}, request *http.Request) []interface{} {
    74  		variables := mux.Vars(request)
    75  		if len(variables) > 0 {
    76  			return append(kv, keyName, variables[variableName])
    77  		}
    78  
    79  		return append(kv, keyName, "")
    80  	}
    81  }
    82  
    83  // SetLogger produces a go-kit RequestFunc that inserts a go-kit Logger into the context.
    84  // Zero or more LoggerFuncs can be provided to added key/values.  Note that nothing is added to
    85  // the base logger by default.  If no LoggerFuncs are supplied, the base Logger is added to the
    86  // context as is.  In particular, RequestInfo must be used to inject the request method, uri, etc.
    87  //
    88  // The base logger must be non-nil.  There is no default applied.
    89  //
    90  // The returned function can be used with xcontext.Populate.
    91  func SetLogger(base log.Logger, lf ...LoggerFunc) func(context.Context, *http.Request) context.Context {
    92  	if base == nil {
    93  		panic("The base Logger cannot be nil")
    94  	}
    95  
    96  	if len(lf) > 0 {
    97  		return func(ctx context.Context, request *http.Request) context.Context {
    98  			kv := []interface{}{}
    99  			for _, f := range lf {
   100  				kv = f(kv, request)
   101  			}
   102  
   103  			return logging.WithLogger(
   104  				ctx,
   105  				log.With(base, kv...),
   106  			)
   107  		}
   108  	}
   109  
   110  	return func(ctx context.Context, _ *http.Request) context.Context {
   111  		return logging.WithLogger(ctx, base)
   112  	}
   113  }