Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6dbde52

Browse files
authored
fix: omit body field from SDK client request/response logs when not logging bodies (#20729)
In SDK request logs, when we don't enable LogBodies, before this change it looks in the logs like we are sending empty bodies.```2025-11-08 01:03:54.710 [debu] sdk request method=POST url=https://coder.example/api/v2/workspaceagents/aws-instance-identity body=""2025-11-08 01:03:54.765 [debu] sdk response method=POST url=https://coder.example/api/v2/workspaceagents/aws-instance-identity status=400 body="" trace_id="" span_id=""```This changes our request and response logging so we omit the `body` field when not logging bodies, rather than show a misleading empty string.
1 parentca94588 commit6dbde52

File tree

2 files changed

+51
-9
lines changed

2 files changed

+51
-9
lines changed

‎codersdk/client.go‎

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,17 @@ func (c *Client) RequestWithoutSessionToken(ctx context.Context, method, path st
251251
}
252252

253253
// Copy the request body so we can log it.
254-
varreqBody []byte
254+
varreqLogFields []any
255255
c.mu.RLock()
256256
logBodies:=c.logBodies
257257
c.mu.RUnlock()
258258
ifr!=nil&&logBodies {
259-
reqBody,err=io.ReadAll(r)
259+
reqBody,err:=io.ReadAll(r)
260260
iferr!=nil {
261261
returnnil,xerrors.Errorf("read request body: %w",err)
262262
}
263263
r=bytes.NewReader(reqBody)
264+
reqLogFields=append(reqLogFields,slog.F("body",string(reqBody)))
264265
}
265266

266267
req,err:=http.NewRequestWithContext(ctx,method,serverURL.String(),r)
@@ -291,7 +292,7 @@ func (c *Client) RequestWithoutSessionToken(ctx context.Context, method, path st
291292
slog.F("url",req.URL.String()),
292293
)
293294
tracing.RunWithoutSpan(ctx,func(ctx context.Context) {
294-
c.Logger().Debug(ctx,"sdk request",slog.F("body",string(reqBody)))
295+
c.Logger().Debug(ctx,"sdk request",reqLogFields...)
295296
})
296297

297298
resp,err:=c.HTTPClient.Do(req)
@@ -324,11 +325,11 @@ func (c *Client) RequestWithoutSessionToken(ctx context.Context, method, path st
324325
span.SetStatus(httpconv.ClientStatus(resp.StatusCode))
325326

326327
// Copy the response body so we can log it if it's a loggable mime type.
327-
varrespBody []byte
328+
varrespLogFields []any
328329
ifresp.Body!=nil&&logBodies {
329330
mimeType:=parseMimeType(resp.Header.Get("Content-Type"))
330331
if_,ok:=loggableMimeTypes[mimeType];ok {
331-
respBody,err=io.ReadAll(resp.Body)
332+
respBody,err:=io.ReadAll(resp.Body)
332333
iferr!=nil {
333334
returnnil,xerrors.Errorf("copy response body for logs: %w",err)
334335
}
@@ -337,16 +338,18 @@ func (c *Client) RequestWithoutSessionToken(ctx context.Context, method, path st
337338
returnnil,xerrors.Errorf("close response body: %w",err)
338339
}
339340
resp.Body=io.NopCloser(bytes.NewReader(respBody))
341+
respLogFields=append(respLogFields,slog.F("body",string(respBody)))
340342
}
341343
}
342344

343345
// See above for why this is not logged to the span.
344346
tracing.RunWithoutSpan(ctx,func(ctx context.Context) {
345347
c.Logger().Debug(ctx,"sdk response",
346-
slog.F("status",resp.StatusCode),
347-
slog.F("body",string(respBody)),
348-
slog.F("trace_id",resp.Header.Get("X-Trace-Id")),
349-
slog.F("span_id",resp.Header.Get("X-Span-Id")),
348+
append(respLogFields,
349+
slog.F("status",resp.StatusCode),
350+
slog.F("trace_id",resp.Header.Get("X-Trace-Id")),
351+
slog.F("span_id",resp.Header.Get("X-Span-Id")),
352+
)...,
350353
)
351354
})
352355

‎codersdk/client_internal_test.go‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,45 @@ func Test_Client(t *testing.T) {
162162
require.Contains(t,logStr,strings.ReplaceAll(resBody,`"`,`\"`))
163163
}
164164

165+
funcTest_Client_LogBodiesFalse(t*testing.T) {
166+
t.Parallel()
167+
168+
constmethod=http.MethodPost
169+
constpath="/ok"
170+
constreqBody=`{"msg": "request body"}`
171+
constresBody=`{"status": "ok"}`
172+
173+
s:=httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
174+
w.Header().Set("Content-Type",jsonCT)
175+
w.WriteHeader(http.StatusOK)
176+
_,_=io.WriteString(w,resBody)
177+
}))
178+
179+
u,err:=url.Parse(s.URL)
180+
require.NoError(t,err)
181+
client:=New(u)
182+
183+
logBuf:=bytes.NewBuffer(nil)
184+
client.SetLogger(slog.Make(sloghuman.Sink(logBuf)).Leveled(slog.LevelDebug))
185+
client.SetLogBodies(false)
186+
187+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
188+
defercancel()
189+
190+
resp,err:=client.Request(ctx,method,path, []byte(reqBody))
191+
require.NoError(t,err)
192+
deferresp.Body.Close()
193+
194+
body,err:=io.ReadAll(resp.Body)
195+
require.NoError(t,err)
196+
require.Equal(t,resBody,string(body))
197+
198+
logStr:=logBuf.String()
199+
require.Contains(t,logStr,"sdk request")
200+
require.Contains(t,logStr,"sdk response")
201+
require.NotContains(t,logStr,"body")
202+
}
203+
165204
funcTest_readBodyAsError(t*testing.T) {
166205
t.Parallel()
167206

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp