@@ -450,11 +450,9 @@ func (r *Request) Body(obj interface{}) *Request {
450
450
r .err = err
451
451
return r
452
452
}
453
- glogBody ("Request Body" , data )
454
453
r .body = nil
455
454
r .bodyBytes = data
456
455
case []byte :
457
- glogBody ("Request Body" , t )
458
456
r .body = nil
459
457
r .bodyBytes = t
460
458
case io.Reader :
@@ -475,7 +473,6 @@ func (r *Request) Body(obj interface{}) *Request {
475
473
r .err = err
476
474
return r
477
475
}
478
- glogBody ("Request Body" , data )
479
476
r .body = nil
480
477
r .bodyBytes = data
481
478
r .SetHeader ("Content-Type" , r .c .content .ContentType )
@@ -704,6 +701,10 @@ func (b *throttledLogger) Infof(message string, args ...interface{}) {
704
701
// Watch attempts to begin watching the requested location.
705
702
// Returns a watch.Interface, or an error.
706
703
func (r * Request ) Watch (ctx context.Context ) (watch.Interface , error ) {
704
+ if r .body == nil {
705
+ logBody (ctx , 2 , "Request Body" , r .bodyBytes )
706
+ }
707
+
707
708
// We specifically don't want to rate limit watches, so we
708
709
// don't use r.rateLimiter here.
709
710
if r .err != nil {
@@ -752,7 +753,7 @@ func (r *Request) Watch(ctx context.Context) (watch.Interface, error) {
752
753
// the server must have sent us an error in 'err'
753
754
return true , nil
754
755
}
755
- result := r .transformResponse (resp , req )
756
+ result := r .transformResponse (ctx , resp , req )
756
757
if err := result .Error (); err != nil {
757
758
return true , err
758
759
}
@@ -845,6 +846,10 @@ func (r WatchListResult) Into(obj runtime.Object) error {
845
846
// Check the documentation https://kubernetes.io/docs/reference/using-api/api-concepts/#streaming-lists
846
847
// to see what parameters are currently required.
847
848
func (r * Request ) WatchList (ctx context.Context ) WatchListResult {
849
+ if r .body == nil {
850
+ logBody (ctx , 2 , "Request Body" , r .bodyBytes )
851
+ }
852
+
848
853
if ! clientfeatures .FeatureGates ().Enabled (clientfeatures .WatchListClient ) {
849
854
return WatchListResult {err : fmt .Errorf ("%q feature gate is not enabled" , clientfeatures .WatchListClient )}
850
855
}
@@ -969,6 +974,10 @@ func sanitize(req *Request, resp *http.Response, err error) (string, string) {
969
974
// Any non-2xx http status code causes an error. If we get a non-2xx code, we try to convert the body into an APIStatus object.
970
975
// If we can, we return that as an error. Otherwise, we create an error that lists the http status and the content of the response.
971
976
func (r * Request ) Stream (ctx context.Context ) (io.ReadCloser , error ) {
977
+ if r .body == nil {
978
+ logBody (ctx , 2 , "Request Body" , r .bodyBytes )
979
+ }
980
+
972
981
if r .err != nil {
973
982
return nil , r .err
974
983
}
@@ -1012,7 +1021,7 @@ func (r *Request) Stream(ctx context.Context) (io.ReadCloser, error) {
1012
1021
if retry .IsNextRetry (ctx , r , req , resp , err , neverRetryError ) {
1013
1022
return false , nil
1014
1023
}
1015
- result := r .transformResponse (resp , req )
1024
+ result := r .transformResponse (ctx , resp , req )
1016
1025
if err := result .Error (); err != nil {
1017
1026
return true , err
1018
1027
}
@@ -1199,9 +1208,13 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp
1199
1208
// - If the server responds with a status: *errors.StatusError or *errors.UnexpectedObjectError
1200
1209
// - http.Client.Do errors are returned directly.
1201
1210
func (r * Request ) Do (ctx context.Context ) Result {
1211
+ if r .body == nil {
1212
+ logBody (ctx , 2 , "Request Body" , r .bodyBytes )
1213
+ }
1214
+
1202
1215
var result Result
1203
1216
err := r .request (ctx , func (req * http.Request , resp * http.Response ) {
1204
- result = r .transformResponse (resp , req )
1217
+ result = r .transformResponse (ctx , resp , req )
1205
1218
})
1206
1219
if err != nil {
1207
1220
return Result {err : err }
@@ -1214,10 +1227,14 @@ func (r *Request) Do(ctx context.Context) Result {
1214
1227
1215
1228
// DoRaw executes the request but does not process the response body.
1216
1229
func (r * Request ) DoRaw (ctx context.Context ) ([]byte , error ) {
1230
+ if r .body == nil {
1231
+ logBody (ctx , 2 , "Request Body" , r .bodyBytes )
1232
+ }
1233
+
1217
1234
var result Result
1218
1235
err := r .request (ctx , func (req * http.Request , resp * http.Response ) {
1219
1236
result .body , result .err = io .ReadAll (resp .Body )
1220
- glogBody ( "Response Body" , result .body )
1237
+ logBody ( ctx , 2 , "Response Body" , result .body )
1221
1238
if resp .StatusCode < http .StatusOK || resp .StatusCode > http .StatusPartialContent {
1222
1239
result .err = r .transformUnstructuredResponseError (resp , req , result .body )
1223
1240
}
@@ -1232,7 +1249,7 @@ func (r *Request) DoRaw(ctx context.Context) ([]byte, error) {
1232
1249
}
1233
1250
1234
1251
// transformResponse converts an API response into a structured API object
1235
- func (r * Request ) transformResponse (resp * http.Response , req * http.Request ) Result {
1252
+ func (r * Request ) transformResponse (ctx context. Context , resp * http.Response , req * http.Request ) Result {
1236
1253
var body []byte
1237
1254
if resp .Body != nil {
1238
1255
data , err := io .ReadAll (resp .Body )
@@ -1261,7 +1278,8 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
1261
1278
}
1262
1279
}
1263
1280
1264
- glogBody ("Response Body" , body )
1281
+ // Call depth is tricky. This one is okay for Do and DoRaw.
1282
+ logBody (ctx , 7 , "Response Body" , body )
1265
1283
1266
1284
// verify the content type is accurate
1267
1285
var decoder runtime.Decoder
@@ -1321,14 +1339,14 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu
1321
1339
}
1322
1340
1323
1341
// truncateBody decides if the body should be truncated, based on the glog Verbosity.
1324
- func truncateBody (body string ) string {
1342
+ func truncateBody (logger klog. Logger , body string ) string {
1325
1343
max := 0
1326
1344
switch {
1327
- case bool (klog .V (10 ).Enabled ()):
1345
+ case bool (logger .V (10 ).Enabled ()):
1328
1346
return body
1329
- case bool (klog .V (9 ).Enabled ()):
1347
+ case bool (logger .V (9 ).Enabled ()):
1330
1348
max = 10240
1331
- case bool (klog .V (8 ).Enabled ()):
1349
+ case bool (logger .V (8 ).Enabled ()):
1332
1350
max = 1024
1333
1351
}
1334
1352
@@ -1339,17 +1357,21 @@ func truncateBody(body string) string {
1339
1357
return body [:max ] + fmt .Sprintf (" [truncated %d chars]" , len (body )- max )
1340
1358
}
1341
1359
1342
- // glogBody logs a body output that could be either JSON or protobuf. It explicitly guards against
1360
+ // logBody logs a body output that could be either JSON or protobuf. It explicitly guards against
1343
1361
// allocating a new string for the body output unless necessary. Uses a simple heuristic to determine
1344
1362
// whether the body is printable.
1345
- func glogBody (prefix string , body []byte ) {
1346
- if klogV := klog .V (8 ); klogV .Enabled () {
1363
+ //
1364
+ // It needs to be called by all functions which send or receive the data.
1365
+ func logBody (ctx context.Context , callDepth int , prefix string , body []byte ) {
1366
+ logger := klog .FromContext (ctx )
1367
+ if loggerV := logger .V (8 ); loggerV .Enabled () {
1368
+ loggerV := loggerV .WithCallDepth (callDepth )
1347
1369
if bytes .IndexFunc (body , func (r rune ) bool {
1348
1370
return r < 0x0a
1349
1371
}) != - 1 {
1350
- klogV . Infof ( "%s: \n %s " , prefix , truncateBody (hex .Dump (body )))
1372
+ loggerV . Info ( prefix , "body " , truncateBody (logger , hex .Dump (body )))
1351
1373
} else {
1352
- klogV . Infof ( "%s: %s" , prefix , truncateBody (string (body )))
1374
+ loggerV . Info ( prefix , "body" , truncateBody (logger , string (body )))
1353
1375
}
1354
1376
}
1355
1377
}
0 commit comments