@@ -4,18 +4,10 @@ import (
44 "context"
55 "crypto/tls"
66 "errors"
7- "fmt"
87 "net"
98 "net/http"
10- "strings"
11- "sync"
129 "time"
1310
14- "github.com/hamba/logger/v2"
15- lctx "github.com/hamba/logger/v2/ctx"
16- "github.com/hamba/pkg/v2/http/healthz"
17- "github.com/hamba/pkg/v2/http/middleware"
18- "github.com/hamba/statter/v2"
1911 "golang.org/x/net/http2"
2012 "golang.org/x/net/http2/h2c"
2113)
@@ -116,184 +108,3 @@ func (s *Server) Shutdown(timeout time.Duration) error {
116108func (s * Server ) Close () error {
117109 return s .srv .Close ()
118110}
119-
120- // HealthServerConfig configures a HealthServer.
121- type HealthServerConfig struct {
122- Addr string
123- Handler http.Handler
124-
125- ReadyzChecks []healthz.HealthChecker
126- LivezChecks []healthz.HealthChecker
127-
128- Stats * statter.Statter
129- Log * logger.Logger
130- }
131-
132- // AddHealthzChecks adds the given checks to the config.
133- func (c * HealthServerConfig ) AddHealthzChecks (checks ... healthz.HealthChecker ) {
134- c .AddReadyzChecks (checks ... )
135- c .AddLivezChecks (checks ... )
136- }
137-
138- // AddReadyzChecks adds the given checks to the config.
139- func (c * HealthServerConfig ) AddReadyzChecks (checks ... healthz.HealthChecker ) {
140- c .ReadyzChecks = append (c .ReadyzChecks , checks ... )
141- }
142-
143- // AddLivezChecks adds the given checks to the config.
144- func (c * HealthServerConfig ) AddLivezChecks (checks ... healthz.HealthChecker ) {
145- c .LivezChecks = append (c .LivezChecks , checks ... )
146- }
147-
148- // HealthServer is an HTTP server with healthz capabilities.
149- type HealthServer struct {
150- srv * Server
151- mux * http.ServeMux
152-
153- shudownCh chan struct {}
154-
155- readyzMu sync.Mutex
156- readyzInstalled bool
157- readyzChecks []healthz.HealthChecker
158-
159- livezMu sync.Mutex
160- livezInstalled bool
161- livezChecks []healthz.HealthChecker
162-
163- stats * statter.Statter
164- log * logger.Logger
165- }
166-
167- // NewHealthServer returns an HTTP server with healthz capabilities.
168- //
169- // Deprecated: Use `server.GenericServer` instead.
170- func NewHealthServer (ctx context.Context , cfg HealthServerConfig , opts ... SrvOptFunc ) * HealthServer {
171- // Setup the mux early so H2C can attach properly.
172- mux := http .NewServeMux ()
173- mux .Handle ("/" , cfg .Handler )
174-
175- srv := NewServer (ctx , cfg .Addr , mux , opts ... )
176-
177- return & HealthServer {
178- srv : srv ,
179- mux : mux ,
180- shudownCh : make (chan struct {}),
181- readyzChecks : cfg .ReadyzChecks ,
182- livezChecks : cfg .LivezChecks ,
183- stats : cfg .Stats ,
184- log : cfg .Log ,
185- }
186- }
187-
188- // AddHealthzChecks adds health checks to both readyz and livez.
189- func (s * HealthServer ) AddHealthzChecks (checks ... healthz.HealthChecker ) error {
190- if err := s .AddReadyzChecks (checks ... ); err != nil {
191- return err
192- }
193- return s .AddLivezChecks (checks ... )
194- }
195-
196- // AddReadyzChecks adds health checks to readyz.
197- func (s * HealthServer ) AddReadyzChecks (checks ... healthz.HealthChecker ) error {
198- s .readyzMu .Lock ()
199- defer s .readyzMu .Unlock ()
200- if s .readyzInstalled {
201- return errors .New ("could not add checks as readyz has already been installed" )
202- }
203- s .readyzChecks = append (s .readyzChecks , checks ... )
204- return nil
205- }
206-
207- // AddLivezChecks adds health checks to livez.
208- func (s * HealthServer ) AddLivezChecks (checks ... healthz.HealthChecker ) error {
209- s .livezMu .Lock ()
210- defer s .livezMu .Unlock ()
211- if s .livezInstalled {
212- return errors .New ("could not add checks as livez has already been installed" )
213- }
214- s .livezChecks = append (s .livezChecks , checks ... )
215- return nil
216- }
217-
218- // Serve installs the health checks and starts the server in a non-blocking way.
219- func (s * HealthServer ) Serve (errFn func (error )) {
220- s .installChecks ()
221-
222- s .srv .Serve (errFn )
223- }
224-
225- func (s * HealthServer ) installChecks () {
226- s .installLivezChecks (s .mux )
227-
228- // When shutdown is started, the readyz check should start failing.
229- if err := s .AddReadyzChecks (shutdownCheck {ch : s .shudownCh }); err != nil {
230- s .log .Error ("Could not install readyz shutdown check" , lctx .Err (err ))
231- }
232- s .installReadyzChecks (s .mux )
233- }
234-
235- func (s * HealthServer ) installReadyzChecks (mux * http.ServeMux ) {
236- s .readyzMu .Lock ()
237- defer s .readyzMu .Unlock ()
238- s .readyzInstalled = true
239- s .installCheckers (mux , "/readyz" , s .readyzChecks )
240- }
241-
242- func (s * HealthServer ) installLivezChecks (mux * http.ServeMux ) {
243- s .livezMu .Lock ()
244- defer s .livezMu .Unlock ()
245- s .livezInstalled = true
246- s .installCheckers (mux , "/livez" , s .livezChecks )
247- }
248-
249- func (s * HealthServer ) installCheckers (mux * http.ServeMux , path string , checks []healthz.HealthChecker ) {
250- if len (checks ) == 0 {
251- checks = []healthz.HealthChecker {healthz .PingHealth }
252- }
253-
254- s .log .Info ("Installing health checkers" ,
255- lctx .Str ("path" , path ),
256- lctx .Str ("checks" , strings .Join (checkNames (checks ), "," )),
257- )
258-
259- name := strings .TrimPrefix (path , "/" )
260- h := healthz .Handler (name , func (output string ) {
261- s .log .Info (fmt .Sprintf ("%s check failed\n %s" , name , output ))
262- }, checks ... )
263- mux .Handle (path , middleware .WithStats (name , s .stats , h ))
264- }
265-
266- // Shutdown attempts to close all server connections.
267- func (s * HealthServer ) Shutdown (timeout time.Duration ) error {
268- close (s .shudownCh )
269-
270- return s .srv .Shutdown (timeout )
271- }
272-
273- // Close closes the server.
274- func (s * HealthServer ) Close () error {
275- return s .srv .Close ()
276- }
277-
278- func checkNames (checks []healthz.HealthChecker ) []string {
279- names := make ([]string , len (checks ))
280- for i , check := range checks {
281- names [i ] = check .Name ()
282- }
283- return names
284- }
285-
286- type shutdownCheck struct {
287- ch <- chan struct {}
288- }
289-
290- func (s shutdownCheck ) Name () string { return "shutdown" }
291-
292- func (s shutdownCheck ) Check (* http.Request ) error {
293- select {
294- case <- s .ch :
295- return errors .New ("server is shutting down" )
296- default :
297- return nil
298- }
299- }
0 commit comments