Skip to content

Commit

Permalink
feat(endpoint/incident): rename caused_at/resolved_at to starts_at/en…
Browse files Browse the repository at this point in the history
…ds_at
  • Loading branch information
macrat committed Jun 25, 2022
1 parent 255f1f9 commit 11a0513
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 60 deletions.
12 changes: 6 additions & 6 deletions internal/endpoint/incidents.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ func IncidentsCSVEndpoint(s Store) http.HandlerFunc {
w.Header().Set("Access-Control-Allow-Methods", "GET")

c := csv.NewWriter(w)
c.Write([]string{"caused_at", "resolved_at", "status", "target", "message"})
c.Write([]string{"starts_at", "ends_at", "status", "target", "message"})

rs := newIncidentsInfo(s).Incidents

for _, r := range rs {
resolved := ""
if !r.ResolvedAt.IsZero() {
resolved = r.ResolvedAt.Format(time.RFC3339)
if !r.EndsAt.IsZero() {
resolved = r.EndsAt.Format(time.RFC3339)
}

c.Write([]string{
r.CausedAt.Format(time.RFC3339),
r.StartsAt.Format(time.RFC3339),
resolved,
r.Status.String(),
r.Target.String(),
Expand Down Expand Up @@ -92,10 +92,10 @@ func newIncidentsInfo(s Store) incidentsInfo {

rs := append(report.IncidentHistory, report.CurrentIncidents...)
sort.Slice(rs, func(i, j int) bool {
if rs[i].CausedAt.Equal(rs[j].CausedAt) {
if rs[i].StartsAt.Equal(rs[j].StartsAt) {
return rs[i].Target.String() < rs[j].Target.String()
}
return rs[i].CausedAt.Before(rs[j].CausedAt)
return rs[i].StartsAt.Before(rs[j].StartsAt)
})

return incidentsInfo{
Expand Down
6 changes: 3 additions & 3 deletions internal/endpoint/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ <h1>
<span class="target" aria-label="incident of '{{ .Target }}'">{{ .Target }}</span>
</h1>
<div class="period">
<time aria-label="since {{ .CausedAt | time2str }}" title="{{ .CausedAt | time2humanize }}">{{ .CausedAt | time2str }}</time>
<time aria-label="since {{ .StartsAt | time2str }}" title="{{ .StartsAt | time2humanize }}">{{ .StartsAt | time2str }}</time>
<span aria-hidden="true">-</span>
{{ if .ResolvedAt.IsZero -}}
{{ if .EndsAt.IsZero -}}
ongoing
{{- else -}}
<time aria-label="until {{ .ResolvedAt | time2str }}" title="{{ .ResolvedAt | time2humanize }}">{{ .ResolvedAt | time2str }}</time>
<time aria-label="until {{ .EndsAt | time2str }}" title="{{ .EndsAt | time2humanize }}">{{ .EndsAt | time2str }}</time>
{{- end }}
</div>{{ if .Message }}
<pre class="message">{{ .Message }}</pre>{{ end }}
Expand Down
6 changes: 3 additions & 3 deletions internal/endpoint/templates/incidents.rss
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
{{ range .Incidents }}
<item>
<guid isPermaLink="false">TODO</guid>
<pubDate>{{ .CausedAt | time2rfc822 }}</pubDate>
<pubDate>{{ .StartsAt | time2rfc822 }}</pubDate>
<title>[{{ .Status }}] {{ .Target }}</title>
<category domain="status">{{ if .ResolvedAt.IsZero }}ongoing{{ else }}{{ .ResolvedAt | time2str }}{{ end }}</category>
<category domain="status">{{ if .EndsAt.IsZero }}ongoing{{ else }}{{ .EndsAt | time2str }}{{ end }}</category>
<category domain="kind">{{ .Status | to_lower }}</category>
<link>{{ .Target }}</link>
<description><![CDATA[<b>target:</b> {{ .Target }}<br />
<b>status:</b> {{ .Status }}<br />
<b>period:</b> {{ .CausedAt | time2str }} - {{ if .ResolvedAt.IsZero }}ongoing{{ else }}{{ .ResolvedAt | time2str }}{{ end }}{{ if .Message }}<br />
<b>period:</b> {{ .StartsAt | time2str }} - {{ if .EndsAt.IsZero }}ongoing{{ else }}{{ .EndsAt | time2str }}{{ end }}{{ if .Message }}<br />
<br />
<pre>{{ .Message }}</pre>{{ end }}]]></description>
</item>{{ end }}
Expand Down
4 changes: 2 additions & 2 deletions internal/endpoint/templates/status.ascii
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
end
}} ------------------------------------------------------------------+
|{{ printf "%-78s" .Target }}|
| {{ printf "%-77s" (printf "%s - ongoing" (.CausedAt | time2str)) }}|
| {{ printf "%-77s" (printf "%s - ongoing" (.StartsAt | time2str)) }}|
| |{{ range (break_text .Message 78) }}
|{{ printf "%-78s" . }}|{{ end }}
+------------------------------------------------------------------------------+
Expand All @@ -39,7 +39,7 @@
end
}} ------------------------------------------------------------------+
|{{ printf "%-78s" .Target }}|
| {{ printf "%-77s" (printf "%s - %s" (.CausedAt | time2str) (.ResolvedAt | time2str))}}|
| {{ printf "%-77s" (printf "%s - %s" (.StartsAt | time2str) (.EndsAt | time2str))}}|
| |{{ range (break_text .Message 78) }}
|{{ printf "%-78s" . }}|{{ end }}
+------------------------------------------------------------------------------+
Expand Down
4 changes: 2 additions & 2 deletions internal/endpoint/templates/status.unicode
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
end
}} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳
┃{{ printf "%-78s" .Target }}┃
┃ {{ printf "%-77s" (printf "%s - ongoing" (.CausedAt | time2str)) }}┃
┃ {{ printf "%-77s" (printf "%s - ongoing" (.StartsAt | time2str)) }}┃
┃ ┃{{ range (break_text .Message 78) }}
┃{{ printf "%-78s" . }}┃{{ end }}
┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻
Expand All @@ -39,7 +39,7 @@
end
}} ──────────────────────────────────────────────────────────────────┐
│{{ printf "%-78s" .Target }}│
│ {{ printf "%-77s" (printf "%s - %s" (.CausedAt | time2str) (.ResolvedAt | time2str))}}│
│ {{ printf "%-77s" (printf "%s - %s" (.StartsAt | time2str) (.EndsAt | time2str))}}│
│ │{{ range (break_text .Message 78) }}
│{{ printf "%-78s" . }}│{{ end }}
└──────────────────────────────────────────────────────────────────────────────┘
Expand Down
2 changes: 1 addition & 1 deletion internal/endpoint/testdata/incidents.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
caused_at,resolved_at,status,target,message
starts_at,ends_at,status,target,message
2021-01-02T15:04:05Z,2021-01-02T15:04:06Z,FAILURE,http://b.example.com,this is failure
2021-01-02T15:04:09Z,,UNKNOWN,http://c.example.com,this is unknown
2 changes: 1 addition & 1 deletion internal/endpoint/testdata/incidents.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"incidents":[{"target":"http://b.example.com","status":"FAILURE","message":"this is failure","caused_at":"2021-01-02T15:04:05Z","resolved_at":"2021-01-02T15:04:06Z"},{"target":"http://c.example.com","status":"UNKNOWN","message":"this is unknown","caused_at":"2021-01-02T15:04:09Z"}],[[MASKED_DATA]]}
{"incidents":[{"target":"http://b.example.com","status":"FAILURE","message":"this is failure","starts_at":"2021-01-02T15:04:05Z","ends_at":"2021-01-02T15:04:06Z"},{"target":"http://c.example.com","status":"UNKNOWN","message":"this is unknown","starts_at":"2021-01-02T15:04:09Z"}],[[MASKED_DATA]]}
8 changes: 4 additions & 4 deletions internal/store/incident.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ func newIncident(r api.Record) *api.Incident {
Target: r.Target,
Status: r.Status,
Message: r.Message,
CausedAt: r.Time,
StartsAt: r.Time,
}
}

// incidentIsContinued checks if an incident is stil continued or not.
func incidentIsContinued(i *api.Incident, r api.Record) bool {
return i.ResolvedAt.IsZero() && i.Status == r.Status && i.Message == r.Message
return i.EndsAt.IsZero() && i.Status == r.Status && i.Message == r.Message
}

type byIncidentCaused []*api.Incident
Expand All @@ -26,10 +26,10 @@ func (xs byIncidentCaused) Len() int {
}

func (xs byIncidentCaused) Less(i, j int) bool {
if xs[i].CausedAt.Equal(xs[j].CausedAt) {
if xs[i].StartsAt.Equal(xs[j].StartsAt) {
return xs[i].Target.String() < xs[j].Target.String()
}
return xs[i].CausedAt.Before(xs[j].CausedAt)
return xs[i].StartsAt.Before(xs[j].StartsAt)
}

func (xs byIncidentCaused) Swap(i, j int) {
Expand Down
2 changes: 1 addition & 1 deletion internal/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func (s *Store) setIncidentIfNeed(r api.Record, needCallback bool) {
return
}

cur.ResolvedAt = r.Time
cur.EndsAt = r.Time
s.incidentHistory = append(s.incidentHistory, cur)
delete(s.currentIncidents, target)

Expand Down
52 changes: 26 additions & 26 deletions lib-ayd/incident.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ type Incident struct {

Message string

// CausedAt is the first detected time the target is unhealthy status
CausedAt time.Time
// StartsAt is the first detected time the target is unhealthy status
StartsAt time.Time

// ResolvedAt is the earliest time that detected the target back to healthy status
ResolvedAt time.Time
// EndsAt is the earliest time that detected the target back to healthy status
EndsAt time.Time
}

type jsonIncident struct {
Target string `json:"target"`
Status Status `json:"status"`
Message string `json:"message"`
CausedAt string `json:"caused_at"`
ResolvedAt string `json:"resolved_at,omitempty"`
Target string `json:"target"`
Status Status `json:"status"`
Message string `json:"message"`
StartsAt string `json:"starts_at"`
EndsAt string `json:"ends_at,omitempty"`
}

// UnmarshalJSON implements the json.Unmarshaler interface.
Expand All @@ -43,42 +43,42 @@ func (i *Incident) UnmarshalJSON(data []byte) error {
return err
}

causedAt, err := time.Parse(time.RFC3339, ji.CausedAt)
startsAt, err := time.Parse(time.RFC3339, ji.StartsAt)
if err != nil {
return err
}

var resolvedAt time.Time
if ji.ResolvedAt != "" {
resolvedAt, err = time.Parse(time.RFC3339, ji.ResolvedAt)
var endsAt time.Time
if ji.EndsAt != "" {
endsAt, err = time.Parse(time.RFC3339, ji.EndsAt)
if err != nil {
return err
}
}

*i = Incident{
Target: target,
Status: ji.Status,
Message: ji.Message,
CausedAt: causedAt,
ResolvedAt: resolvedAt,
Target: target,
Status: ji.Status,
Message: ji.Message,
StartsAt: startsAt,
EndsAt: endsAt,
}

return nil
}

// MarshalJSON implements the json.Marshaler interface.
func (i Incident) MarshalJSON() ([]byte, error) {
var resolvedAt string
if !i.ResolvedAt.IsZero() {
resolvedAt = i.ResolvedAt.Format(time.RFC3339)
var endsAt string
if !i.EndsAt.IsZero() {
endsAt = i.EndsAt.Format(time.RFC3339)
}

return json.Marshal(jsonIncident{
Target: i.Target.String(),
Status: i.Status,
Message: i.Message,
CausedAt: i.CausedAt.Format(time.RFC3339),
ResolvedAt: resolvedAt,
Target: i.Target.String(),
Status: i.Status,
Message: i.Message,
StartsAt: i.StartsAt.Format(time.RFC3339),
EndsAt: endsAt,
})
}
22 changes: 11 additions & 11 deletions lib-ayd/incident_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ func TestIncident(t *testing.T) {
t.Errorf("the message is different: %s != %s", i1.Message, i2.Message)
}

if i1.CausedAt.String() != i2.CausedAt.String() {
t.Errorf("the caused_at is different: %s != %s", i1.CausedAt, i2.CausedAt)
if i1.StartsAt.String() != i2.StartsAt.String() {
t.Errorf("the starts_at is different: %s != %s", i1.StartsAt, i2.StartsAt)
}

if i1.ResolvedAt.String() != i2.ResolvedAt.String() {
t.Errorf("the resolved_at is different: %s != %s", i1.ResolvedAt, i2.ResolvedAt)
if i1.EndsAt.String() != i2.EndsAt.String() {
t.Errorf("the ends_at is different: %s != %s", i1.EndsAt, i2.EndsAt)
}
}

t.Run("marshal-and-unmarshal", func(t *testing.T) {
i1 := ayd.Incident{
Target: &ayd.URL{Scheme: "dummy", Opaque: "failure", Fragment: "hello-world"},
Status: ayd.StatusFailure,
Message: "it's incident",
CausedAt: time.Date(2001, 1, 2, 15, 4, 5, 0, time.UTC),
ResolvedAt: time.Date(2021, 6, 5, 16, 3, 2, 0, time.UTC),
Target: &ayd.URL{Scheme: "dummy", Opaque: "failure", Fragment: "hello-world"},
Status: ayd.StatusFailure,
Message: "it's incident",
StartsAt: time.Date(2001, 1, 2, 15, 4, 5, 0, time.UTC),
EndsAt: time.Date(2021, 6, 5, 16, 3, 2, 0, time.UTC),
}

j, err := json.Marshal(i1)
Expand All @@ -55,12 +55,12 @@ func TestIncident(t *testing.T) {
})

t.Run("unmarshal", func(t *testing.T) {
source := `{"target":"dummy:failure#hello-world", "status":"FAILURE", "message":"it's incident", "caused_at":"2021-01-02T15:04:05Z"}`
source := `{"target":"dummy:failure#hello-world", "status":"FAILURE", "message":"it's incident", "starts_at":"2021-01-02T15:04:05Z"}`
expect := ayd.Incident{
Target: &ayd.URL{Scheme: "dummy", Opaque: "failure", Fragment: "hello-world"},
Status: ayd.StatusFailure,
Message: "it's incident",
CausedAt: time.Date(2021, 1, 2, 15, 4, 5, 0, time.UTC),
StartsAt: time.Date(2021, 1, 2, 15, 4, 5, 0, time.UTC),
}

var i ayd.Incident
Expand Down

0 comments on commit 11a0513

Please sign in to comment.