Skip to content

Commit

Permalink
Merge ac52bea into 1a0e4d5
Browse files Browse the repository at this point in the history
  • Loading branch information
rphillips committed Dec 16, 2016
2 parents 1a0e4d5 + ac52bea commit 4e49c3a
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 12 deletions.
36 changes: 35 additions & 1 deletion check/check_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
protocol "github.com/racker/rackspace-monitoring-poller/protocol/check"
"github.com/racker/rackspace-monitoring-poller/protocol/metric"
Expand All @@ -35,6 +36,7 @@ import (
"net/http"
"net/http/httptrace"
"net/url"
"regexp"
"strconv"
"strings"
)
Expand Down Expand Up @@ -222,7 +224,7 @@ func (ch *HTTPCheck) Run() (*CheckResultSet, error) {
req = req.WithContext(httptrace.WithClientTrace(ctx, trace))

// Add Headers
req.Header.Add("Accept-Encoding", "gzip, deflate")
req.Header.Add("Accept-Encoding", "gzip,deflate")
req.Header.Add("User-Agent", UserAgent)
req.Header.Add("Host", host)
for key, value := range ch.Details.Headers {
Expand All @@ -247,6 +249,38 @@ func (ch *HTTPCheck) Run() (*CheckResultSet, error) {
return crs, nil
}
endtime := utils.NowTimestampMillis()

// Parse Body
if len(ch.Details.Body) > 0 {
if re, err := regexp.Compile(ch.Details.Body); err == nil {
if m := re.FindSubmatch(body); m != nil {
cr.AddMetric(metric.NewMetric("body_match", "", metric.MetricString, string(m[1]), ""))
} else {
cr.AddMetric(metric.NewMetric("body_match", "", metric.MetricString, "", ""))
}
} else {
crs.SetStatus(err.Error())
crs.SetStateUnavailable()
return crs, nil
}
}

// Body Matches
for key, regex := range ch.Details.BodyMatches {
if re, err := regexp.Compile(regex); err == nil {
if m := re.FindSubmatch(body); m != nil {
cr.AddMetric(metric.NewMetric(fmt.Sprintf("body_match_%s", key), "", metric.MetricString, string(m[1]), ""))
} else {
cr.AddMetric(metric.NewMetric(fmt.Sprintf("body_match_%s", key), "", metric.MetricString, "", ""))
}
} else {
crs.SetStatus(err.Error())
crs.SetStateUnavailable()
return crs, nil
}

}

truncated := resp.ContentLength - int64(len(body))
codeStr := strconv.FormatInt(int64(resp.StatusCode), 10)

Expand Down
64 changes: 64 additions & 0 deletions check/check_http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,70 @@ func TestHTTPSuccessIncludeBodyAndHeaders(t *testing.T) {
}
}

func TestHTTPSuccessBodyMatch(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(staticResponse))
defer ts.Close()

// Create Check
checkData := fmt.Sprintf(`{
"id":"chPzAHTTP",
"zone_id":"pzA",
"entity_id":"enAAAAIPV4",
"details":{"url":"%s","include_body":true,"headers":{"foo":"bar"},"body":"Foo=(.*)","body_matches":{"foo":"Foo=(.*)"}},
"type":"remote.http",
"timeout":15,
"period":30,
"ip_addresses":{"default":"127.0.0.1"},
"target_alias":"default",
"target_hostname":"",
"target_resolver":"",
"disabled":false
}`, ts.URL)
check := check.NewCheck([]byte(checkData))

// Run check
crs, err := check.Run()
if err != nil {
t.Error(err)
}

// Validate Metrics
if crs.Available == false {
t.Fatal("availability should be true")
}

metrics := []string{
"bytes",
"code",
"body",
"body_match",
"body_match_foo",
"truncated",
"tt_connect",
"tt_firstbyte",
}
ValidateMetrics(t, metrics, crs.Get(0))

// Validate body
body, _ := crs.Get(0).GetMetric("body").ToString()
if !strings.Contains(body, staticHello) {
t.Fatal("body does not contain: " + staticHello)
}
if !strings.Contains(body, "Foo=bar") {
t.Fatal("header is not present")
}
// Validate body_match
bodyMatch, _ := crs.Get(0).GetMetric("body_match").ToString()
if !strings.Contains(bodyMatch, "bar") {
t.Fatal("bodyMatch does not contain bar")
}
// Validate body_match_foo
foo, _ := crs.Get(0).GetMetric("body_match_foo").ToString()
if !strings.Contains(foo, "bar") {
t.Fatal("foo does not contain bar")
}
}

func TestHTTPClosed(t *testing.T) {
// Create a server then close it
ts := httptest.NewServer(http.HandlerFunc(staticResponse))
Expand Down
4 changes: 2 additions & 2 deletions check/check_tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ func (ch *TCPCheck) Run() (*CheckResultSet, error) {
if len(line) > MaxTCPBannerLength {
line = line[:MaxTCPBannerLength]
}
if re, err := regexp.Compile(ch.Details.BannerMatch); err != nil {
if re, err := regexp.Compile(ch.Details.BannerMatch); err == nil {
if m := re.FindSubmatch(line); m != nil {
cr.AddMetric(metric.NewMetric("banner_match", "", metric.MetricString, m[0], ""))
cr.AddMetric(metric.NewMetric("banner_match", "", metric.MetricString, string(m[1]), ""))
} else {
cr.AddMetric(metric.NewMetric("banner_match", "", metric.MetricString, "", ""))
}
Expand Down
18 changes: 9 additions & 9 deletions protocol/check/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ package check

type HTTPCheckDetails struct {
Details struct {
AuthPassword string `json:"auth_password"`
AuthUser string `json:"auth_user"`
Body string `json:"body"`
BodyMatches []map[string]string `json:"body_matches"`
FollowRedirects bool `json:"follow_redirects"`
Headers map[string]string `json:"headers"`
IncludeBody bool `json:"include_body"`
Method string `json:"method"`
Url string `json:"url"`
AuthPassword string `json:"auth_password"`
AuthUser string `json:"auth_user"`
Body string `json:"body"`
BodyMatches map[string]string `json:"body_matches"`
FollowRedirects bool `json:"follow_redirects"`
Headers map[string]string `json:"headers"`
IncludeBody bool `json:"include_body"`
Method string `json:"method"`
Url string `json:"url"`
}
}

Expand Down

0 comments on commit 4e49c3a

Please sign in to comment.