Documentation
¶
Overview ¶
Package observe exposes a standard way of decorating http.ResponseWriter objects so that they can be examined by infrastructure such as logging and metrics.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Then ¶
Then is a serverside middleware that ensures the next handler sees an observable Writer in it ServeHTTP method. This method is idempotent. If next is already an observable handler, it is returned as is. Additionally, if an http.ResponseWriter is already observable, possibly due to other infrastructure, the returned handler will simply pass the call through to next.
Example ¶
decorator := Then(
http.HandlerFunc(func(response http.ResponseWriter, _ *http.Request) {
o := response.(Writer)
// register a callback to be notified when a status code is written
o.OnWriteHeader(func(code int) {
fmt.Println("onWriteHeader callback =>", "code:", code)
})
// this will normally be done in another nested handler
o.WriteHeader(201)
// now, decorator code can access observed information
fmt.Println("observed status code:", o.StatusCode())
}),
)
response := httptest.NewRecorder()
request := httptest.NewRequest("GET", "/example", nil)
decorator.ServeHTTP(response, request)
Output: onWriteHeader callback => code: 201 observed status code: 201
Types ¶
type OnWriteHeader ¶
type OnWriteHeader func(int)
OnWriteHeader is a callback that is invoked once a handler either invokes WriteHeader or calls Write for the first time. Note that if a handler never writes to the response body for any reason, including panicing, these callbacks will not be invoked.
Use of this callback enables logging and metrics around things like how long a handler took to write headers. Note that the status code passed to this callback is also available via the StatusCoder interface, so use of this callback is only in the niche cases where code needs to be aware of the point in time the header was written.
type ResponseBody ¶
type ResponseBody interface {
// ContentLength returns the count of bytes actually written with Write. It does
// not consult the Content-Length header.
//
// The count of bytes returned by this method is simply the current count of bytes
// written so far. If Write is called after this method, this method will return
// a different value.
ContentLength() int64
}
ResponseBody is the interface implemented by an observable http.ResponseWriter
type StatusCoder ¶
type StatusCoder interface {
// StatusCode returns the response code reported through WriteHeader. Certain
// methods cause WriteHeader to be called implicitly, with a status of http.StatusOK.
//
// If no status code has been written yet, this method returns zero (0).
StatusCode() int
}
StatusCoder is the interface implemented by an observable http.ResponseWriter.
type Writer ¶
type Writer interface {
http.ResponseWriter
StatusCoder
ResponseBody
// OnWriteHeader appends callbacks that are invoked when WriteHeader is called, whether
// explicitly or implicitly due to calling methods like Flush.
//
// If the status code for the response has already been established, these callbacks
// are invoked immediately.
OnWriteHeader(...OnWriteHeader)
}
Writer is the decorator interface for instrumented http.ResponseWriter instances. Instances of this interface are created with New to decorate an existing response writer.
func New ¶
func New(delegate http.ResponseWriter) Writer
New decorates an http.ResponseWriter to produces a Writer If the delegate is already an Writer, it is returned as is.
There are several optional interfaces that an http.ResponseWriter may implement. If the delegate implements any of the following interfaces, the returned observable writer will as well:
- http.Pusher
- http.Flusher
- http.Hijacker
- io.ReaderFrom