apm-agent-go
apm-agent-go copied to clipboard
Feature: buffalo middleware
Implement tracing middleware for https://gobuffalo.io
I could give it a Go any hints or recommendations you can offer?
Hi @theodesp, thanks for offering! I don't know Buffalo well, so I can only offer fairly general advice.
Looking at Buffalo's API, I think its middleware is roughly similar to Echo's; so I would suggest you copy apmecho, and adapt it to Buffalo's middleware API.
The middleware needs to be able to do a few things:
- get the current route (for the transaction name)
- update the request context
- capture the response status code
It appears that you can get the current route from the context (c.Value("current_route")), though at a glance that doesn't appear to be documented.
To update the request context and capture the response status code, you may have to wrap the buffalo.Context and its http.ResponseWriter. For wrapping an http.ResponseWriter, you can use apmhttp.WrapResponseWriter.
Besides the routing middleware, there's also "Pop" - Buffalo's ORM. Ideally we would create spans for those, but from what I've seen of the API it doesn't look achievable without major changes to Pop's API, since it doesn't work with context.
If that sounds doable, please feel free to assign yourself. I'm happy to provide more help along the way.
Yes Buffalo uses gorilla/mux as a router so I will borrow items from the apmgorilla package
c.Value("current_route") will return a RouteInfo object that contains the path for example
"/articles/{id:[0-9]+}" will return
{
"method": "GET",
"path": "/articles/{id:[0-9]+}/",
"handler": "github.com/theodesp/buffalo-example/coke/actions.App.func1",
"pathName": "articlePath",
"aliases": []
}
Then I will need to reuse the massageTemplate function from apmgorilla package to normalize it.
@axw I've created a draft PR for evaluation of the API https://github.com/elastic/apm-agent-go/pull/509
@axw I've updated the PR. Can you take a look. I need to add more tests.
Also, I need to figure out why the NotFoundHandler and the MethodNotAllowedHandler are not traced. I suspect it's because the framework adds a default one but does not call the middleware stack.