-
Notifications
You must be signed in to change notification settings - Fork 6
/
router.go
117 lines (97 loc) · 3.6 KB
/
router.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package server
// Code auto-generated. Do not edit.
import (
"log"
"net/http"
_ "net/http/pprof"
"os"
"path"
"time"
"github.com/Clever/go-process-metrics/metrics"
"github.com/gorilla/mux"
"github.com/kardianos/osext"
lightstep "github.com/lightstep/lightstep-tracer-go"
opentracing "github.com/opentracing/opentracing-go"
"gopkg.in/Clever/kayvee-go.v6/logger"
kvMiddleware "gopkg.in/Clever/kayvee-go.v6/middleware"
"gopkg.in/tylerb/graceful.v1"
)
type contextKey struct{}
// Server defines a HTTP server that implements the Controller interface.
type Server struct {
// Handler should generally not be changed. It exposed to make testing easier.
Handler http.Handler
addr string
l logger.KayveeLogger
}
// Serve starts the server. It will return if an error occurs.
func (s *Server) Serve() error {
go func() {
metrics.Log("swagger-test", 1*time.Minute)
}()
go func() {
// This should never return. Listen on the pprof port
log.Printf("PProf server crashed: %s", http.ListenAndServe(":6060", nil))
}()
dir, err := osext.ExecutableFolder()
if err != nil {
log.Fatal(err)
}
if err := logger.SetGlobalRouting(path.Join(dir, "kvconfig.yml")); err != nil {
s.l.Info("please provide a kvconfig.yml file to enable app log routing")
}
if lightstepToken := os.Getenv("LIGHTSTEP_ACCESS_TOKEN"); lightstepToken != "" {
tags := make(map[string]interface{})
tags[lightstep.ComponentNameKey] = "swagger-test"
lightstepTracer := lightstep.NewTracer(lightstep.Options{
AccessToken: lightstepToken,
Tags: tags,
UseGRPC: true,
})
defer lightstep.FlushLightStepTracer(lightstepTracer)
opentracing.InitGlobalTracer(lightstepTracer)
} else {
s.l.Error("please set LIGHTSTEP_ACCESS_TOKEN to enable tracing")
}
s.l.Counter("server-started")
// Give the sever 30 seconds to shut down
return graceful.RunWithErr(s.addr, 30*time.Second, s.Handler)
}
type handler struct {
Controller
}
func withMiddleware(serviceName string, router http.Handler, m []func(http.Handler) http.Handler) http.Handler {
handler := router
// Wrap the middleware in the opposite order specified so that when called then run
// in the order specified
for i := len(m) - 1; i >= 0; i-- {
handler = m[i](handler)
}
handler = TracingMiddleware(handler)
handler = PanicMiddleware(handler)
// Logging middleware comes last, i.e. will be run first.
// This makes it so that other middleware has access to the logger
// that kvMiddleware injects into the request context.
handler = kvMiddleware.New(handler, serviceName)
return handler
}
// New returns a Server that implements the Controller interface. It will start when "Serve" is called.
func New(c Controller, addr string) *Server {
return NewWithMiddleware(c, addr, []func(http.Handler) http.Handler{})
}
// NewWithMiddleware returns a Server that implemenets the Controller interface. It runs the
// middleware after the built-in middleware (e.g. logging), but before the controller methods.
// The middleware is executed in the order specified. The server will start when "Serve" is called.
func NewWithMiddleware(c Controller, addr string, m []func(http.Handler) http.Handler) *Server {
router := mux.NewRouter()
h := handler{Controller: c}
l := logger.New("swagger-test")
router.Methods("GET").Path("/v1/books/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logger.FromContext(r.Context()).AddContext("op", "getBook")
h.GetBookHandler(r.Context(), w, r)
ctx := WithTracingOpName(r.Context(), "getBook")
r = r.WithContext(ctx)
})
handler := withMiddleware("swagger-test", router, m)
return &Server{Handler: handler, addr: addr, l: l}
}