2020-12-29 21:47:57 +01:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/TwinProduction/gatus/core"
|
|
|
|
)
|
|
|
|
|
|
|
|
// InMemoryStore implements an in-memory store
|
2020-12-31 21:37:11 +01:00
|
|
|
type InMemoryStore struct {
|
|
|
|
serviceStatuses map[string]*core.ServiceStatus
|
|
|
|
serviceResultsMutex sync.RWMutex
|
|
|
|
}
|
2020-12-29 21:47:57 +01:00
|
|
|
|
|
|
|
// NewInMemoryStore returns an in-memory store. Note that the store acts as a singleton, so although new-ing
|
|
|
|
// up in-memory stores will give you a unique reference to a struct each time, all structs returned
|
|
|
|
// by this function will act on the same in-memory store.
|
|
|
|
func NewInMemoryStore() InMemoryStore {
|
2020-12-31 21:37:11 +01:00
|
|
|
return InMemoryStore{
|
|
|
|
serviceStatuses: make(map[string]*core.ServiceStatus),
|
|
|
|
}
|
2020-12-29 21:47:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetAll returns all the observed results for all services from the in memory store
|
|
|
|
func (ims *InMemoryStore) GetAll() map[string]*core.ServiceStatus {
|
|
|
|
results := make(map[string]*core.ServiceStatus)
|
2020-12-31 21:37:11 +01:00
|
|
|
ims.serviceResultsMutex.RLock()
|
|
|
|
for key, svcStatus := range ims.serviceStatuses {
|
2020-12-29 21:47:57 +01:00
|
|
|
copiedResults := copyResults(svcStatus.Results)
|
|
|
|
results[key] = &core.ServiceStatus{
|
|
|
|
Name: svcStatus.Name,
|
|
|
|
Group: svcStatus.Group,
|
|
|
|
Results: copiedResults,
|
|
|
|
}
|
|
|
|
}
|
2020-12-31 21:37:11 +01:00
|
|
|
ims.serviceResultsMutex.RUnlock()
|
2020-12-29 21:47:57 +01:00
|
|
|
|
|
|
|
return results
|
|
|
|
}
|
|
|
|
|
2020-12-31 21:33:35 +01:00
|
|
|
// GetServiceStatus returns the service status for a given service name in the given group
|
|
|
|
func (ims *InMemoryStore) GetServiceStatus(group, name string) *core.ServiceStatus {
|
|
|
|
key := fmt.Sprintf("%s_%s", group, name)
|
2020-12-31 21:37:11 +01:00
|
|
|
ims.serviceResultsMutex.RLock()
|
|
|
|
serviceStatus, exists := ims.serviceStatuses[key]
|
|
|
|
ims.serviceResultsMutex.RUnlock()
|
2020-12-31 21:33:35 +01:00
|
|
|
if !exists {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return serviceStatus
|
|
|
|
}
|
|
|
|
|
2020-12-29 21:47:57 +01:00
|
|
|
// Insert inserts the observed result for the specified service into the in memory store
|
|
|
|
func (ims *InMemoryStore) Insert(service *core.Service, result *core.Result) {
|
|
|
|
key := fmt.Sprintf("%s_%s", service.Group, service.Name)
|
2020-12-31 21:37:11 +01:00
|
|
|
ims.serviceResultsMutex.Lock()
|
|
|
|
serviceStatus, exists := ims.serviceStatuses[key]
|
2020-12-29 21:47:57 +01:00
|
|
|
if !exists {
|
|
|
|
serviceStatus = core.NewServiceStatus(service)
|
2020-12-31 21:37:11 +01:00
|
|
|
ims.serviceStatuses[key] = serviceStatus
|
2020-12-29 21:47:57 +01:00
|
|
|
}
|
|
|
|
serviceStatus.AddResult(result)
|
2020-12-31 21:37:11 +01:00
|
|
|
ims.serviceResultsMutex.Unlock()
|
2020-12-29 21:47:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func copyResults(results []*core.Result) []*core.Result {
|
|
|
|
copiedResults := []*core.Result{}
|
|
|
|
for _, result := range results {
|
|
|
|
copiedErrors := copyErrors(result.Errors)
|
|
|
|
copiedConditionResults := copyConditionResults(result.ConditionResults)
|
|
|
|
|
|
|
|
copiedResults = append(copiedResults, &core.Result{
|
|
|
|
HTTPStatus: result.HTTPStatus,
|
|
|
|
DNSRCode: result.DNSRCode,
|
|
|
|
Body: result.Body,
|
|
|
|
Hostname: result.Hostname,
|
|
|
|
IP: result.IP,
|
|
|
|
Connected: result.Connected,
|
|
|
|
Duration: result.Duration,
|
|
|
|
Errors: copiedErrors,
|
|
|
|
ConditionResults: copiedConditionResults,
|
|
|
|
Success: result.Connected,
|
|
|
|
Timestamp: result.Timestamp,
|
|
|
|
CertificateExpiration: result.CertificateExpiration,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return copiedResults
|
|
|
|
}
|
|
|
|
|
|
|
|
func copyConditionResults(crs []*core.ConditionResult) []*core.ConditionResult {
|
|
|
|
copiedConditionResults := []*core.ConditionResult{}
|
|
|
|
for _, conditionResult := range crs {
|
|
|
|
copiedConditionResults = append(copiedConditionResults, &core.ConditionResult{
|
|
|
|
Condition: conditionResult.Condition,
|
|
|
|
Success: conditionResult.Success,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return copiedConditionResults
|
|
|
|
}
|
|
|
|
|
|
|
|
func copyErrors(errors []string) []string {
|
|
|
|
copiedErrors := []string{}
|
|
|
|
for _, error := range errors {
|
|
|
|
copiedErrors = append(copiedErrors, error)
|
|
|
|
}
|
|
|
|
return copiedErrors
|
|
|
|
}
|
2020-12-30 11:57:17 +01:00
|
|
|
|
|
|
|
// Clear will empty all the results from the in memory store
|
|
|
|
func (ims *InMemoryStore) Clear() {
|
2020-12-31 21:37:11 +01:00
|
|
|
ims.serviceResultsMutex.Lock()
|
|
|
|
ims.serviceStatuses = make(map[string]*core.ServiceStatus)
|
|
|
|
ims.serviceResultsMutex.Unlock()
|
2020-12-30 11:57:17 +01:00
|
|
|
}
|