Skip to content

Instantly share code, notes, and snippets.

@arschles
Last active September 11, 2018 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arschles/f3afb2000343f951b2629d326084de1e to your computer and use it in GitHub Desktop.
Save arschles/f3afb2000343f951b2629d326084de1e to your computer and use it in GitHub Desktop.
Threading Log Entries Down the Stack in Athens
func newLogEntry(req *http.Request, lggr *log.Logger) logrus.Entry {
return lggr.WithFields(logrus.Fields{
"http-method": req.Method,
"http-path": req.URL.Path,
"http-url": req.URL.String(),
})
}
// LogEntryHandler constructs a log.Entry out of the given
// *log.Logger so that it applies default fields to every single
// incoming request without having to do those in every single handler.
// This is like a middleware minus the context magic.
func LogEntryHandler(ph ProtocolHandler, opts *HandlerOpts) buffalo.Handler {
return func(c buffalo.Context) error {
ent := newLogEntry(c.Request(), opts.Logger)
handler := ph(opts.Protocol, ent, opts.Engine)
return handler(c)
}
}
// NewValidationMiddleware builds a middleware function that performs validation checks by calling
// an external webhook
func NewValidationMiddleware(lggr *log.Logger, validatorHook string) buffalo.MiddlewareFunc {
const op errors.Op = "actions.ValidationMiddleware"
return func(next buffalo.Handler) buffalo.Handler {
return func(c buffalo.Context) error {
entry := newLogEntry(c.Request(), lggr)
mod, err := paths.GetModule(c)
if err != nil {
// if there is no module the path we are hitting is not one related to modules, like /
return next(c)
}
// not checking the error. Not all requests include a version
// i.e. list requests path is like /{module:.+}/@v/list with no version parameter
version, _ := paths.GetVersion(c)
if version != "" {
valid, err := validate(validatorHook, mod, version)
if err != nil {
entry.SystemErr(err)
return c.Render(http.StatusInternalServerError, nil)
}
if !valid {
return c.Render(http.StatusForbidden, nil)
}
}
return next(c)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment