...
1 package cushion
2
3 import (
4 "fmt"
5 "net"
6 "net/http"
7
8 "github.com/gin-gonic/gin"
9 "github.com/prometheus/client_golang/prometheus/promhttp"
10 )
11
12
13
14 func init() {
15 gin.SetMode(gin.ReleaseMode)
16 gin.DisableConsoleColor()
17 }
18
19
20
21 type ServerConfig struct {
22 port int
23 listener net.Listener
24 }
25
26
27
28 type ServerOption func(*ServerConfig) error
29
30
31 func ServerOptionPort(port int) ServerOption {
32 return func(cfg *ServerConfig) error {
33 if port <= 0 || port > 65535 {
34 return fmt.Errorf("Invalid port number %q", port)
35 }
36 cfg.port = port
37 return nil
38 }
39 }
40
41
42
43 func ServerOptionListener(l net.Listener) ServerOption {
44 return func(cfg *ServerConfig) error {
45 cfg.listener = l
46 return nil
47 }
48 }
49
50
51 type Server struct {
52 Router *gin.Engine
53
54 Config ServerConfig
55 }
56
57
58 var HealthzEndpoints = []string{"/healthz", "/cushion/healthz"}
59
60
61 var MetricsEndpoints = []string{"/metrics", "/cushion/metrics"}
62
63
64 func NewServer(options ...ServerOption) (*Server, error) {
65 s := &Server{
66 Router: gin.New(),
67 }
68
69 for _, option := range options {
70 if err := option(&s.Config); err != nil {
71 return nil, err
72 }
73 }
74
75
76 if s.Config.port == 0 {
77 s.Config.port = 80
78 }
79
80
81 for _, hzep := range HealthzEndpoints {
82 s.Router.GET(hzep, s.HealthHandlerFunction)
83 }
84
85
86 metricsHandlerFunc := gin.WrapH(promhttp.Handler())
87 for _, mep := range MetricsEndpoints {
88 s.Router.GET(mep, metricsHandlerFunc)
89 }
90
91 return s, nil
92 }
93
94
95 func (s *Server) HealthHandlerFunction(c *gin.Context) {
96 c.JSON(http.StatusOK, "UP")
97 }
98
99
100 func (s *Server) Run() error {
101 if s.Config.listener != nil {
102 return s.Router.RunListener(s.Config.listener)
103 }
104 addr := fmt.Sprintf(":%d", s.Config.port)
105 return s.Router.Run(addr)
106 }
107
View as plain text