Skip to content

Commit 477a0fb

Browse files
author
Andrei Skomorkhov
authored
Merge pull request #26 from qa-dev/optional-statsd
Optional statsd.
2 parents f3b3799 + 9b98220 commit 477a0fb

File tree

6 files changed

+140
-46
lines changed

6 files changed

+140
-46
lines changed

config/config.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import (
99

1010
// Config - settings of application.
1111
type Config struct {
12-
Logger Logger `json:"logger"`
13-
DB DB `json:"db"`
14-
Grid Grid `json:"grid"`
15-
Statsd Statsd `json:"statsd"`
12+
Logger Logger `json:"logger"`
13+
DB DB `json:"db"`
14+
Grid Grid `json:"grid"`
15+
Statsd *Statsd `json:"statsd,omitempty"`
1616
}
1717

1818
// Grid general settings

logger/logger.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import (
88
)
99

1010
// Init - initialisation of logger.
11-
func Init(logger config.Logger) error {
12-
level, err := logrus.ParseLevel(logger.Level)
11+
func Init(cfgLogger config.Logger) error {
12+
level, err := logrus.ParseLevel(cfgLogger.Level)
1313
if err != nil {
14-
return fmt.Errorf("Parse log level, %v", err)
14+
return fmt.Errorf("parse log level, %v", err)
1515
}
1616
logrus.Infof("Set log level to: %v", level)
1717
logrus.SetLevel(level)

main.go

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,7 @@ func main() {
3232
log.Fatalf("Problem in init logger, %s", err)
3333
}
3434

35-
statsdClient, err := metrics.NewStatsd(
36-
cfg.Statsd.Host,
37-
cfg.Statsd.Port,
38-
cfg.Statsd.Protocol,
39-
cfg.Statsd.Prefix,
40-
cfg.Statsd.Enable)
41-
42-
if nil != err {
43-
log.Errorf("Statsd create socked error: %s", err)
44-
}
35+
middlewareWrap := middleware.NewWrap(log.StandardLogger())
4536

4637
busyNodeDuration, err := time.ParseDuration(cfg.Grid.BusyNodeDuration)
4738
if err != nil {
@@ -84,8 +75,7 @@ func main() {
8475
poolInstance.SetBusyNodeDuration(busyNodeDuration)
8576
poolInstance.SetReservedNodeDuration(reservedNodeDuration)
8677

87-
poolMetricsSender := poolMetrics.NewSender(statsdClient, poolInstance, time.Second*1) // todo: move to config
88-
go poolMetricsSender.SendAll()
78+
8979

9080
go func() {
9181
for {
@@ -103,13 +93,29 @@ func main() {
10393
}
10494
}()
10595

106-
m := middleware.NewLogMiddleware(statsdClient)
107-
http.Handle("/wd/hub/session", m.Log(&handlers.CreateSession{Pool: poolInstance, ClientFactory: clientFactory})) //selenium
108-
http.Handle("/session", m.Log(&handlers.CreateSession{Pool: poolInstance, ClientFactory: clientFactory})) //wda
109-
http.Handle("/grid/register", m.Log(&handlers.RegisterNode{Pool: poolInstance}))
96+
97+
98+
if cfg.Statsd != nil {
99+
statsdClient, err := metrics.NewStatsd(
100+
cfg.Statsd.Host,
101+
cfg.Statsd.Port,
102+
cfg.Statsd.Protocol,
103+
cfg.Statsd.Prefix,
104+
cfg.Statsd.Enable)
105+
poolMetricsSender := poolMetrics.NewSender(statsdClient, poolInstance, time.Second*1) // todo: move to config
106+
go poolMetricsSender.SendAll()
107+
if err != nil {
108+
log.Errorf("Statsd create socked error: %s", err)
109+
}
110+
middlewareWrap.Add(middleware.NewStatsd(log.StandardLogger(), statsdClient, true).RegisterMetrics)
111+
}
112+
113+
http.Handle("/wd/hub/session", middlewareWrap.Do(&handlers.CreateSession{Pool: poolInstance, ClientFactory: clientFactory})) //selenium
114+
http.Handle("/session", middlewareWrap.Do(&handlers.CreateSession{Pool: poolInstance, ClientFactory: clientFactory})) //wda
115+
http.Handle("/grid/register", middlewareWrap.Do(&handlers.RegisterNode{Pool: poolInstance}))
110116
http.Handle("/grid/api/proxy", &handlers.APIProxy{Pool: poolInstance})
111117
http.HandleFunc("/_info", heartbeat)
112-
http.Handle("/", m.Log(&handlers.UseSession{Pool: poolInstance, Cache: cache}))
118+
http.Handle("/", middlewareWrap.Do(&handlers.UseSession{Pool: poolInstance, Cache: cache}))
113119

114120
server := &http.Server{Addr: fmt.Sprintf(":%v", cfg.Grid.Port)}
115121
serverError := make(chan error)

middleware/log.go renamed to middleware/statsd.go

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,38 @@ package middleware
22

33
import (
44
"net/http"
5-
"runtime/debug"
65
"strings"
76

87
"fmt"
9-
log "github.com/Sirupsen/logrus"
8+
"github.com/Sirupsen/logrus"
109
"gopkg.in/alexcesaro/statsd.v2"
1110
"regexp"
1211
)
1312

14-
// LogMiddleware - wraps adds logging to the query handlers.
15-
type LogMiddleware struct {
16-
statsd *statsd.Client
13+
// Statsd is statsd metrics middleware.
14+
type Statsd struct {
15+
logger *logrus.Logger
16+
client *statsd.Client
17+
withLog bool
1718
}
1819

19-
// NewLogMiddleware - constructor of LogMiddleware.
20-
func NewLogMiddleware(statsd *statsd.Client) *LogMiddleware {
21-
return &LogMiddleware{
22-
statsd: statsd,
20+
// NewStatsd construct Statsd.
21+
func NewStatsd(logger *logrus.Logger, client *statsd.Client, withLog bool) *Statsd {
22+
return &Statsd{
23+
logger: logger,
24+
client: client,
25+
withLog: withLog,
2326
}
2427
}
2528

26-
// Log - wraps http.Handler for runtime logging.
27-
func (m *LogMiddleware) Log(handler http.Handler) http.Handler {
29+
// RegisterMetrics send metrics to statsd
30+
func (s *Statsd) RegisterMetrics(handler http.Handler) http.Handler {
2831
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
2932

30-
defer func() {
31-
if err := recover(); err != nil {
32-
log.Fatalf("Panic: %+v\n%s", err, debug.Stack())
33-
}
34-
}()
35-
3633
path := req.URL.Path
3734
handlerName := prepareHandlerName(path)
3835

39-
requestTimer := m.statsd.NewTiming()
36+
requestTimer := s.client.NewTiming()
4037

4138
lrw := &LoggedResponseWriter{responseWriter: resp}
4239

@@ -49,10 +46,11 @@ func (m *LogMiddleware) Log(handler http.Handler) http.Handler {
4946
handlerName,
5047
))
5148

52-
//Example: 200 POST /rec/ (127.0.0.1) 1.460s
53-
log.Infof("%v %v %v (%v) %.3fs",
54-
lrw.Status(), req.Method, path, req.RemoteAddr, requestTimer.Duration().Seconds())
55-
49+
if s.withLog {
50+
//Example: 200 POST /rec/ (127.0.0.1) 1.460s
51+
s.logger.Infof("%v %v %v (%v) %.3fs",
52+
lrw.Status(), req.Method, path, req.RemoteAddr, requestTimer.Duration().Seconds())
53+
}
5654
})
5755
}
5856

middleware/wrap.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package middleware
2+
3+
import (
4+
"net/http"
5+
"runtime/debug"
6+
"github.com/Sirupsen/logrus"
7+
)
8+
9+
type Wrap struct {
10+
logger *logrus.Entry
11+
list []func(http.Handler) http.Handler
12+
}
13+
14+
func NewWrap(logger *logrus.Logger) *Wrap {
15+
return &Wrap{
16+
logger: logger.WithField("component", "middlewareWrap"),
17+
list: make([]func(http.Handler) http.Handler, 0),
18+
}
19+
}
20+
21+
func (s *Wrap) Add(middleware func(http.Handler) http.Handler) {
22+
s.list = append(s.list, middleware)
23+
}
24+
25+
func (s *Wrap) Do(handler http.Handler) http.Handler {
26+
for i := 0; i < len(s.list); i++ {
27+
handler = s.list[i](handler)
28+
}
29+
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
30+
defer func() {
31+
if err := recover(); err != nil {
32+
s.logger.Errorf("Panic: %+v\n%s", err, debug.Stack())
33+
}
34+
}()
35+
36+
handler.ServeHTTP(resp, req)
37+
})
38+
}

middleware/wrap_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package middleware
2+
3+
import (
4+
"testing"
5+
"github.com/Sirupsen/logrus"
6+
"net/http"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestWrap_Add(t *testing.T) {
11+
a := assert.New(t)
12+
wrap := NewWrap(logrus.StandardLogger())
13+
eLen := 5
14+
for i := 0; i < eLen; i++ {
15+
wrap.Add(func(handler http.Handler) http.Handler { return handler })
16+
}
17+
a.Len(wrap.list, eLen)
18+
}
19+
20+
func TestWrap_Do(t *testing.T) {
21+
a := assert.New(t)
22+
wrap := NewWrap(logrus.StandardLogger())
23+
checkArray := make([]int, 0)
24+
25+
wrap.Add(
26+
func(handler http.Handler) http.Handler {
27+
checkArray = append(checkArray, 1)
28+
return handler
29+
},
30+
)
31+
32+
wrap.Add(
33+
func(handler http.Handler) http.Handler {
34+
checkArray = append(checkArray, 2)
35+
return handler
36+
},
37+
)
38+
39+
wrap.Add(
40+
func(handler http.Handler) http.Handler {
41+
checkArray = append(checkArray, 3)
42+
return handler
43+
},
44+
)
45+
46+
wrap.Do(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {}))
47+
48+
a.Len(checkArray, 3)
49+
a.Equal(1, checkArray[0])
50+
a.Equal(2, checkArray[1])
51+
a.Equal(3, checkArray[2])
52+
}

0 commit comments

Comments
 (0)