Skip to content

Commit

Permalink
Added reporter middleware
Browse files Browse the repository at this point in the history
Signed-off-by: Vishal Rana <[email protected]>
  • Loading branch information
vishr committed Sep 18, 2017
1 parent c43bc4a commit 743dce7
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: go
go:
- 1.7.x
- 1.8.x
- 1.8.x
- tip
install:
Expand Down
28 changes: 14 additions & 14 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,20 @@

[[constraint]]
name = "github.com/casbin/casbin"
version = "0.8.0"
version = "1.0.0"

[[constraint]]
name = "github.com/gorilla/sessions"
version = "1.1.0"

[[constraint]]
branch = "master"
name = "github.com/labstack/echo"
version = "3.2.3"

[[constraint]]
branch = "master"
name = "github.com/labstack/labstack-go"
version = "0.7.2"

[[constraint]]
name = "github.com/stretchr/testify"
version = "1.1.4"
9 changes: 7 additions & 2 deletions cube/cube.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type (
// App name
AppName string

// LabStack Account ID
AccountID string `json:"account_id"`

// LabStack API key
APIKey string `json:"api_key"`

Expand All @@ -44,8 +47,9 @@ var (
)

// Middleware implements Cube middleware.
func Middleware(apiKey string) echo.MiddlewareFunc {
func Middleware(accountID, apiKey string) echo.MiddlewareFunc {
c := DefaultConfig
c.AccountID = accountID
c.APIKey = apiKey
return MiddlewareWithConfig(c)
}
Expand All @@ -68,7 +72,8 @@ func MiddlewareWithConfig(config Config) echo.MiddlewareFunc {
}

// Initialize
cube := labstack.NewClient(config.APIKey).Cube()
client := labstack.NewClient(config.AccountID, config.APIKey)
cube := client.Cube()
cube.AppID = config.AppID
cube.AppName = config.AppName
cube.APIKey = config.APIKey
Expand Down
120 changes: 120 additions & 0 deletions reporter/reporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package reporter

import (
"fmt"
"runtime"

"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"github.com/labstack/labstack-go"
)

type (
// Config defines the config for Reporter middleware.
Config struct {
// Skipper defines a function to skip middleware.
Skipper middleware.Skipper

// App ID
AppID string

// App name
AppName string

// LabStack Account ID
AccountID string `json:"account_id"`

// LabStack API key
APIKey string `json:"api_key"`

// Headers to include
Headers []string `json:"headers"`

// TODO: To be implemented
ClientLookup string `json:"client_lookup"`
}
)

var (
// DefaultConfig is the default Reporter middleware config.
DefaultConfig = Config{
Skipper: middleware.DefaultSkipper,
}
)

// Middleware implements Reporter middleware.
func Middleware(accountID string, apiKey string) echo.MiddlewareFunc {
c := DefaultConfig
c.AccountID = accountID
c.APIKey = apiKey
return MiddlewareWithConfig(c)
}

// MiddlewareWithConfig returns a Reporter middleware with config.
// See: `Middleware()`.
func MiddlewareWithConfig(config Config) echo.MiddlewareFunc {
// Defaults
if config.APIKey == "" {
panic("echo: reporter middleware requires an api key")
}
if config.Skipper == nil {
config.Skipper = DefaultConfig.Skipper
}

// Initialize
client := labstack.NewClient(config.AccountID, config.APIKey)
log := client.Log()
log.Fields.Add("app_id", config.AppID).
Add("app_name", config.AppName)

return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) (err error) {
if config.Skipper(c) {
return next(c)
}

// Capture error and non-fatal report
c.Echo().HTTPErrorHandler = func(err error, c echo.Context) {
c.Echo().DefaultHTTPErrorHandler(err, c)
fields := labstack.Fields{}.
Add("message", err.Error())
appendFields(fields, c, config)
log.Error(fields)
}

// Automatically report fatal error
defer func() {
if r := recover(); r != nil {
var err error
switch r := r.(type) {
case error:
err = r
default:
err = fmt.Errorf("%v", r)
}
stack := make([]byte, 4<<10) // 4 KB
length := runtime.Stack(stack, false)
fields := labstack.Fields{}.
Add("message", err.Error()).
Add("stack_trace", string(stack[:length]))
appendFields(fields, c, config)
log.Fatal(fields)
}
}()
return next(c)
}
}
}

func appendFields(f labstack.Fields, c echo.Context, config Config) {
f.
Add("host", c.Request().Host).
Add("path", c.Request().URL.Path).
Add("method", c.Request().Method).
Add("client_id", c.RealIP()).
Add("remote_ip", c.RealIP()).
Add("status", c.Response().Status)
for _, h := range config.Headers {
f.Add("header_"+h, c.Request().Header.Get(h))
}
}

0 comments on commit 743dce7

Please sign in to comment.