mirror of
https://github.com/TwiN/gatus.git
synced 2025-02-16 10:20:00 +01:00
Move structs to core package
This commit is contained in:
parent
eea38c8618
commit
ee479be716
@ -1,13 +1,12 @@
|
|||||||
services:
|
services:
|
||||||
- name: twinnation
|
- name: twinnation
|
||||||
url: https://twinnation.org/actuator/health
|
url: https://twinnation.org/actuator/health
|
||||||
interval: 10
|
interval: 15
|
||||||
failure-threshold: 3
|
failure-threshold: 3
|
||||||
conditions:
|
conditions:
|
||||||
- "$STATUS == 200"
|
- "$STATUS == 200"
|
||||||
- name: github
|
- name: github
|
||||||
url: https://github.com
|
url: https://github.com
|
||||||
interval: 10
|
|
||||||
failure-threshold: 3
|
|
||||||
conditions:
|
conditions:
|
||||||
- "$STATUS == 200"
|
- "$STATUS != 400"
|
||||||
|
- "$STATUS != 500"
|
@ -1,24 +1,15 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TwinProduction/gatus/core"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Services []Service `yaml:"services"`
|
Services []*core.Service `yaml:"services"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service struct {
|
|
||||||
Name string `yaml:"name"`
|
|
||||||
Url string `yaml:"url"`
|
|
||||||
Interval uint `yaml:"interval"`
|
|
||||||
FailureThreshold uint `yaml:"failure-threshold"`
|
|
||||||
Conditions []Condition `yaml:"conditions"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Condition string
|
|
||||||
|
|
||||||
var config *Config
|
var config *Config
|
||||||
|
|
||||||
func Get() *Config {
|
func Get() *Config {
|
||||||
@ -41,5 +32,13 @@ func ReadConfigurationFile(fileName string) *Config {
|
|||||||
func ParseConfigBytes(yamlBytes []byte) *Config {
|
func ParseConfigBytes(yamlBytes []byte) *Config {
|
||||||
config = &Config{}
|
config = &Config{}
|
||||||
yaml.Unmarshal(yamlBytes, config)
|
yaml.Unmarshal(yamlBytes, config)
|
||||||
|
for _, service := range config.Services {
|
||||||
|
if service.FailureThreshold == 0 {
|
||||||
|
service.FailureThreshold = 1
|
||||||
|
}
|
||||||
|
if service.Interval == 0 {
|
||||||
|
service.Interval = 10
|
||||||
|
}
|
||||||
|
}
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,14 @@ func TestParseConfigBytes(t *testing.T) {
|
|||||||
services:
|
services:
|
||||||
- name: twinnation
|
- name: twinnation
|
||||||
url: https://twinnation.org/actuator/health
|
url: https://twinnation.org/actuator/health
|
||||||
interval: 10
|
interval: 15
|
||||||
failure-threshold: 3
|
failure-threshold: 3
|
||||||
conditions:
|
conditions:
|
||||||
- "$STATUS == 200"
|
- "$STATUS == 200"
|
||||||
- name: github
|
- name: github
|
||||||
url: https://github.com
|
url: https://github.com
|
||||||
interval: 9
|
|
||||||
failure-threshold: 2
|
|
||||||
conditions:
|
conditions:
|
||||||
- "$STATUS != 405"
|
- "$STATUS != 400"
|
||||||
- "$STATUS != 500"
|
- "$STATUS != 500"
|
||||||
`))
|
`))
|
||||||
if len(config.Services) != 2 {
|
if len(config.Services) != 2 {
|
||||||
@ -28,17 +26,17 @@ services:
|
|||||||
if config.Services[1].Url != "https://github.com" {
|
if config.Services[1].Url != "https://github.com" {
|
||||||
t.Errorf("URL should have been %s", "https://github.com")
|
t.Errorf("URL should have been %s", "https://github.com")
|
||||||
}
|
}
|
||||||
if config.Services[0].Interval != 10 {
|
if config.Services[0].Interval != 15 {
|
||||||
t.Errorf("Interval should have been %d", 10)
|
t.Errorf("Interval should have been %d", 15)
|
||||||
}
|
}
|
||||||
if config.Services[1].Interval != 9 {
|
if config.Services[1].Interval != 10 {
|
||||||
t.Errorf("Interval should have been %d", 9)
|
t.Errorf("Interval should have been %d, because it is the default value", 10)
|
||||||
}
|
}
|
||||||
if config.Services[0].FailureThreshold != 3 {
|
if config.Services[0].FailureThreshold != 3 {
|
||||||
t.Errorf("FailureThreshold should have been %d", 3)
|
t.Errorf("FailureThreshold should have been %d", 3)
|
||||||
}
|
}
|
||||||
if config.Services[1].FailureThreshold != 2 {
|
if config.Services[1].FailureThreshold != 1 {
|
||||||
t.Errorf("FailureThreshold should have been %d", 2)
|
t.Errorf("FailureThreshold should have been %d, because it is the default value", 1)
|
||||||
}
|
}
|
||||||
if len(config.Services[0].Conditions) != 1 {
|
if len(config.Services[0].Conditions) != 1 {
|
||||||
t.Errorf("There should have been %d conditions", 1)
|
t.Errorf("There should have been %d conditions", 1)
|
||||||
|
126
core/types.go
Normal file
126
core/types.go
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Result struct {
|
||||||
|
HttpStatus int
|
||||||
|
Hostname string
|
||||||
|
Ip string
|
||||||
|
Duration time.Duration
|
||||||
|
Errors []error
|
||||||
|
ConditionResult []*ConditionResult
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Url string `yaml:"url"`
|
||||||
|
Interval int `yaml:"interval,omitempty"`
|
||||||
|
FailureThreshold int `yaml:"failure-threshold,omitempty"`
|
||||||
|
Conditions []*Condition `yaml:"conditions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *Service) getIp(result *Result) {
|
||||||
|
urlObject, err := url.Parse(service.Url)
|
||||||
|
if err != nil {
|
||||||
|
result.Errors = append(result.Errors, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result.Hostname = urlObject.Hostname()
|
||||||
|
ips, err := net.LookupIP(urlObject.Hostname())
|
||||||
|
if err != nil {
|
||||||
|
result.Errors = append(result.Errors, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result.Ip = ips[0].String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *Service) getStatus(result *Result) {
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: time.Second * 10,
|
||||||
|
}
|
||||||
|
startTime := time.Now()
|
||||||
|
response, err := client.Get(service.Url)
|
||||||
|
if err != nil {
|
||||||
|
result.Errors = append(result.Errors, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result.Duration = time.Now().Sub(startTime)
|
||||||
|
result.HttpStatus = response.StatusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *Service) EvaluateConditions() *Result {
|
||||||
|
result := &Result{}
|
||||||
|
service.getStatus(result)
|
||||||
|
service.getIp(result)
|
||||||
|
for _, condition := range service.Conditions {
|
||||||
|
condition.Evaluate(result)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConditionResult struct {
|
||||||
|
Condition *Condition
|
||||||
|
Success bool
|
||||||
|
Explanation string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Condition string
|
||||||
|
|
||||||
|
func (c *Condition) Evaluate(result *Result) {
|
||||||
|
condition := string(*c)
|
||||||
|
if strings.Contains(condition, "==") {
|
||||||
|
parts := sanitizeAndResolve(strings.Split(condition, "=="), result)
|
||||||
|
if parts[0] == parts[1] {
|
||||||
|
result.ConditionResult = append(result.ConditionResult, &ConditionResult{
|
||||||
|
Condition: c,
|
||||||
|
Success: true,
|
||||||
|
Explanation: fmt.Sprintf("%s is equal to %s", parts[0], parts[1]),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result.ConditionResult = append(result.ConditionResult, &ConditionResult{
|
||||||
|
Condition: c,
|
||||||
|
Success: false,
|
||||||
|
Explanation: fmt.Sprintf("%s is not equal to %s", parts[0], parts[1]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if strings.Contains(condition, "!=") {
|
||||||
|
parts := sanitizeAndResolve(strings.Split(condition, "!="), result)
|
||||||
|
if parts[0] != parts[1] {
|
||||||
|
result.ConditionResult = append(result.ConditionResult, &ConditionResult{
|
||||||
|
Condition: c,
|
||||||
|
Success: true,
|
||||||
|
Explanation: fmt.Sprintf("%s is not equal to %s", parts[0], parts[1]),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result.ConditionResult = append(result.ConditionResult, &ConditionResult{
|
||||||
|
Condition: c,
|
||||||
|
Success: false,
|
||||||
|
Explanation: fmt.Sprintf("%s is equal to %s", parts[0], parts[1]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitizeAndResolve(list []string, result *Result) []string {
|
||||||
|
var sanitizedList []string
|
||||||
|
for _, element := range list {
|
||||||
|
element = strings.TrimSpace(element)
|
||||||
|
switch strings.ToUpper(element) {
|
||||||
|
case "$STATUS":
|
||||||
|
element = strconv.Itoa(result.HttpStatus)
|
||||||
|
case "$IP":
|
||||||
|
element = result.Ip
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
sanitizedList = append(sanitizedList, element)
|
||||||
|
}
|
||||||
|
return sanitizedList
|
||||||
|
}
|
14
main.go
14
main.go
@ -3,15 +3,13 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TwinProduction/gatus/config"
|
"github.com/TwinProduction/gatus/config"
|
||||||
"github.com/TwinProduction/gatus/watchdog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
request := watchdog.Request{Url: "https://twinnation.org/actuator/health"}
|
for _, service := range config.Get().Services {
|
||||||
result := &watchdog.Result{}
|
result := service.EvaluateConditions()
|
||||||
request.GetIp(result)
|
for _, conditionResult := range result.ConditionResult {
|
||||||
request.GetStatus(result)
|
fmt.Printf("%v\n", *conditionResult)
|
||||||
fmt.Println(result)
|
}
|
||||||
|
}
|
||||||
fmt.Println(config.Get())
|
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1 @@
|
|||||||
package watchdog
|
package watchdog
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Request struct {
|
|
||||||
Url string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Result struct {
|
|
||||||
HttpStatus int
|
|
||||||
Hostname string
|
|
||||||
Ip string
|
|
||||||
Duration time.Duration
|
|
||||||
Errors []error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (request *Request) GetIp(result *Result) {
|
|
||||||
urlObject, err := url.Parse(request.Url)
|
|
||||||
if err != nil {
|
|
||||||
result.Errors = append(result.Errors, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Hostname = urlObject.Hostname()
|
|
||||||
ips, err := net.LookupIP(urlObject.Hostname())
|
|
||||||
if err != nil {
|
|
||||||
result.Errors = append(result.Errors, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Ip = ips[0].String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (request *Request) GetStatus(result *Result) {
|
|
||||||
client := &http.Client{
|
|
||||||
Timeout: time.Second * 10,
|
|
||||||
}
|
|
||||||
startTime := time.Now()
|
|
||||||
response, err := client.Get(request.Url)
|
|
||||||
if err != nil {
|
|
||||||
result.Errors = append(result.Errors, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result.Duration = time.Now().Sub(startTime)
|
|
||||||
result.HttpStatus = response.StatusCode
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user