diff --git a/checker/checker.go b/checker/checker.go new file mode 100644 index 0000000..c08a207 --- /dev/null +++ b/checker/checker.go @@ -0,0 +1,24 @@ +package checker + +import ( + "context" + "time" +) + +// Checker performs a configured check +type Checker interface { + Check(context.Context) (*Result, error) +} + +// Config is a common configuration for any checker +type Config struct { + Type string `json:"type"` + Interval time.Duration `json:"interval"` +} + +// Result from a check +type Result struct { + Success bool `json:"success"` + Message string `json:"message"` + RTT time.Duration `json:"rtt"` +} diff --git a/checker/http.go b/checker/http.go new file mode 100644 index 0000000..8fc445c --- /dev/null +++ b/checker/http.go @@ -0,0 +1,52 @@ +package checker + +import ( + "context" + "fmt" + "net/http" + "time" +) + +const ( + // HTTPCheckerType name + HTTPCheckerType = "http" +) + +// HTTP checker implementation +type HTTP struct { + URL string `json:"url"` + ExpectedStatus int `json:"status_code"` + Config +} + +// Check the configuration via HTTP +func (h *HTTP) Check(ctx context.Context) (*Result, error) { + request, err := http.NewRequestWithContext(ctx, http.MethodGet, h.URL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create a request for URL %s: %w", h.URL, err) + } + + result := &Result{} + + start := time.Now() + response, err := http.DefaultClient.Do(request) + result.RTT = time.Since(start) + + if err != nil { + result.Message = err.Error() + + return result, nil + } + + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + result.Message = fmt.Sprintf("failed to get a status 200, got %d", response.StatusCode) + + return result, nil + } + + result.Success = true + + return result, nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5ebd049 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.0xdad.com/tblyler/status + +go 1.16