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
|
package httplog
import (
"context"
"net/http"
)
type Logger interface {
// Log logs an event of the given kind with the given request
// or response (either *Request or *Response).
Log(ctx context.Context, kind EventKind, r RequestOrResponse)
}
type EventKind int
//go:generate go run golang.org/x/tools/cmd/stringer -type=EventKind -linecomment
const (
NoEvent EventKind = iota
KindClientSendRequest // http client->
KindClientRecvResponse // http client<-
// TODO KindServerRecvRequest
// TODO KindServerSendResponse
)
// Request represents an HTTP request.
type Request struct {
ID int64 `json:"id"`
Method string `json:"method"`
URL string `json:"url"`
ContentLength int64 `json:"contentLength"`
Header http.Header `json:"header"`
BodyData
}
func (*Request) requestOrResponse() {}
// RequestOrResponse is implemented by [*Request] and [*Response].
type RequestOrResponse interface {
requestOrResponse()
}
// TODO include timing data for when the initial response was received
// vs the body being read?
// Response represents an HTTP response.
type Response struct {
ID int64 `json:"id"`
Method string `json:"method,omitempty"`
URL string `json:"url,omitempty"`
Error string `json:"error,omitempty"`
StatusCode int `json:"statusCode,omitempty"`
Header http.Header `json:"header,omitempty"`
BodyData
}
// BodyData holds information about the body of a request
// or response.
type BodyData struct {
Body string `json:"body,omitempty"`
Body64 []byte `json:"body64,omitempty"`
BodyRedactedBecause string `json:"bodyRedactedBecause,omitempty"`
BodyTruncated bool `json:"bodyTruncated,omitempty"`
}
func (*Response) requestOrResponse() {}
|