Skip to content

Instantly share code, notes, and snippets.

@briangershon
Created January 8, 2017 07:57
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save briangershon/fa9feb08e6a65d52bdc35c738d8cf104 to your computer and use it in GitHub Desktop.
Save briangershon/fa9feb08e6a65d52bdc35c738d8cf104 to your computer and use it in GitHub Desktop.
Log Request Body for Debugging (golang)
buf, bodyErr := ioutil.ReadAll(r.Body)
if bodyErr != nil {
log.Print("bodyErr ", bodyErr.Error())
http.Error(w, bodyErr.Error(), http.StatusInternalServerError)
return
}
rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf))
rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf))
log.Printf("BODY: %q", rdr1)
r.Body = rdr2
@vituchon
Copy link

vituchon commented Jun 6, 2019

nice snippet! Thanks for sharing!

@abhishek-buragadda
Copy link

nice

@nstansby
Copy link

Thank you, this pointed me in the right direction. But it seems this is dangerous code. From the docs for NewBuffer():

NewBuffer creates and initializes a new Buffer using buf as its initial contents. The new Buffer takes ownership of buf, and the caller should not use buf after this call.

But this code is using buf twice. Moreover, while you need to construct a NopCloser to make the stored content readable, is there really any reason to construct a second one just to log it?

I got what I needed with the following code, which only creates one NopCloser and also doesn't violate the directive to not use the byte buffer after calling bytes.Newbuffer() (this uses zerolog logging syntax but hopefully the difference is still clear):

	buf, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Error().Msgf("Error reading request body: %v", err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	log.Debug().Msgf("Request body: %v", string(buf))

	reader := ioutil.NopCloser(bytes.NewBuffer(buf))
	r.Body = reader

@briangershon
Copy link
Author

Thanks @nstansby -- you're right, a second NopCloser not needed since you can just log the message as you've demonstrated above, then create just the one NopCloser for r.Body to continue on.

Mine was mainly a quick paste-in for debugging, so I didn't invest too much time in it.

Yours is nicer and could be used for debugging or production logging. Thanks again for adding your improvements!

@xbhoneybee
Copy link

It helps a lot, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment