Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply a 4K limit to the output size for HTTP checks #1952

Merged
merged 2 commits into from
Apr 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions command/agent/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package agent

import (
"fmt"
"io/ioutil"
"io"
"log"
"net"
"net/http"
Expand Down Expand Up @@ -423,13 +423,14 @@ func (c *CheckHTTP) check() {
}
defer resp.Body.Close()

// Format the response body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
// Read the response into a circular buffer to limit the size
output, _ := circbuf.NewBuffer(CheckBufSize)
if _, err := io.Copy(output, resp.Body); err != nil {
c.Logger.Printf("[WARN] agent: check '%v': Get error while reading body: %s", c.CheckID, err)
body = []byte{}
}
result := fmt.Sprintf("HTTP GET %s: %s Output: %s", c.HTTP, resp.Status, body)

// Format the response body
result := fmt.Sprintf("HTTP GET %s: %s Output: %s", c.HTTP, resp.Status, output.String())

if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
// PASSING (2xx)
Expand Down
9 changes: 9 additions & 0 deletions command/agent/check_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package agent

import (
"bytes"
"errors"
"fmt"
"log"
Expand Down Expand Up @@ -186,7 +187,10 @@ func TestCheckTTL(t *testing.T) {
func mockHTTPServer(responseCode int) *httptest.Server {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Body larger than 4k limit
body := bytes.Repeat([]byte{'a'}, 2*CheckBufSize)
w.WriteHeader(responseCode)
w.Write(body)
return
})

Expand Down Expand Up @@ -219,6 +223,11 @@ func expectHTTPStatus(t *testing.T, url string, status string) {
if mock.state["foo"] != status {
t.Fatalf("should be %v %v", status, mock.state)
}

// Allow slightly more data than CheckBufSize, for the header
if n := len(mock.output["foo"]); n > (CheckBufSize + 256) {
t.Fatalf("output too long: %d (%d-byte limit)", n, CheckBufSize)
}
}

func TestCheckHTTPCritical(t *testing.T) {
Expand Down
9 changes: 6 additions & 3 deletions website/source/docs/agent/checks.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ There are five different kinds of checks:
* Script + Interval - These checks depend on invoking an external application
that performs the health check, exits with an appropriate exit code, and potentially
generates some output. A script is paired with an invocation interval (e.g.
every 30 seconds). This is similar to the Nagios plugin system.
every 30 seconds). This is similar to the Nagios plugin system. The output of
a script check is limited to 4K. Output larger than this will be truncated.

* HTTP + Interval - These checks make an HTTP `GET` request every Interval (e.g.
every 30 seconds) to the specified URL. The status of the service depends on the HTTP response code:
Expand All @@ -29,7 +30,8 @@ There are five different kinds of checks:
to check a simple HTTP operation. By default, HTTP checks will be configured
with a request timeout equal to the check interval, with a max of 10 seconds.
It is possible to configure a custom HTTP check timeout value by specifying
the `timeout` field in the check definition.
the `timeout` field in the check definition. The output of the check is
limited to roughly 4K. Responses larger than this will be truncated.

* TCP + Interval - These checks make an TCP connection attempt every Interval
(e.g. every 30 seconds) to the specified IP/hostname and port. The status of
Expand Down Expand Up @@ -68,7 +70,8 @@ determine the Docker API endpoint. The application is expected to run, perform a
check of the service running inside the container, and exit with an appropriate exit code.
The check should be paired with an invocation interval. The shell on which the check
has to be performed is configurable which makes it possible to run containers which
have different shells on the same host.
have different shells on the same host. Check output for Docker is limited to
4K. Any output larger than this will be truncated.

## Check Definition

Expand Down