...

Source file src/github.com/docker/distribution/health/doc.go

Documentation: github.com/docker/distribution/health

     1  // Package health provides a generic health checking framework.
     2  // The health package works expvar style. By importing the package the debug
     3  // server is getting a "/debug/health" endpoint that returns the current
     4  // status of the application.
     5  // If there are no errors, "/debug/health" will return an HTTP 200 status,
     6  // together with an empty JSON reply "{}". If there are any checks
     7  // with errors, the JSON reply will include all the failed checks, and the
     8  // response will be have an HTTP 503 status.
     9  //
    10  // A Check can either be run synchronously, or asynchronously. We recommend
    11  // that most checks are registered as an asynchronous check, so a call to the
    12  // "/debug/health" endpoint always returns immediately. This pattern is
    13  // particularly useful for checks that verify upstream connectivity or
    14  // database status, since they might take a long time to return/timeout.
    15  //
    16  // # Installing
    17  //
    18  // To install health, just import it in your application:
    19  //
    20  //	import "github.com/docker/distribution/health"
    21  //
    22  // You can also (optionally) import "health/api" that will add two convenience
    23  // endpoints: "/debug/health/down" and "/debug/health/up". These endpoints add
    24  // "manual" checks that allow the service to quickly be brought in/out of
    25  // rotation.
    26  //
    27  //	import _ "github.com/docker/distribution/health/api"
    28  //
    29  //	# curl localhost:5001/debug/health
    30  //	{}
    31  //	# curl -X POST localhost:5001/debug/health/down
    32  //	# curl localhost:5001/debug/health
    33  //	{"manual_http_status":"Manual Check"}
    34  //
    35  // After importing these packages to your main application, you can start
    36  // registering checks.
    37  //
    38  // # Registering Checks
    39  //
    40  // The recommended way of registering checks is using a periodic Check.
    41  // PeriodicChecks run on a certain schedule and asynchronously update the
    42  // status of the check. This allows CheckStatus to return without blocking
    43  // on an expensive check.
    44  //
    45  // A trivial example of a check that runs every 5 seconds and shuts down our
    46  // server if the current minute is even, could be added as follows:
    47  //
    48  //	func currentMinuteEvenCheck() error {
    49  //	  m := time.Now().Minute()
    50  //	  if m%2 == 0 {
    51  //	    return errors.New("Current minute is even!")
    52  //	  }
    53  //	  return nil
    54  //	}
    55  //
    56  //	health.RegisterPeriodicFunc("minute_even", currentMinuteEvenCheck, time.Second*5)
    57  //
    58  // Alternatively, you can also make use of "RegisterPeriodicThresholdFunc" to
    59  // implement the exact same check, but add a threshold of failures after which
    60  // the check will be unhealthy. This is particularly useful for flaky Checks,
    61  // ensuring some stability of the service when handling them.
    62  //
    63  //	health.RegisterPeriodicThresholdFunc("minute_even", currentMinuteEvenCheck, time.Second*5, 4)
    64  //
    65  // The lowest-level way to interact with the health package is calling
    66  // "Register" directly. Register allows you to pass in an arbitrary string and
    67  // something that implements "Checker" and runs your check. If your method
    68  // returns an error with nil, it is considered a healthy check, otherwise it
    69  // will make the health check endpoint "/debug/health" start returning a 503
    70  // and list the specific check that failed.
    71  //
    72  // Assuming you wish to register a method called "currentMinuteEvenCheck()
    73  // error" you could do that by doing:
    74  //
    75  //	health.Register("even_minute", health.CheckFunc(currentMinuteEvenCheck))
    76  //
    77  // CheckFunc is a convenience type that implements Checker.
    78  //
    79  // Another way of registering a check could be by using an anonymous function
    80  // and the convenience method RegisterFunc. An example that makes the status
    81  // endpoint always return an error:
    82  //
    83  //	health.RegisterFunc("my_check", func() error {
    84  //	 return Errors.new("This is an error!")
    85  //	}))
    86  //
    87  // # Examples
    88  //
    89  // You could also use the health checker mechanism to ensure your application
    90  // only comes up if certain conditions are met, or to allow the developer to
    91  // take the service out of rotation immediately. An example that checks
    92  // database connectivity and immediately takes the server out of rotation on
    93  // err:
    94  //
    95  //	updater = health.NewStatusUpdater()
    96  //	 health.RegisterFunc("database_check", func() error {
    97  //	  return updater.Check()
    98  //	}))
    99  //
   100  //	conn, err := Connect(...) // database call here
   101  //	if err != nil {
   102  //	  updater.Update(errors.New("Error connecting to the database: " + err.Error()))
   103  //	}
   104  //
   105  // You can also use the predefined Checkers that come included with the health
   106  // package. First, import the checks:
   107  //
   108  //	import "github.com/docker/distribution/health/checks
   109  //
   110  // After that you can make use of any of the provided checks. An example of
   111  // using a `FileChecker` to take the application out of rotation if a certain
   112  // file exists can be done as follows:
   113  //
   114  //	health.Register("fileChecker", health.PeriodicChecker(checks.FileChecker("/tmp/disable"), time.Second*5))
   115  //
   116  // After registering the check, it is trivial to take an application out of
   117  // rotation from the console:
   118  //
   119  //	# curl localhost:5001/debug/health
   120  //	{}
   121  //	# touch /tmp/disable
   122  //	# curl localhost:5001/debug/health
   123  //	{"fileChecker":"file exists"}
   124  //
   125  // FileChecker only accepts absolute or relative file path. It does not work
   126  // properly with tilde(~). You should make sure that the application has
   127  // proper permission(read and execute permission for directory along with
   128  // the specified file path). Otherwise, the FileChecker will report error
   129  // and file health check is not ok.
   130  //
   131  // You could also test the connectivity to a downstream service by using a
   132  // "HTTPChecker", but ensure that you only mark the test unhealthy if there
   133  // are a minimum of two failures in a row:
   134  //
   135  //	health.Register("httpChecker", health.PeriodicThresholdChecker(checks.HTTPChecker("https://www.google.pt"), time.Second*5, 2))
   136  package health
   137  

View as plain text