From cc784ffc96d2a8aca82158c6d39d1f7ef955d47b Mon Sep 17 00:00:00 2001 From: Kyle Brandt Date: Fri, 13 May 2016 11:34:34 -0400 Subject: [PATCH] cmd/scollector: fastly status.io monitoring and status.io lib --- cmd/scollector/collectors/fastly.go | 92 +++++ .../statusio/componentstatus_jsonenums.go | 62 ++++ .../statusio/incidentstatus_jsonenums.go | 65 ++++ .../statusio/maintenancestatus_jsonenums.go | 62 ++++ .../statusio/statusindicator_jsonenums.go | 62 ++++ .../collectors/statusio/statusio.go | 342 ++++++++++++++++++ cmd/scollector/conf/conf.go | 1 + metadata/metadata.go | 1 + 8 files changed, 687 insertions(+) create mode 100644 cmd/scollector/collectors/statusio/componentstatus_jsonenums.go create mode 100644 cmd/scollector/collectors/statusio/incidentstatus_jsonenums.go create mode 100644 cmd/scollector/collectors/statusio/maintenancestatus_jsonenums.go create mode 100644 cmd/scollector/collectors/statusio/statusindicator_jsonenums.go create mode 100644 cmd/scollector/collectors/statusio/statusio.go diff --git a/cmd/scollector/collectors/fastly.go b/cmd/scollector/collectors/fastly.go index 420e3dc6b9..0a7345d9f0 100644 --- a/cmd/scollector/collectors/fastly.go +++ b/cmd/scollector/collectors/fastly.go @@ -7,9 +7,11 @@ import ( "net/http" "net/url" "reflect" + "regexp" "strconv" "time" + "bosun.org/cmd/scollector/collectors/statusio" "bosun.org/cmd/scollector/conf" "bosun.org/metadata" "bosun.org/opentsdb" @@ -34,6 +36,15 @@ func init() { name: "c_fastly_billing", Interval: time.Minute * 5, }) + if f.StatusBaseAddr != "" { + collectors = append(collectors, &IntervalCollector{ + F: func() (opentsdb.MultiDataPoint, error) { + return c_fastly_status(f.StatusBaseAddr) + }, + name: "c_fastly_status", + Interval: time.Minute * 1, + }) + } } }) } @@ -50,8 +61,89 @@ const ( fastlyBillingBeforeDiscountDesc = "The total incurred cost plus extras cost this month." fastlyBillingDiscountDesc = "The calculated discount rate this month." fastlyBillingCostDesc = "The final amount to be paid this month." + + fastlyStatusPrefix = "fastly.status." + fastlyComponentStatusDesc = "The current status of the %v. 0: Operational, 1: Degraded Performance, 2: Partial Outage, 3: Major Outage." // see iota for statusio.ComponentStatus + fastlyScheduledMaintDesc = "The number of currently scheduled maintenances. Does not include maintenance that is current active" + fastlyActiveScheduledMaintDesc = "The number of currently scheduled maintenances currently in progress. Includes the 'in_progress' and 'verifying'" + fastlyActiveIncidentDesc = "The number of currently active incidents. Includes the 'investingating', 'identified', and 'monitoring' states." +) + +var ( + fastlyStatusPopRegex = regexp.MustCompile(`(.*)\(([A-Z]{3})\)`) ) +func c_fastly_status(baseAddr string) (opentsdb.MultiDataPoint, error) { + var md opentsdb.MultiDataPoint + c := statusio.NewClient(baseAddr) + summary, err := c.GetSummary() + if err != nil { + return md, err + } + + // Process Components (Pops, Support Systems) + for _, comp := range summary.Components { + match := fastlyStatusPopRegex.FindAllStringSubmatch(comp.Name, 1) + if len(match) != 0 && len(match[0]) == 3 { // We have a pop + //name := match[0][1] + code := match[0][2] + tagSet := opentsdb.TagSet{"code": code} + Add(&md, fastlyStatusPrefix+"pop", int(comp.Status), tagSet, metadata.Gauge, metadata.StatusCode, fmt.Sprintf(fastlyComponentStatusDesc, "pop")) + continue + } + // Must be service component + tagSet := opentsdb.TagSet{"service": comp.Name} + Add(&md, fastlyStatusPrefix+"service", int(comp.Status), tagSet, metadata.Gauge, metadata.StatusCode, fmt.Sprintf(fastlyComponentStatusDesc, "service")) + } + + // Scheduled Maintenance + scheduledMaintByImpact := make(map[statusio.StatusIndicator]int) + activeScheduledMaintByImpact := make(map[statusio.StatusIndicator]int) + // Make Maps + for _, si := range statusio.StatusIndicatorValues { + scheduledMaintByImpact[si] = 0 + activeScheduledMaintByImpact[si] = 0 + } + // Group by scheduled vs inprogress/verifying + for _, maint := range summary.ScheduledMaintenances { + switch maint.Status { + case statusio.Scheduled: + scheduledMaintByImpact[maint.Impact]++ + case statusio.InProgress, statusio.Verifying: + activeScheduledMaintByImpact[maint.Impact]++ + } + } + for impact, count := range scheduledMaintByImpact { + tagSet := opentsdb.TagSet{"impact": fmt.Sprint(impact)} + Add(&md, fastlyStatusPrefix+"scheduled_maint_count", count, tagSet, metadata.Gauge, metadata.Count, fastlyScheduledMaintDesc) + } + for impact, count := range activeScheduledMaintByImpact { + tagSet := opentsdb.TagSet{"impact": fmt.Sprint(impact)} + Add(&md, fastlyStatusPrefix+"in_progress_maint_count", count, tagSet, metadata.Gauge, metadata.Count, fastlyActiveScheduledMaintDesc) + } + + // Incidents + // Make Map + incidentsByImpact := make(map[statusio.StatusIndicator]int) + for _, si := range statusio.StatusIndicatorValues { + incidentsByImpact[si] = 0 + } + for _, incident := range summary.Incidents { + switch incident.Status { + case statusio.Investigating, statusio.Identified, statusio.Monitoring: + incidentsByImpact[incident.Impact]++ + default: + continue + } + } + for impact, count := range incidentsByImpact { + tagSet := opentsdb.TagSet{"impact": fmt.Sprint(impact)} + Add(&md, fastlyStatusPrefix+"active_incident_count", count, tagSet, metadata.Gauge, metadata.Incident, fastlyActiveIncidentDesc) + } + + return md, nil +} + func c_fastly_billing(c fastlyClient) (opentsdb.MultiDataPoint, error) { var md opentsdb.MultiDataPoint now := time.Now().UTC() diff --git a/cmd/scollector/collectors/statusio/componentstatus_jsonenums.go b/cmd/scollector/collectors/statusio/componentstatus_jsonenums.go new file mode 100644 index 0000000000..7ab78a3d78 --- /dev/null +++ b/cmd/scollector/collectors/statusio/componentstatus_jsonenums.go @@ -0,0 +1,62 @@ +// generated by jsonenums -type=ComponentStatus; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _ComponentStatusNameToValue = map[string]ComponentStatus{ + "Operational": Operational, + "DegradedPerformance": DegradedPerformance, + "PartialOutage": PartialOutage, + "MajorOutage": MajorOutage, + } + + _ComponentStatusValueToName = map[ComponentStatus]string{ + Operational: "Operational", + DegradedPerformance: "DegradedPerformance", + PartialOutage: "PartialOutage", + MajorOutage: "MajorOutage", + } +) + +func init() { + var v ComponentStatus + if _, ok := interface{}(v).(fmt.Stringer); ok { + _ComponentStatusNameToValue = map[string]ComponentStatus{ + interface{}(Operational).(fmt.Stringer).String(): Operational, + interface{}(DegradedPerformance).(fmt.Stringer).String(): DegradedPerformance, + interface{}(PartialOutage).(fmt.Stringer).String(): PartialOutage, + interface{}(MajorOutage).(fmt.Stringer).String(): MajorOutage, + } + } +} + +// MarshalJSON is generated so ComponentStatus satisfies json.Marshaler. +func (r ComponentStatus) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _ComponentStatusValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid ComponentStatus: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so ComponentStatus satisfies json.Unmarshaler. +func (r *ComponentStatus) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("ComponentStatus should be a string, got %s", data) + } + v, ok := _ComponentStatusNameToValue[s] + if !ok { + return fmt.Errorf("invalid ComponentStatus %q", s) + } + *r = v + return nil +} diff --git a/cmd/scollector/collectors/statusio/incidentstatus_jsonenums.go b/cmd/scollector/collectors/statusio/incidentstatus_jsonenums.go new file mode 100644 index 0000000000..4b39ecbdd8 --- /dev/null +++ b/cmd/scollector/collectors/statusio/incidentstatus_jsonenums.go @@ -0,0 +1,65 @@ +// generated by jsonenums -type=IncidentStatus; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _IncidentStatusNameToValue = map[string]IncidentStatus{ + "Investigating": Investigating, + "Identified": Identified, + "Monitoring": Monitoring, + "Resolved": Resolved, + "PostMortem": PostMortem, + } + + _IncidentStatusValueToName = map[IncidentStatus]string{ + Investigating: "Investigating", + Identified: "Identified", + Monitoring: "Monitoring", + Resolved: "Resolved", + PostMortem: "PostMortem", + } +) + +func init() { + var v IncidentStatus + if _, ok := interface{}(v).(fmt.Stringer); ok { + _IncidentStatusNameToValue = map[string]IncidentStatus{ + interface{}(Investigating).(fmt.Stringer).String(): Investigating, + interface{}(Identified).(fmt.Stringer).String(): Identified, + interface{}(Monitoring).(fmt.Stringer).String(): Monitoring, + interface{}(Resolved).(fmt.Stringer).String(): Resolved, + interface{}(PostMortem).(fmt.Stringer).String(): PostMortem, + } + } +} + +// MarshalJSON is generated so IncidentStatus satisfies json.Marshaler. +func (r IncidentStatus) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _IncidentStatusValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid IncidentStatus: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so IncidentStatus satisfies json.Unmarshaler. +func (r *IncidentStatus) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("IncidentStatus should be a string, got %s", data) + } + v, ok := _IncidentStatusNameToValue[s] + if !ok { + return fmt.Errorf("invalid IncidentStatus %q", s) + } + *r = v + return nil +} diff --git a/cmd/scollector/collectors/statusio/maintenancestatus_jsonenums.go b/cmd/scollector/collectors/statusio/maintenancestatus_jsonenums.go new file mode 100644 index 0000000000..ca16501966 --- /dev/null +++ b/cmd/scollector/collectors/statusio/maintenancestatus_jsonenums.go @@ -0,0 +1,62 @@ +// generated by jsonenums -type=MaintenanceStatus; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _MaintenanceStatusNameToValue = map[string]MaintenanceStatus{ + "Scheduled": Scheduled, + "InProgress": InProgress, + "Verifying": Verifying, + "Completed": Completed, + } + + _MaintenanceStatusValueToName = map[MaintenanceStatus]string{ + Scheduled: "Scheduled", + InProgress: "InProgress", + Verifying: "Verifying", + Completed: "Completed", + } +) + +func init() { + var v MaintenanceStatus + if _, ok := interface{}(v).(fmt.Stringer); ok { + _MaintenanceStatusNameToValue = map[string]MaintenanceStatus{ + interface{}(Scheduled).(fmt.Stringer).String(): Scheduled, + interface{}(InProgress).(fmt.Stringer).String(): InProgress, + interface{}(Verifying).(fmt.Stringer).String(): Verifying, + interface{}(Completed).(fmt.Stringer).String(): Completed, + } + } +} + +// MarshalJSON is generated so MaintenanceStatus satisfies json.Marshaler. +func (r MaintenanceStatus) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _MaintenanceStatusValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid MaintenanceStatus: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so MaintenanceStatus satisfies json.Unmarshaler. +func (r *MaintenanceStatus) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("MaintenanceStatus should be a string, got %s", data) + } + v, ok := _MaintenanceStatusNameToValue[s] + if !ok { + return fmt.Errorf("invalid MaintenanceStatus %q", s) + } + *r = v + return nil +} diff --git a/cmd/scollector/collectors/statusio/statusindicator_jsonenums.go b/cmd/scollector/collectors/statusio/statusindicator_jsonenums.go new file mode 100644 index 0000000000..6caf157313 --- /dev/null +++ b/cmd/scollector/collectors/statusio/statusindicator_jsonenums.go @@ -0,0 +1,62 @@ +// generated by jsonenums -type=StatusIndicator; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _StatusIndicatorNameToValue = map[string]StatusIndicator{ + "None": None, + "Minor": Minor, + "Major": Major, + "Critical": Critical, + } + + _StatusIndicatorValueToName = map[StatusIndicator]string{ + None: "None", + Minor: "Minor", + Major: "Major", + Critical: "Critical", + } +) + +func init() { + var v StatusIndicator + if _, ok := interface{}(v).(fmt.Stringer); ok { + _StatusIndicatorNameToValue = map[string]StatusIndicator{ + interface{}(None).(fmt.Stringer).String(): None, + interface{}(Minor).(fmt.Stringer).String(): Minor, + interface{}(Major).(fmt.Stringer).String(): Major, + interface{}(Critical).(fmt.Stringer).String(): Critical, + } + } +} + +// MarshalJSON is generated so StatusIndicator satisfies json.Marshaler. +func (r StatusIndicator) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _StatusIndicatorValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid StatusIndicator: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so StatusIndicator satisfies json.Unmarshaler. +func (r *StatusIndicator) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("StatusIndicator should be a string, got %s", data) + } + v, ok := _StatusIndicatorNameToValue[s] + if !ok { + return fmt.Errorf("invalid StatusIndicator %q", s) + } + *r = v + return nil +} diff --git a/cmd/scollector/collectors/statusio/statusio.go b/cmd/scollector/collectors/statusio/statusio.go new file mode 100644 index 0000000000..89154bc810 --- /dev/null +++ b/cmd/scollector/collectors/statusio/statusio.go @@ -0,0 +1,342 @@ +package statusio + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "time" + + "bosun.org/slog" +) + +type Client struct { + baseAddr string + client *http.Client +} + +// NewClient creates a new flastly client for the *public api*. +// baseAddr is i.e. 889dh1w1xtt0.statuspage.io/api/v2/ +func NewClient(baseAddr string) *Client { + return &Client{ + baseAddr: baseAddr, + client: &http.Client{}, + } +} + +type SummaryResponse struct { + Components []Component `json:"components"` + Incidents []Incident `json:"incidents"` + Page Page `json:"page"` + ScheduledMaintenances []ScheduledMaintenance `json:"scheduled_maintenances"` + Status struct { + Description string `json:"description"` + StatusIndicator string `json:"indicator"` + } `json:"status"` +} + +// GetSummary returns a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances. +func (c *Client) GetSummary() (SummaryResponse, error) { + s := SummaryResponse{} + err := c.request("api/v2/summary.json", &s) + return s, err +} + +type StatusResponse struct { + Page Page `json:"page"` + Status struct { + Description string `json:"description"` + Indicator StatusIndicator `json:"indicator"` + } `json:"status"` +} + +// GetStatus returns rollup for the whole page. This endpoint includes an indicator - one of none, minor, major, or critical, as well as a human description of the blended component status. +// Examples of the blended status include "All Systems Operational", "Partial System Outage", and "Major Service Outage". +func (c *Client) GetStatus() (StatusResponse, error) { + s := StatusResponse{} + err := c.request("api/v2/status.json", &s) + return s, err +} + +type ComponentsResponse struct { + Components []Component `json:"components"` + Page Page `json:"page"` +} + +// GetComponents gets the components for the page. Each component is listed along with its status - one of operational, degraded_performance, partial_outage, or major_outage. +func (c *Client) GetComponents() (ComponentsResponse, error) { + comp := ComponentsResponse{} + err := c.request("api/v2/components.json", &comp) + return comp, err +} + +type IncidentsResponse struct { + Incidents []Incident `json:"incidents"` + Page Page `json:"page"` +} + +// GetUnresolvedIncidents gets a list of any unresolved incidents. +// This endpoint will only return incidents in the Investigating, Identified, or Monitoring state. +func (c *Client) GetUnresolvedIncidents() (IncidentsResponse, error) { + i := IncidentsResponse{} + err := c.request("api/v2/incidents/unresolved.json", &i) + return i, err +} + +// GetIncidents returns a list of the 50 most recent incidents. +// This includes all unresolved incidents returned in GetUnresolvedIncidents, as well as those in the Resolved and Postmortem state. +func (c *Client) GetIncidents() (IncidentsResponse, error) { + i := IncidentsResponse{} + err := c.request("api/v2/incidents.json", &i) + return i, err +} + +type ScheduledMaintenancesResponse struct { + Page Page `json:"page"` + ScheduledMaintenances []ScheduledMaintenance `json:"scheduled_maintenances"` +} + +// GetUpcomingScheduledMaintenances gets a list of any upcoming maintenances. +// This endpoint will only return scheduled maintenances still in the Scheduled state. +func (c *Client) GetUpcomingScheduledMaintenances() (ScheduledMaintenancesResponse, error) { + s := ScheduledMaintenancesResponse{} + err := c.request("api/v2/scheduled-maintenances/upcoming.json", &s) + return s, err +} + +// GetActiveScheduledMaintenances gets a list of any upcoming maintenances. // This endpoint will only return scheduled maintenances in the In Progress or Verifying state. +func (c *Client) GetActiveScheduledMaintenances() (ScheduledMaintenancesResponse, error) { + s := ScheduledMaintenancesResponse{} + err := c.request("api/v2/scheduled-maintenances/active.json", &s) + return s, err +} + +// GetAllScheduledMaintenances gets a list of the 50 most recent scheduled maintenances. +// This includes scheduled maintenances as described in the above two endpoints, as well as those in the Completed state. +func (c *Client) GetAllScheduledMaintenances() (ScheduledMaintenancesResponse, error) { + s := ScheduledMaintenancesResponse{} + err := c.request("api/v2/scheduled-maintenances.json", &s) + return s, err +} + +type NotImplemented bool + +// GetPageSubscribers is not implemented +func (c *Client) GetPageSubscribers() NotImplemented { + return true +} + +// GetIncidentSubscribers is not implemented +func (c *Client) GetIncidentSubscribers() NotImplemented { + return true +} + +// RemoveSubscription is not implemented +func (c *Client) RemoveSubscription() NotImplemented { + return true +} + +func (c *Client) request(path string, s interface{}) error { + u := &url.URL{ + Scheme: "https", + Host: c.baseAddr, + Path: path, + } + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + slog.Error(err) + return err + } + req.Header.Set("Accept", "application/json") + resp, err := c.client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + b, _ := ioutil.ReadAll(resp.Body) + return fmt.Errorf("%v: %v: %v", req.URL, resp.Status, string(b)) + } + d := json.NewDecoder(resp.Body) + if err := d.Decode(&s); err != nil { + return err + } + return nil +} + +// Page is part of all status.io public api responses. +type Page struct { + ID string `json:"id"` + Name string `json:"name"` + UpdatedAt *time.Time `json:"updated_at"` + URL string `json:"url"` +} + +type Component struct { + CreatedAt *time.Time `json:"created_at"` + Description interface{} `json:"description"` + Group bool `json:"group"` + GroupID interface{} `json:"group_id"` + ID string `json:"id"` + Name string `json:"name"` + OnlyShowIfDegraded bool `json:"only_show_if_degraded"` + PageID string `json:"page_id"` + Position int `json:"position"` + Status ComponentStatus `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type Incident struct { + CreatedAt *time.Time `json:"created_at"` + ID string `json:"id"` + Impact StatusIndicator `json:"impact"` + IncidentUpdates []IncidentUpdate `json:"incident_updates"` + MonitoringAt *time.Time `json:"monitoring_at"` + Name string `json:"name"` + PageID string `json:"page_id"` + ResolvedAt *time.Time `json:"resolved_at"` + Shortlink string `json:"shortlink"` + Status IncidentStatus `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type IncidentUpdate struct { + Body string `json:"body"` + CreatedAt *time.Time `json:"created_at"` + DisplayAt *time.Time `json:"display_at"` + ID string `json:"id"` + IncidentID string `json:"incident_id"` + Status string `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type ScheduledMaintenance struct { + CreatedAt *time.Time `json:"created_at"` + ID string `json:"id"` + Impact StatusIndicator `json:"impact"` + IncidentUpdates []IncidentUpdate `json:"incident_updates"` + MonitoringAt *time.Time `json:"monitoring_at"` + Name string `json:"name"` + PageID string `json:"page_id"` + ResolvedAt *time.Time `json:"resolved_at"` + ScheduledFor *time.Time `json:"scheduled_for"` + ScheduledUntil *time.Time `json:"scheduled_until"` + Shortlink string `json:"shortlink"` + Status MaintenanceStatus `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type ComponentStatus int + +func (c ComponentStatus) String() string { + switch c { + case 0: + return "operational" + case 1: + return "degraded_performance" + case 2: + return "partial_outage" + case 3: + return "major_outage" + } + return "UnexpectedComponentStatus" +} + +// Comments are the JSON representation +const ( + Operational ComponentStatus = iota // operational + DegradedPerformance // degraded_performance + PartialOutage // partial_outage + MajorOutage // major_outage +) + +// ComponentStatusValues represents all the possible values of the ComponetStatus iota +var ComponentStatusValues = []ComponentStatus{Operational, DegradedPerformance, PartialOutage, MajorOutage} + +// StatusIndicator is an enum used for general status and impact fields +type StatusIndicator int // ScheduledMaintenance Impact field seems to use the same enum + +func (s StatusIndicator) String() string { + switch s { + case 0: + return "none" + case 1: + return "minor" + case 2: + return "major" + case 3: + return "critical" + } + return "UnexpectedStatusIndicator" +} + +// Comments are the JSON representation +const ( + None StatusIndicator = iota // none + Minor // minor + Major // major + Critical // critical +) + +// StatusIndicatorValues represents all the possible values of the StatusIndicator iota +var StatusIndicatorValues = []StatusIndicator{None, Minor, Major, Critical} + +// IncidentStatus represents the status of an incident +type IncidentStatus int + +func (i IncidentStatus) String() string { + switch i { + case 0: + return "investigating" + case 1: + return "identified" + case 2: + return "monitoring" + case 3: + return "resolved" + case 4: + return "post_mortem" + } + return "UnexpectedIncidentStatus" +} + +// Comments are the JSON representation +const ( + Investigating IncidentStatus = iota // investigating + Identified // identified + Monitoring // monitoring + Resolved // resolved + PostMortem // post_mortem (?) Guessing, the documentation doesn't use the literals for this enum +) + +// IncidentStatusValues represents all the possible values of an incident status +var IncidenStatusValues = []IncidentStatus{Investigating, Identified, Monitoring, Resolved, PostMortem} + +// MaintenanceStatus represents the status of a maintenance operation +type MaintenanceStatus int + +func (m MaintenanceStatus) String() string { + switch m { + case 0: + return "scheduled" + case 1: + return "in_progress" + case 2: + return "verifying" + case 3: + return "completed" + } + return "UnexpectedMaintenanceStatus" +} + +// Comments are the JSON representation +const ( + Scheduled MaintenanceStatus = iota // scheduled + InProgress // in_progress (?) Guessing, the documentation doesn't use the literals for this enum + Verifying // verifying + Completed // completed +) + +// MaitenanceStatusValues represents all the possible values of the MaintenanceStatus enum +var MaintenanceStatusValues = []MaintenanceStatus{Scheduled, InProgress, Verifying, Completed} diff --git a/cmd/scollector/conf/conf.go b/cmd/scollector/conf/conf.go index 6fcd9625be..210ad26748 100644 --- a/cmd/scollector/conf/conf.go +++ b/cmd/scollector/conf/conf.go @@ -102,6 +102,7 @@ type GoogleAnalytics struct { type Fastly struct { Key string + StatusBaseAddr string } type GoogleAnalyticsSite struct { diff --git a/metadata/metadata.go b/metadata/metadata.go index 60667bf8c5..e17fb9f492 100644 --- a/metadata/metadata.go +++ b/metadata/metadata.go @@ -71,6 +71,7 @@ const ( Fraction = "fraction" Get = "gets" GetExists = "get exists" + Incident = "incidents" Interupt = "interupts" InProgress = "in progress" Item = "items"