Honeybadger.io integration


#1

I am looking to use Honeybadger.io in echo and I am able to use it for several things, but I want it to handle panic logging for us well. If we were using the basic golang http.Handler, we would just do the below to wrapper things.

log.Fatal(http.ListenAndServe(":8080", honeybadger.Handler(handler)))

However, with echo, I can’t do that. Using their wrapper allows the reporting to Honeybadger to have things about the context of the request (env variables, headers, URI, etc). I want to integrate that, but I am not seeing how easily.


#2

You can treat Echo as standard HTTP handler, so something like below should work:

package main

import (
	"net/http"

	honeybadger "github.com/honeybadger-io/honeybadger-go"
	"github.com/labstack/echo"
)

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.JSON(200, "Hello, World!")
	})
	e.Logger.Fatal(http.ListenAndServe(":8080", honeybadger.Handler(e)))
}

#3

but the way you start the server for Echo is with “e.Start(”:" + portnum)" type of way. That does not give you the option to set a handler wrapper.

Perhaps I should be doing something with echo.Wraphandler?

Thanks for the suggestion.


#4

In this case honebadger want to wrap Echo go get the control, so we have to do like this.

This is helpful to use http.Handler with Echo while setting up a specific route.


#5

Ok, do I lose anything by not using the Start method and instead using the ListenAndServe?


#6

I don’t think you are loosing anything… It is just that you will skip this function call https://github.com/labstack/echo/blob/master/echo.go#L626 as you will be running the server using ListenAndServe.


#7

Ok, I did that and it does start my server fine but I don’t see to be getting anything going to Honeybadger when I purposely put in a panic. I get my customer error page though. I wonder if I have to do something with the custom error page handling to get this to work.


#8

What all middleware are you using? Recover() will capture the panic.


#9

That could be it, it is never getting outside of the recover middleware. I wonder if I can put it into the Recover middleware somehow?


#10

I think having both of them is redundant. Additionally, you can manually call honeybadger from your custom http error handler.


#11

Thanks for all your help. It led me to doing it from my custom handler as you said. However, I also found that I had to emulate some of what the go library does. For instance, this may help some people later with echo. These are some helper functions I wrote. One is emulating what is done in the honeybadger library for it’s default catching of the error and the other things are just grabbing the equivalent items from echo that the Notify function needs. The documentation does not mention that you can put some extra data into notify and have it show up nice and rendered in the honeybadger web interface. I had to look through the git repo to see how it was done and what was done internally on the panic handler to figure it out.

func ReportError(err error, ctx echo.Context) {
	honeybadger.Notify(err, honeybadger.Context{
		"parameters": ctx.QueryParams(),
		"action":     ctx.Request().Method,
	}, *ctx.Request().URL, getCGIData(ctx.Request()))
}

func getCGIData(request *http.Request) honeybadger.CGIData {
	cgiData := honeybadger.CGIData{}
	replacer := strings.NewReplacer("-", "_")
	for k, v := range request.Header {
		key := "HTTP_" + replacer.Replace(strings.ToUpper(k))
		cgiData[key] = v[0]
	}
	return cgiData
}

#12

You may be interested in Reporter middleware which automatically sends error reports and notify you via different channels.


#13

Exactly,
Won’t lose anything. There are alternatives to this approach as well to the ListenAndSereve