Compare commits

..

8 Commits

Author SHA1 Message Date
TwiN
3a4ab62ddd #191: Handle memory issue caused by migration from Service to Endpoint 2021-10-24 21:20:01 -04:00
TwiN
a4e9d8e9b0 Revert "Add GATUS_DONT_EXPAND_ENV env var" 2021-10-24 18:34:39 -04:00
TwiN
3be6d04d29 Add GATUS_DONT_EXPAND_ENV env var 2021-10-24 16:20:24 -04:00
TwiN
b59ff6f89e Add ServiceAccount to Kubernetes example 2021-10-24 15:33:15 -04:00
TwiN
813fea93ee #167: Rename examples/minimal to .examples/docker-minimal 2021-10-24 15:27:25 -04:00
TwiN
8f50e44b45 #167: Rename examples/ to .examples/ 2021-10-24 15:20:39 -04:00
TwiN
fb2448c15a Omit fields that are not set 2021-10-24 15:03:41 -04:00
TwiN
db575aad13 Remove comments that no longer apply 2021-10-24 14:51:49 -04:00
24 changed files with 64 additions and 36 deletions

View File

@@ -1,4 +1,4 @@
examples
.examples
Dockerfile
.github
.idea

View File

@@ -9,14 +9,17 @@ data:
endpoints:
- name: website
url: https://twin.sh/health
interval: 1m
interval: 5m
conditions:
- "[STATUS] == 200"
- "[BODY].status == UP"
- name: github
url: https://api.github.com/healthz
interval: 5m
conditions:
- "[STATUS] == 200"
- name: cat-fact
url: "https://cat-fact.herokuapp.com/facts/random"
interval: 5m
@@ -27,11 +30,18 @@ data:
- "[BODY].text == pat(*cat*)"
- "[STATUS] == pat(2*)"
- "[CONNECTED] == true"
- name: example
url: https://example.com/
conditions:
- "[STATUS] == 200"
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: gatus
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -41,14 +51,16 @@ spec:
replicas: 1
selector:
matchLabels:
k8s-app: gatus
app: gatus
template:
metadata:
labels:
k8s-app: gatus
app: gatus
name: gatus
namespace: kube-system
spec:
serviceAccountName: gatus
terminationGracePeriodSeconds: 5
containers:
- image: twinproduction/gatus
imagePullPolicy: IfNotPresent
@@ -84,4 +96,4 @@ spec:
protocol: TCP
targetPort: 8080
selector:
k8s-app: gatus
app: gatus

View File

@@ -19,7 +19,7 @@ core applications: https://status.twin.sh/
<details>
<summary><b>Quick start</b></summary>
```
```console
docker run -p 8080:8080 --name gatus twinproduction/gatus
```
For more details, see [Usage](#usage)
@@ -246,7 +246,7 @@ storage:
type: sqlite
file: data.db
```
See [examples/docker-compose-sqlite-storage](examples/docker-compose-sqlite-storage) for an example.
See [examples/docker-compose-sqlite-storage](.examples/docker-compose-sqlite-storage) for an example.
- If `storage.type` is `postgres`, `storage.file` must be the connection URL:
```yaml
@@ -254,7 +254,7 @@ storage:
type: postgres
file: "postgres://user:password@127.0.0.1:5432/gatus?sslmode=disable"
```
See [examples/docker-compose-postgres-storage](examples/docker-compose-postgres-storage) for an example.
See [examples/docker-compose-postgres-storage](.examples/docker-compose-postgres-storage) for an example.
### Client configuration
@@ -798,29 +798,29 @@ maintenance:
## Deployment
Many examples can be found in the [examples](examples) folder, but this section will focus on the most popular ways of deploying Gatus.
Many examples can be found in the [.examples](.examples) folder, but this section will focus on the most popular ways of deploying Gatus.
### Docker
To run Gatus locally with Docker:
```
```console
docker run -p 8080:8080 --name gatus twinproduction/gatus
```
Other than using one of the examples provided in the `examples` folder, you can also try it out locally by
Other than using one of the examples provided in the [.examples](.examples) folder, you can also try it out locally by
creating a configuration file, we'll call it `config.yaml` for this example, and running the following
command:
```
```console
docker run -p 8080:8080 --mount type=bind,source="$(pwd)"/config.yaml,target=/config/config.yaml --name gatus twinproduction/gatus
```
If you're on Windows, replace `"$(pwd)"` by the absolute path to your current directory, e.g.:
```
```console
docker run -p 8080:8080 --mount type=bind,source=C:/Users/Chris/Desktop/config.yaml,target=/config/config.yaml --name gatus twinproduction/gatus
```
To build the image locally:
```
```console
docker build . -t twinproduction/gatus
```
@@ -845,7 +845,7 @@ Gatus can be deployed on Terraform by using the following module: [terraform-kub
## Running the tests
```
```console
go test ./... -mod vendor
```

View File

@@ -43,28 +43,28 @@ var (
// Config is the main configuration structure
type Config struct {
// Debug Whether to enable debug logs
Debug bool `yaml:"debug"`
Debug bool `yaml:"debug,omitempty"`
// Metrics Whether to expose metrics at /metrics
Metrics bool `yaml:"metrics"`
Metrics bool `yaml:"metrics,omitempty"`
// SkipInvalidConfigUpdate Whether to make the application ignore invalid configuration
// if the configuration file is updated while the application is running
SkipInvalidConfigUpdate bool `yaml:"skip-invalid-config-update"`
SkipInvalidConfigUpdate bool `yaml:"skip-invalid-config-update,omitempty"`
// DisableMonitoringLock Whether to disable the monitoring lock
// The monitoring lock is what prevents multiple endpoints from being processed at the same time.
// Disabling this may lead to inaccurate response times
DisableMonitoringLock bool `yaml:"disable-monitoring-lock"`
DisableMonitoringLock bool `yaml:"disable-monitoring-lock,omitempty"`
// Security Configuration for securing access to Gatus
Security *security.Config `yaml:"security"`
Security *security.Config `yaml:"security,omitempty"`
// Alerting Configuration for alerting
Alerting *alerting.Config `yaml:"alerting"`
Alerting *alerting.Config `yaml:"alerting,omitempty"`
// Endpoints List of endpoints to monitor
Endpoints []*core.Endpoint `yaml:"endpoints"`
Endpoints []*core.Endpoint `yaml:"endpoints,omitempty"`
// Services List of endpoints to monitor
//
@@ -72,19 +72,19 @@ type Config struct {
// XXX: This is not a typo -- not v4.0.0, but v5.0.0 -- I want to give enough time for people to migrate
//
// Deprecated in favor of Endpoints
Services []*core.Endpoint `yaml:"services"`
Services []*core.Endpoint `yaml:"services,omitempty"`
// Storage is the configuration for how the data is stored
Storage *storage.Config `yaml:"storage"`
Storage *storage.Config `yaml:"storage,omitempty"`
// Web is the web configuration for the application
Web *web.Config `yaml:"web"`
Web *web.Config `yaml:"web,omitempty"`
// UI is the configuration for the UI
UI *ui.Config `yaml:"ui"`
UI *ui.Config `yaml:"ui,omitempty"`
// Maintenance is the configuration for creating a maintenance window in which no alerts are sent
Maintenance *maintenance.Config `yaml:"maintenance"`
Maintenance *maintenance.Config `yaml:"maintenance,omitempty"`
filePath string // path to the file from which config was loaded from
lastFileModTime time.Time // last modification time
@@ -149,12 +149,12 @@ func readConfigurationFile(fileName string) (config *Config, err error) {
return
}
// parseAndValidateConfigBytes parses a Gatus configuration file into a Config struct and validates its parameters
func parseAndValidateConfigBytes(yamlBytes []byte) (config *Config, err error) {
// Expand environment variables
yamlBytes = []byte(os.ExpandEnv(string(yamlBytes)))
// Parse configuration file
err = yaml.Unmarshal(yamlBytes, &config)
if err != nil {
if err = yaml.Unmarshal(yamlBytes, &config); err != nil {
return
}
if config != nil && len(config.Services) > 0 { // XXX: Remove this in v5.0.0
@@ -167,8 +167,6 @@ func parseAndValidateConfigBytes(yamlBytes []byte) (config *Config, err error) {
if config == nil || config.Endpoints == nil || len(config.Endpoints) == 0 {
err = ErrNoEndpointInConfig
} else {
// Note that the functions below may panic, and this is on purpose to prevent Gatus from starting with
// invalid configurations
validateAlertingConfig(config.Alerting, config.Endpoints, config.Debug)
if err := validateSecurityConfig(config); err != nil {
return nil, err

View File

@@ -79,19 +79,19 @@ type Endpoint struct {
Conditions []*Condition `yaml:"conditions"`
// Alerts is the alerting configuration for the endpoint in case of failure
Alerts []*alert.Alert `yaml:"alerts"`
Alerts []*alert.Alert `yaml:"alerts,omitempty"`
// ClientConfig is the configuration of the client used to communicate with the endpoint's target
ClientConfig *client.Config `yaml:"client"`
ClientConfig *client.Config `yaml:"client,omitempty"`
// UIConfig is the configuration for the UI
UIConfig *ui.Config `yaml:"ui"`
UIConfig *ui.Config `yaml:"ui,omitempty"`
// NumberOfFailuresInARow is the number of unsuccessful evaluations in a row
NumberOfFailuresInARow int
NumberOfFailuresInARow int `yaml:"-"`
// NumberOfSuccessesInARow is the number of successful evaluations in a row
NumberOfSuccessesInARow int
NumberOfSuccessesInARow int `yaml:"-"`
}
// IsEnabled returns whether the endpoint is enabled or not

View File

@@ -2,7 +2,11 @@ package memory
import (
"encoding/gob"
"io/fs"
"io/ioutil"
"log"
"sort"
"strings"
"sync"
"time"
@@ -40,6 +44,20 @@ func NewStore(file string) (*Store, error) {
if len(file) > 0 {
_, err := store.cache.ReadFromFile(file)
if err != nil {
// XXX: Remove the block below in v4.0.0
if data, err2 := ioutil.ReadFile(file); err2 == nil {
isFromOldVersion := strings.Contains(string(data), "*core.ServiceStatus")
if isFromOldVersion {
log.Println("WARNING: Couldn't read file due to recent change in v3.3.0, see https://github.com/TwiN/gatus/issues/191")
log.Println("WARNING: Will automatically rename old file to " + file + ".old and overwrite the current file")
if err = ioutil.WriteFile(file+".old", data, fs.ModePerm); err != nil {
log.Println("WARNING: Tried my best to keep the old file, but it wasn't enough. Sorry, your file will be overwritten :(")
}
// Return the store regardless of whether there was an error or not
return store, nil
}
}
// XXX: Remove the block above in v4.0.0
return nil, err
}
}