Skip to content

Commit 743dce7

Browse files
committed
Added reporter middleware
Signed-off-by: Vishal Rana <vr@labstack.com>
1 parent c43bc4a commit 743dce7

File tree

5 files changed

+149
-20
lines changed

5 files changed

+149
-20
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: go
22
go:
3-
- 1.7.x
3+
- 1.8.x
44
- 1.8.x
55
- tip
66
install:

Gopkg.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,20 @@
2323

2424
[[constraint]]
2525
name = "github.com/casbin/casbin"
26-
version = "0.8.0"
26+
version = "1.0.0"
2727

2828
[[constraint]]
2929
name = "github.com/gorilla/sessions"
3030
version = "1.1.0"
3131

3232
[[constraint]]
33-
branch = "master"
3433
name = "github.com/labstack/echo"
34+
version = "3.2.3"
3535

3636
[[constraint]]
37-
branch = "master"
3837
name = "github.com/labstack/labstack-go"
38+
version = "0.7.2"
39+
40+
[[constraint]]
41+
name = "github.com/stretchr/testify"
42+
version = "1.1.4"

cube/cube.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ type (
2020
// App name
2121
AppName string
2222

23+
// LabStack Account ID
24+
AccountID string `json:"account_id"`
25+
2326
// LabStack API key
2427
APIKey string `json:"api_key"`
2528

@@ -44,8 +47,9 @@ var (
4447
)
4548

4649
// Middleware implements Cube middleware.
47-
func Middleware(apiKey string) echo.MiddlewareFunc {
50+
func Middleware(accountID, apiKey string) echo.MiddlewareFunc {
4851
c := DefaultConfig
52+
c.AccountID = accountID
4953
c.APIKey = apiKey
5054
return MiddlewareWithConfig(c)
5155
}
@@ -68,7 +72,8 @@ func MiddlewareWithConfig(config Config) echo.MiddlewareFunc {
6872
}
6973

7074
// Initialize
71-
cube := labstack.NewClient(config.APIKey).Cube()
75+
client := labstack.NewClient(config.AccountID, config.APIKey)
76+
cube := client.Cube()
7277
cube.AppID = config.AppID
7378
cube.AppName = config.AppName
7479
cube.APIKey = config.APIKey

reporter/reporter.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package reporter
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
7+
"github.com/labstack/echo"
8+
"github.com/labstack/echo/middleware"
9+
"github.com/labstack/labstack-go"
10+
)
11+
12+
type (
13+
// Config defines the config for Reporter middleware.
14+
Config struct {
15+
// Skipper defines a function to skip middleware.
16+
Skipper middleware.Skipper
17+
18+
// App ID
19+
AppID string
20+
21+
// App name
22+
AppName string
23+
24+
// LabStack Account ID
25+
AccountID string `json:"account_id"`
26+
27+
// LabStack API key
28+
APIKey string `json:"api_key"`
29+
30+
// Headers to include
31+
Headers []string `json:"headers"`
32+
33+
// TODO: To be implemented
34+
ClientLookup string `json:"client_lookup"`
35+
}
36+
)
37+
38+
var (
39+
// DefaultConfig is the default Reporter middleware config.
40+
DefaultConfig = Config{
41+
Skipper: middleware.DefaultSkipper,
42+
}
43+
)
44+
45+
// Middleware implements Reporter middleware.
46+
func Middleware(accountID string, apiKey string) echo.MiddlewareFunc {
47+
c := DefaultConfig
48+
c.AccountID = accountID
49+
c.APIKey = apiKey
50+
return MiddlewareWithConfig(c)
51+
}
52+
53+
// MiddlewareWithConfig returns a Reporter middleware with config.
54+
// See: `Middleware()`.
55+
func MiddlewareWithConfig(config Config) echo.MiddlewareFunc {
56+
// Defaults
57+
if config.APIKey == "" {
58+
panic("echo: reporter middleware requires an api key")
59+
}
60+
if config.Skipper == nil {
61+
config.Skipper = DefaultConfig.Skipper
62+
}
63+
64+
// Initialize
65+
client := labstack.NewClient(config.AccountID, config.APIKey)
66+
log := client.Log()
67+
log.Fields.Add("app_id", config.AppID).
68+
Add("app_name", config.AppName)
69+
70+
return func(next echo.HandlerFunc) echo.HandlerFunc {
71+
return func(c echo.Context) (err error) {
72+
if config.Skipper(c) {
73+
return next(c)
74+
}
75+
76+
// Capture error and non-fatal report
77+
c.Echo().HTTPErrorHandler = func(err error, c echo.Context) {
78+
c.Echo().DefaultHTTPErrorHandler(err, c)
79+
fields := labstack.Fields{}.
80+
Add("message", err.Error())
81+
appendFields(fields, c, config)
82+
log.Error(fields)
83+
}
84+
85+
// Automatically report fatal error
86+
defer func() {
87+
if r := recover(); r != nil {
88+
var err error
89+
switch r := r.(type) {
90+
case error:
91+
err = r
92+
default:
93+
err = fmt.Errorf("%v", r)
94+
}
95+
stack := make([]byte, 4<<10) // 4 KB
96+
length := runtime.Stack(stack, false)
97+
fields := labstack.Fields{}.
98+
Add("message", err.Error()).
99+
Add("stack_trace", string(stack[:length]))
100+
appendFields(fields, c, config)
101+
log.Fatal(fields)
102+
}
103+
}()
104+
return next(c)
105+
}
106+
}
107+
}
108+
109+
func appendFields(f labstack.Fields, c echo.Context, config Config) {
110+
f.
111+
Add("host", c.Request().Host).
112+
Add("path", c.Request().URL.Path).
113+
Add("method", c.Request().Method).
114+
Add("client_id", c.RealIP()).
115+
Add("remote_ip", c.RealIP()).
116+
Add("status", c.Response().Status)
117+
for _, h := range config.Headers {
118+
f.Add("header_"+h, c.Request().Header.Get(h))
119+
}
120+
}

0 commit comments

Comments
 (0)