Skip to content

Instantly share code, notes, and snippets.

Created September 26, 2017 18:11
What would you like to do?
Wrapping a request with libhoney
func (a *App) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
// we wrap the writer to gain access to the status field later
w := api.NewResponseWrapper(writer)
builder := libhoney.NewBuilder()
// we wrap libhoney in an interface to abstract events vs. builders
hnyWrapper := &libhoneyWrapper{builder: builder}
// Embed the libhoney wrapper in a context to give the rest of the code access
ctx := context.WithValue(request.Context(), CtxKeyLibhoney, hnyWrapper)
r := request.WithContext(ctx)
// send the event at the end of the request, even if it panics
defer func() {
// this evt will have all fields added throughout the request's lifetime
evt := builder.NewEvent()
if p := recover(); p != nil {
evt.AddField("panic", p)
evt.AddField("status", w.Status())
// apply dynamic sampling to make sure all customers are represented
// while discarding most high volume successful traffic
if a.DynamicSampler != nil {
key := fmt.Sprintf("%s,%s,%v,%v", r.Method, r.URL.Path,
hnyWrapper.datasetID, w.Status())
evt.AddField("dynsample_key", key)
rate := a.DynamicSampler.GetSampleRate(key)
evt.AddField("dynsample_rate", rate)
evt.SampleRate = uint(rate)
// add a timer for the entire request
defer trackTimer(hnyWrapper, "request", time.Now())
// go on and actually handle the request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment