mirror of
https://github.com/TwiN/gatus.git
synced 2024-12-14 11:58:04 +00:00
114 lines
4 KiB
Go
114 lines
4 KiB
Go
package core
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/TwinProduction/gatus/util"
|
|
)
|
|
|
|
const (
|
|
// MaximumNumberOfResults is the maximum number of results that ServiceStatus.Results can have
|
|
MaximumNumberOfResults = 100
|
|
|
|
// MaximumNumberOfEvents is the maximum number of events that ServiceStatus.Events can have
|
|
MaximumNumberOfEvents = 50
|
|
)
|
|
|
|
// ServiceStatus contains the evaluation Results of a Service
|
|
type ServiceStatus struct {
|
|
// Name of the service
|
|
Name string `json:"name,omitempty"`
|
|
|
|
// Group the service is a part of. Used for grouping multiple services together on the front end.
|
|
Group string `json:"group,omitempty"`
|
|
|
|
// Key is the key representing the ServiceStatus
|
|
Key string `json:"key"`
|
|
|
|
// Results is the list of service evaluation results
|
|
Results []*Result `json:"results"`
|
|
|
|
// Events is a list of events
|
|
//
|
|
// We don't expose this through JSON, because the main dashboard doesn't need to have this data.
|
|
// However, the detailed service page does leverage this by including it to a map that will be
|
|
// marshalled alongside the ServiceStatus.
|
|
Events []*Event `json:"-"`
|
|
|
|
// Uptime information on the service's uptime
|
|
//
|
|
// We don't expose this through JSON, because the main dashboard doesn't need to have this data.
|
|
// However, the detailed service page does leverage this by including it to a map that will be
|
|
// marshalled alongside the ServiceStatus.
|
|
Uptime *Uptime `json:"-"`
|
|
}
|
|
|
|
// NewServiceStatus creates a new ServiceStatus
|
|
func NewServiceStatus(service *Service) *ServiceStatus {
|
|
return &ServiceStatus{
|
|
Name: service.Name,
|
|
Group: service.Group,
|
|
Key: util.ConvertGroupAndServiceToKey(service.Group, service.Name),
|
|
Results: make([]*Result, 0),
|
|
Events: []*Event{{
|
|
Type: EventStart,
|
|
Timestamp: time.Now(),
|
|
}},
|
|
Uptime: NewUptime(),
|
|
}
|
|
}
|
|
|
|
// WithResultPagination returns a shallow copy of the ServiceStatus with only the results
|
|
// within the range defined by the page and pageSize parameters
|
|
func (ss ServiceStatus) WithResultPagination(page, pageSize int) *ServiceStatus {
|
|
shallowCopy := ss
|
|
numberOfResults := len(shallowCopy.Results)
|
|
start := numberOfResults - (page * pageSize)
|
|
end := numberOfResults - ((page - 1) * pageSize)
|
|
if start > numberOfResults {
|
|
start = -1
|
|
} else if start < 0 {
|
|
start = 0
|
|
}
|
|
if end > numberOfResults {
|
|
end = numberOfResults
|
|
}
|
|
if start < 0 || end < 0 {
|
|
shallowCopy.Results = []*Result{}
|
|
} else {
|
|
shallowCopy.Results = shallowCopy.Results[start:end]
|
|
}
|
|
return &shallowCopy
|
|
}
|
|
|
|
// AddResult adds a Result to ServiceStatus.Results and makes sure that there are
|
|
// no more than 20 results in the Results slice
|
|
func (ss *ServiceStatus) AddResult(result *Result) {
|
|
if len(ss.Results) > 0 {
|
|
// Check if there's any change since the last result
|
|
// OR there's only 1 event, which only happens when there's a start event
|
|
if ss.Results[len(ss.Results)-1].Success != result.Success || len(ss.Events) == 1 {
|
|
event := &Event{Timestamp: result.Timestamp}
|
|
if result.Success {
|
|
event.Type = EventHealthy
|
|
} else {
|
|
event.Type = EventUnhealthy
|
|
}
|
|
ss.Events = append(ss.Events, event)
|
|
if len(ss.Events) > MaximumNumberOfEvents {
|
|
// Doing ss.Events[1:] would usually be sufficient, but in the case where for some reason, the slice has
|
|
// more than one extra element, we can get rid of all of them at once and thus returning the slice to a
|
|
// length of MaximumNumberOfEvents by using ss.Events[len(ss.Events)-MaximumNumberOfEvents:] instead
|
|
ss.Events = ss.Events[len(ss.Events)-MaximumNumberOfEvents:]
|
|
}
|
|
}
|
|
}
|
|
ss.Results = append(ss.Results, result)
|
|
if len(ss.Results) > MaximumNumberOfResults {
|
|
// Doing ss.Results[1:] would usually be sufficient, but in the case where for some reason, the slice has more
|
|
// than one extra element, we can get rid of all of them at once and thus returning the slice to a length of
|
|
// MaximumNumberOfResults by using ss.Results[len(ss.Results)-MaximumNumberOfResults:] instead
|
|
ss.Results = ss.Results[len(ss.Results)-MaximumNumberOfResults:]
|
|
}
|
|
ss.Uptime.ProcessResult(result)
|
|
}
|