github.com/m3db/m3@v1.5.0/src/ctl/service/health/service.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE 20 21 package health 22 23 import ( 24 "encoding/json" 25 "fmt" 26 "net/http" 27 "os" 28 "time" 29 30 mservice "github.com/m3db/m3/src/ctl/service" 31 "github.com/m3db/m3/src/x/instrument" 32 33 "github.com/gorilla/mux" 34 ) 35 36 const ( 37 ok healthStatus = "OK" 38 healthURL = "/health" 39 unknownName = "unknown" 40 ) 41 42 type healthStatus string 43 44 type healthCheckResult struct { 45 Host string `json:"host"` 46 Timestamp time.Time `json:"timestamp"` 47 ResponseTime time.Duration `json:"response_time"` 48 Status healthStatus `json:"status"` 49 } 50 51 type service struct { 52 iOpts instrument.Options 53 } 54 55 // NewService creates a new rules controller. 56 func NewService(iOpts instrument.Options) mservice.Service { 57 return &service{iOpts: iOpts} 58 } 59 60 func (s *service) URLPrefix() string { 61 return healthURL 62 } 63 64 func (s *service) RegisterHandlers(router *mux.Router) error { 65 log := s.iOpts.Logger() 66 router.HandleFunc("", healthCheck) 67 log.Info("registered health endpoints") 68 return nil 69 } 70 71 func (s *service) Close() {} 72 73 func status() healthStatus { 74 return ok 75 } 76 77 func hostName() string { 78 host, err := os.Hostname() 79 if err != nil { 80 host = unknownName 81 } 82 return host 83 } 84 85 func healthCheck(w http.ResponseWriter, r *http.Request) { 86 start := time.Now() 87 host := hostName() 88 status := status() 89 h := healthCheckResult{Host: host, Timestamp: start, Status: status} 90 h.ResponseTime = time.Since(start) 91 92 body, err := json.Marshal(h) 93 if err != nil { 94 w.WriteHeader(http.StatusInternalServerError) 95 fmt.Fprintf(w, "Could not generate health check result") 96 return 97 } 98 99 w.Header().Set("Content-Type", "application/json") 100 w.Write(body) 101 }