health.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package health
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "github.com/go-chi/chi"
  7. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/dao"
  8. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/logging"
  9. )
  10. // global storage definition
  11. var myhealthy bool
  12. var log logging.ServiceLogger
  13. /*
  14. This is the healtchcheck you will have to provide.
  15. */
  16. func check() (bool, string) {
  17. myhealthy = true
  18. message := ""
  19. err := dao.GetStorage().Ping()
  20. if err != nil {
  21. myhealthy = false
  22. message = err.Error()
  23. }
  24. return myhealthy, message
  25. }
  26. //##### template internal functions for processing the healthchecks #####
  27. var healthmessage string
  28. var healthy bool
  29. var lastChecked time.Time
  30. var period int
  31. // CheckConfig configuration for the healthcheck system
  32. type CheckConfig struct {
  33. Period int
  34. }
  35. // InitHealthSystem initialise the complete health system
  36. func InitHealthSystem(config CheckConfig) {
  37. period = config.Period
  38. log.Infof("healthcheck starting with period: %d seconds", period)
  39. healthmessage = "service starting"
  40. healthy = false
  41. doCheck()
  42. go func() {
  43. background := time.NewTicker(time.Second * time.Duration(period))
  44. for range background.C {
  45. doCheck()
  46. }
  47. }()
  48. }
  49. /*
  50. internal function to process the health check
  51. */
  52. func doCheck() {
  53. var msg string
  54. healthy, msg = check()
  55. if !healthy {
  56. healthmessage = msg
  57. } else {
  58. healthmessage = ""
  59. }
  60. lastChecked = time.Now()
  61. }
  62. /*
  63. Routes getting all routes for the health endpoint
  64. */
  65. func Routes() *chi.Mux {
  66. router := chi.NewRouter()
  67. router.Get("/health", GetHealthyEndpoint)
  68. router.Get("/readiness", GetReadinessEndpoint)
  69. return router
  70. }
  71. /*
  72. GetHealthyEndpoint is this service healthy
  73. */
  74. func GetHealthyEndpoint(response http.ResponseWriter, req *http.Request) {
  75. t := time.Now()
  76. if t.Sub(lastChecked) > (time.Second * time.Duration(2*period)) {
  77. healthy = false
  78. healthmessage = "Healthcheck not running"
  79. }
  80. response.Header().Add("Content-Type", "application/json")
  81. if healthy {
  82. response.WriteHeader(http.StatusOK)
  83. message := fmt.Sprintf(`{ "message": "service up and running", "lastCheck": "%s" }`, lastChecked.String())
  84. response.Write([]byte(message))
  85. } else {
  86. response.WriteHeader(http.StatusServiceUnavailable)
  87. message := fmt.Sprintf(`{ "message": "service is unavailable: %s", "lastCheck": "%s" }`, healthmessage, lastChecked.String())
  88. response.Write([]byte(message))
  89. }
  90. }
  91. /*
  92. GetReadinessEndpoint is this service ready for taking requests
  93. */
  94. func GetReadinessEndpoint(response http.ResponseWriter, req *http.Request) {
  95. response.Header().Add("Content-Type", "application/json")
  96. response.WriteHeader(http.StatusOK)
  97. response.Write([]byte(`{ "message": "service started" }`))
  98. }