This repository was archived by the owner on Sep 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathoptions.go
158 lines (138 loc) · 5.54 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package http_logrus
import (
"net/http"
"github.com/improbable-eng/go-httpwares"
"github.com/sirupsen/logrus"
)
var (
defaultOptions = &options{
levelFunc: nil,
levelForConnectivityError: logrus.WarnLevel,
requestCaptureFunc: func(r *http.Request) bool { return false },
responseCaptureFunc: func(r *http.Request, status int) bool { return false },
requestFieldExtractor: func(req *http.Request) map[string]interface{} { return map[string]interface{}{} },
responseFieldExtractor: func(res httpwares.WrappedResponseWriter) map[string]interface{} {
return map[string]interface{}{}
},
}
)
type options struct {
levelFunc CodeToLevel
levelForConnectivityError logrus.Level
requestCaptureFunc func(r *http.Request) bool
responseCaptureFunc func(r *http.Request, status int) bool
requestFieldExtractor RequestFieldExtractorFunc
responseFieldExtractor ResponseFieldExtractorFunc
shouldLog Decider
}
func evaluateTripperwareOpts(opts []Option) *options {
optCopy := &options{}
*optCopy = *defaultOptions
optCopy.levelFunc = DefaultTripperwareCodeToLevel
for _, o := range opts {
o(optCopy)
}
return optCopy
}
func evaluateMiddlewareOpts(opts []Option) *options {
optCopy := &options{}
*optCopy = *defaultOptions
optCopy.levelFunc = DefaultMiddlewareCodeToLevel
for _, o := range opts {
o(optCopy)
}
return optCopy
}
type Option func(*options)
// CodeToLevel user functions define the mapping between HTTP status codes and logrus log levels.
type CodeToLevel func(httpStatusCode int) logrus.Level
// WithLevels customizes the function that maps HTTP client or server side status codes to log levels.
//
// By default `DefaultMiddlewareCodeToLevel` is used for server-side middleware, and `DefaultTripperwareCodeToLevel`
// is used for client-side tripperware.
func WithLevels(f CodeToLevel) Option {
return func(o *options) {
o.levelFunc = f
}
}
// WithConnectivityErrorLevel customizes
func WithConnectivityErrorLevel(level logrus.Level) Option {
return func(o *options) {
o.levelForConnectivityError = level
}
}
// WithRequestBodyCapture enables recording of request body pre-handling/pre-call.
//
// The body will be recorded as a separate log message. Body of `application/json` will be captured as
// http.request.body_json (in structured JSON form) and others will be captured as http.request.body_raw logrus field
// (raw base64-encoded value).
//
// For tripperware, only requests with Body of type `bytes.Buffer`, `strings.Reader`, `bytes.Buffer`, or with
// a specified `GetBody` function will be captured.
//
// For middleware, only requests with a set Content-Length will be captured, with no streaming or chunk encoding supported.
//
// This option creates a copy of the body per request, so please use with care.
func WithRequestBodyCapture(deciderFunc func(r *http.Request) bool) Option {
return func(o *options) {
o.requestCaptureFunc = deciderFunc
}
}
// WithResponseBodyCapture enables recording of response body post-handling/post-call.
//
// The body will be recorded as a separate log message. Body of `application/json` will be captured as
// http.response.body_json (in structured JSON form) and others will be captured as http.response.body_raw logrus field
// (raw base64-encoded value).
//
// Only responses with Content-Length will be captured, with non-default Transfer-Encoding not being supported.
func WithResponseBodyCapture(deciderFunc func(r *http.Request, status int) bool) Option {
return func(o *options) {
o.responseCaptureFunc = deciderFunc
}
}
// WithDecider customizes the function for deciding if the middleware logs at the end of the request.
func WithDecider(f Decider) Option {
return func(o *options) {
o.shouldLog = f
}
}
// Decider function defines rules for suppressing any interceptor logs
type Decider func(w httpwares.WrappedResponseWriter, r *http.Request) bool
// DefaultMiddlewareCodeToLevel is the default of a mapper between HTTP server-side status codes and logrus log levels.
func DefaultMiddlewareCodeToLevel(httpStatusCode int) logrus.Level {
if httpStatusCode < 400 || httpStatusCode == http.StatusNotFound {
return logrus.InfoLevel
} else if httpStatusCode < 500 {
return logrus.WarnLevel
} else if httpStatusCode < 600 {
return logrus.ErrorLevel
} else {
return logrus.ErrorLevel
}
}
// DefaultTripperwareCodeToLevel is the default of a mapper between HTTP client-side status codes and logrus log levels.
func DefaultTripperwareCodeToLevel(httpStatusCode int) logrus.Level {
if httpStatusCode < 400 {
return logrus.DebugLevel
} else if httpStatusCode < 500 {
return logrus.InfoLevel
} else {
return logrus.WarnLevel
}
}
// WithRequestFieldExtractor adds a field, allowing you to customize what fields get populated from the request.
func WithRequestFieldExtractor(f RequestFieldExtractorFunc) Option {
return func(o *options) {
o.requestFieldExtractor = f
}
}
// WithRequestFieldExtractor adds a field, allowing you to customize what fields get populated from the response.
func WithResponseFieldExtractor(f ResponseFieldExtractorFunc) Option {
return func(o *options) {
o.responseFieldExtractor = f
}
}
// RequestFieldExtractorFunc is a signature of user-customizable functions for extracting log fields from requests.
type RequestFieldExtractorFunc func(req *http.Request) map[string]interface{}
// ResponseFieldExtractorFunc is a signature of user-customizable functions for extracting log fields from responses.
type ResponseFieldExtractorFunc func(res httpwares.WrappedResponseWriter) map[string]interface{}