From b5552bc4e57f73a80e990ee4182fb48fa4851ad3 Mon Sep 17 00:00:00 2001
From: DJ Mountney <david@twkie.net>
Date: Wed, 18 May 2016 08:48:48 -0700
Subject: [PATCH] Add health check feature documentation

---
 doc/README.md                             |   1 +
 doc/monitoring/health_check.md            |  57 ++++++++++++++++++++++
 doc/monitoring/img/health_check_token.png | Bin 0 -> 10884 bytes
 3 files changed, 58 insertions(+)
 create mode 100644 doc/monitoring/health_check.md
 create mode 100644 doc/monitoring/img/health_check_token.png

diff --git a/doc/README.md b/doc/README.md
index e358da1c424..8aed060d247 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -41,6 +41,7 @@
 - [Git LFS configuration](workflow/lfs/lfs_administration.md)
 - [Housekeeping](administration/housekeeping.md) Keep your Git repository tidy and fast.
 - [GitLab Performance Monitoring](monitoring/performance/introduction.md) Configure GitLab and InfluxDB for measuring performance metrics
+- [Monitoring uptime](monitoring/health_check.md) Check the server status using the health check endpoint
 - [Sidekiq Troubleshooting](administration/troubleshooting/sidekiq.md) Debug when Sidekiq appears hung and is not processing jobs
 - [High Availability](administration/high_availability/README.md) Configure multiple servers for scaling or high availability
 
diff --git a/doc/monitoring/health_check.md b/doc/monitoring/health_check.md
new file mode 100644
index 00000000000..bbfb63dd844
--- /dev/null
+++ b/doc/monitoring/health_check.md
@@ -0,0 +1,57 @@
+# Health Check
+_**Note:** This feature was [introduced][ce-3888] in GitLab 8.8_
+
+GitLab provides a health check endpoint for uptime monitoring on the `health_check` web
+endpoint. The health check reports on the overall system status based on the status of
+the database connection, the state of the database migrations, and the ability to write
+and access the cache. This endpoint can be provided to uptime monitoring services like
+[Pingdom][pindom], [Nagios][nagios-health], and [NewRelic][newrelic-health].
+
+## Access Token
+
+A access token needs to be provided while accessing the health check endpoint. The current
+accepted token can be found on the `admin/heath_check` page of your GitLab instance.
+
+![access token](img/health_check_token.png)
+
+The access token can be passed as a url parameter:
+
+`https://gitlab.example.com/health_check.json?token=ACCESS_TOKEN`
+
+or as a http header:
+
+```bash
+curl -H "TOKEN: ACCESS_TOKEN" https://gitlab.example.com/health_check.json
+```
+
+## Using the Endpoint
+
+Once you have the access token, health information can be retrieved as plain text, JSON,
+or XML using the `health_check` endpoint:
+
+- `https://gitlab.example.com/health_check?token=ACCESS_TOKEN`
+- `https://gitlab.example.com/health_check.json?token=ACCESS_TOKEN`
+- `https://gitlab.example.com/health_check.xml?token=ACCESS_TOKEN`
+
+You can also ask for the status of specific services:
+
+- `https://gitlab.example.com/health_check/cache.json?token=ACCESS_TOKEN`
+- `https://gitlab.example.com/health_check/database.json?token=ACCESS_TOKEN`
+- `https://gitlab.example.com/health_check/migrations.json?token=ACCESS_TOKEN`
+
+Example output:
+```bash
+curl -H "TOKEN: ACCESS_TOKEN" https://gitlab.example.com/health_check.json
+{"healthy":true,"message":"success"}
+```
+
+## Status
+
+On failure the endpoint will return a `500` http status code. On success the endpoint
+will return a valid successful http status code, and a `success` message. Ideally your
+uptime monitoring should look for the success message.
+
+[ce-3888]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/3888
+[pingdom]: https://www.pingdom.com
+[nagios-health]: https://nagios-plugins.org/doc/man/check_http.html
+[newrelic-health]: https://docs.newrelic.com/docs/alerts/alert-policies/downtime-alerts/availability-monitoring
diff --git a/doc/monitoring/img/health_check_token.png b/doc/monitoring/img/health_check_token.png
new file mode 100644
index 0000000000000000000000000000000000000000..2daf8606b009aedda120af03baa13c36a195f07d
GIT binary patch
literal 10884
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
V7{3}jmV(w}db;|#taD0e0syE<(}4g0

literal 0
HcmV?d00001

-- 
GitLab