diff --git a/README.md b/README.md index 2b95fd9e..155314c7 100644 --- a/README.md +++ b/README.md @@ -40,16 +40,17 @@ Note that you can also add environment variables in the your configuration file ### Configuration -| Parameter | Description | Default | -| ----------------------- | ------------------------------------------------------ | -------------- | -| `metrics` | Whether to expose metrics at /metrics | `false` | -| `services[].name` | Name of the service. Can be anything. | Required `""` | -| `services[].url` | URL to send the request to | Required `""` | -| `services[].conditions` | Conditions used to determine the health of the service | `[]` | -| `services[].interval` | Duration to wait between every status check | `10s` | -| `services[].method` | Request method | `GET` | -| `services[].body` | Request body | `""` | -| `services[].headers` | Request headers | `{}` | +| Parameter | Description | Default | +| ----------------------- | --------------------------------------------------------------- | -------------- | +| `metrics` | Whether to expose metrics at /metrics | `false` | +| `services[].name` | Name of the service. Can be anything. | Required `""` | +| `services[].url` | URL to send the request to | Required `""` | +| `services[].conditions` | Conditions used to determine the health of the service | `[]` | +| `services[].interval` | Duration to wait between every status check | `10s` | +| `services[].method` | Request method | `GET` | +| `services[].graphql` | Whether to wrap the body in a query param (`{"query":"$body"}`) | `false` | +| `services[].body` | Request body | `""` | +| `services[].headers` | Request headers | `{}` | ### Conditions @@ -95,3 +96,38 @@ go test ./... -mod vendor ## Using in Production See the [example](example) folder. + + +## FAQ + +### Sending a GraphQL request + +By setting `services[].graphql` to true, the body will automatically be wrapped by the standard GraphQL `query` parameter. + +For instance, the following configuration: +``` +services: + - name: properties + url: http://localhost:8080/playground + method: POST + graphql: true + body: | + { + user(gender: "female") { + id + name + gender + avatar + } + } + headers: + Content-Type: application/json + conditions: + - "[STATUS] == 200" + - "[BODY].data.user[0].gender == female" +``` + +will send a `POST` request to `http://localhost:8080/playground` with the following body: +```json +{"query":" {\n user(gender: \"female\") {\n id\n name\n gender\n avatar\n }\n }"} +``` \ No newline at end of file diff --git a/core/service.go b/core/service.go index b28055cc..02f294ef 100644 --- a/core/service.go +++ b/core/service.go @@ -2,6 +2,7 @@ package core import ( "bytes" + "encoding/json" "errors" "github.com/TwinProduction/gatus/client" "io/ioutil" @@ -21,6 +22,7 @@ type Service struct { Url string `yaml:"url"` Method string `yaml:"method,omitempty"` Body string `yaml:"body,omitempty"` + GraphQL bool `yaml:"graphql,omitempty"` Headers map[string]string `yaml:"headers,omitempty"` Interval time.Duration `yaml:"interval,omitempty"` Conditions []*Condition `yaml:"conditions"` @@ -102,7 +104,17 @@ func (service *Service) call(result *Result) { } func (service *Service) buildRequest() *http.Request { - request, _ := http.NewRequest(service.Method, service.Url, bytes.NewBuffer([]byte(service.Body))) + var bodyBuffer *bytes.Buffer + if service.GraphQL { + graphQlBody := map[string]string{ + "query": service.Body, + } + body, _ := json.Marshal(graphQlBody) + bodyBuffer = bytes.NewBuffer(body) + } else { + bodyBuffer = bytes.NewBuffer([]byte(service.Body)) + } + request, _ := http.NewRequest(service.Method, service.Url, bodyBuffer) for k, v := range service.Headers { request.Header.Set(k, v) } diff --git a/watchdog/watchdog.go b/watchdog/watchdog.go index 779e9cb7..d52eaf01 100644 --- a/watchdog/watchdog.go +++ b/watchdog/watchdog.go @@ -1,6 +1,7 @@ package watchdog import ( + "fmt" "github.com/TwinProduction/gatus/config" "github.com/TwinProduction/gatus/core" "github.com/TwinProduction/gatus/metric" @@ -39,11 +40,16 @@ func monitor(service *core.Service) { serviceResults[service.Name] = serviceResults[service.Name][1:] } rwLock.Unlock() + var extra string + if !result.Success { + extra = fmt.Sprintf("responseBody=%s", result.Body) + } log.Printf( - "[watchdog][Monitor] Finished monitoring serviceName=%s; errors=%d; requestDuration=%s", + "[watchdog][Monitor] Finished monitoring serviceName=%s; errors=%d; requestDuration=%s; %s", service.Name, len(result.Errors), result.Duration.Round(time.Millisecond), + extra, ) log.Printf("[watchdog][Monitor] Waiting interval=%s before monitoring serviceName=%s", service.Interval, service.Name) time.Sleep(service.Interval)