Beispiel #1
0
// FileChecker checks the existence of a file and returns an error
// if the file exists.
func FileChecker(f string) health.Checker {
	return health.CheckFunc(func() error {
		if _, err := os.Stat(f); err == nil {
			return errors.New("file exists")
		}
		return nil
	})
}
Beispiel #2
0
// TCPChecker attempts to open a TCP connection.
func TCPChecker(addr string, timeout time.Duration) health.Checker {
	return health.CheckFunc(func() error {
		conn, err := net.DialTimeout("tcp", addr, timeout)
		if err != nil {
			return errors.New("connection to " + addr + " failed")
		}
		conn.Close()
		return nil
	})
}
Beispiel #3
0
// HTTPChecker does a HEAD request and verifies if the HTTP status
// code return is a 200, taking the application out of rotation if
// otherwise
func HTTPChecker(r string) health.Checker {
	return health.CheckFunc(func() error {
		response, err := http.Head(r)
		if err != nil {
			return errors.New("error while checking: " + r)
		}
		if response.StatusCode != http.StatusOK {
			return errors.New("downstream service returned unexpected status: " + string(response.StatusCode))
		}
		return nil
	})
}
Beispiel #4
0
// Start checks the modules for the following interfaces and registers and/or starts:
//   Startable:
//   health.Checker:
//   Endpoint: Register the handler function of the Endpoint in the http service at prefix
func (s *Service) Start() error {
	el := protocol.NewErrorList("service: errors occured while starting: ")

	if s.healthEndpoint != "" {
		loggerService.WithField("healthEndpoint", s.healthEndpoint).Info("Health endpoint")
		s.webserver.Handle(s.healthEndpoint, http.HandlerFunc(health.StatusHandler))
	} else {
		loggerService.Info("Health endpoint disabled")
	}

	if s.metricsEndpoint != "" {
		loggerService.WithField("metricsEndpoint", s.metricsEndpoint).Info("Metrics endpoint")
		s.webserver.Handle(s.metricsEndpoint, http.HandlerFunc(metrics.HttpHandler))
	} else {
		loggerService.Info("Metrics endpoint disabled")
	}

	for _, module := range s.modules {
		name := reflect.TypeOf(module).String()
		if startable, ok := module.(Startable); ok {
			loggerService.WithFields(log.Fields{
				"name": name,
			}).Info("Starting module")

			if err := startable.Start(); err != nil {
				loggerService.WithFields(log.Fields{
					"name": name,
					"err":  err,
				}).Error("Error while starting module")
				el.Add(err)
			}
		}
		if checker, ok := module.(health.Checker); ok && s.healthEndpoint != "" {
			loggerService.WithField("name", name).Info("Registering module as Health-Checker")
			health.RegisterPeriodicThresholdFunc(name, s.healthFrequency, s.healthThreshold, health.CheckFunc(checker.Check))
		}
		if endpoint, ok := module.(Endpoint); ok {
			prefix := endpoint.GetPrefix()
			loggerService.WithFields(log.Fields{
				"name":   name,
				"prefix": prefix,
			}).Info("Registering module as Endpoint")
			s.webserver.Handle(prefix, endpoint)
		}
	}
	return el.ErrorOrNil()
}
Beispiel #5
0
// Start checks the modules for the following interfaces and registers and/or starts:
//   Startable:
//   health.Checker:
//   Endpoint: Register the handler function of the Endpoint in the http service at prefix
func (s *Service) Start() error {
	var multierr *multierror.Error
	if s.healthEndpoint != "" {
		logger.WithField("healthEndpoint", s.healthEndpoint).Info("Health endpoint")
		s.webserver.Handle(s.healthEndpoint, http.HandlerFunc(health.StatusHandler))
	} else {
		logger.Info("Health endpoint disabled")
	}
	if s.metricsEndpoint != "" {
		logger.WithField("metricsEndpoint", s.metricsEndpoint).Info("Metrics endpoint")
		s.webserver.Handle(s.metricsEndpoint, http.HandlerFunc(metrics.HttpHandler))
	} else {
		logger.Info("Metrics endpoint disabled")
	}
	for order, iface := range s.ModulesSortedByStartOrder() {
		name := reflect.TypeOf(iface).String()
		if s, ok := iface.(Startable); ok {
			logger.WithFields(log.Fields{"name": name, "order": order}).Info("Starting module")
			if err := s.Start(); err != nil {
				logger.WithError(err).WithField("name", name).Error("Error while starting module")
				multierr = multierror.Append(multierr, err)
			}
		} else {
			logger.WithFields(log.Fields{"name": name, "order": order}).Debug("Module is not startable")
		}
		if c, ok := iface.(health.Checker); ok && s.healthEndpoint != "" {
			logger.WithField("name", name).Info("Registering module as Health-Checker")
			health.RegisterPeriodicThresholdFunc(name, s.healthFrequency, s.healthThreshold, health.CheckFunc(c.Check))
		}
		if e, ok := iface.(Endpoint); ok {
			prefix := e.GetPrefix()
			logger.WithFields(log.Fields{"name": name, "prefix": prefix}).Info("Registering module as Endpoint")
			s.webserver.Handle(prefix, e)
		}
	}
	return multierr.ErrorOrNil()
}
Beispiel #6
0
// HTTPChecker does a HEAD request and verifies that the HTTP status code
// returned matches statusCode.
func HTTPChecker(r string, statusCode int, timeout time.Duration, headers http.Header) health.Checker {
	return health.CheckFunc(func() error {
		client := http.Client{
			Timeout: timeout,
		}
		req, err := http.NewRequest("HEAD", r, nil)
		if err != nil {
			return errors.New("error creating request: " + r)
		}
		for headerName, headerValues := range headers {
			for _, headerValue := range headerValues {
				req.Header.Add(headerName, headerValue)
			}
		}
		response, err := client.Do(req)
		if err != nil {
			return errors.New("error while checking: " + r)
		}
		if response.StatusCode != statusCode {
			return errors.New("downstream service returned unexpected status: " + strconv.Itoa(response.StatusCode))
		}
		return nil
	})
}