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 }