@@ -5,9 +5,12 @@ import (
5
5
"regexp"
6
6
"strconv"
7
7
"strings"
8
+ "time"
8
9
10
+ "github.com/robfig/cron/v3"
9
11
"github.com/samber/lo"
10
12
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
13
+ "k8s.io/apimachinery/pkg/util/duration"
11
14
)
12
15
13
16
var re = regexp .MustCompile (`(?:\((\d+\.?\d*)%\))|(\d+\.?\d*)%` )
@@ -95,7 +98,10 @@ func getScrapeConfigHealth(obj *unstructured.Unstructured) (*HealthStatus, error
95
98
h = HealthUnknown
96
99
}
97
100
98
- status := & HealthStatus {Health : h }
101
+ status := & HealthStatus {
102
+ Health : h ,
103
+ Ready : true ,
104
+ }
99
105
100
106
if errorCount > 0 {
101
107
errorMsgs , _ , err := unstructured .NestedStringSlice (obj .Object , "status" , "lastRun" , "errors" )
@@ -108,6 +114,44 @@ func getScrapeConfigHealth(obj *unstructured.Unstructured) (*HealthStatus, error
108
114
}
109
115
}
110
116
117
+ if lastRunTime , _ , err := unstructured .NestedString (obj .Object , "status" , "lastRun" , "timestamp" ); err != nil {
118
+ return nil , err
119
+ } else if lastRunTime != "" {
120
+ parsedLastRuntime , err := time .Parse (time .RFC3339 , lastRunTime )
121
+ if err != nil {
122
+ return nil , fmt .Errorf ("failed to parse lastRun timestamp: %w" , err )
123
+ }
124
+
125
+ var schedule time.Duration
126
+ if scheduleRaw , _ , err := unstructured .NestedString (obj .Object , "spec" , "schedule" ); err != nil {
127
+ return nil , fmt .Errorf ("failed to parse scraper schedule: %w" , err )
128
+ } else if scheduleRaw == "" {
129
+ schedule = time .Hour // The default schedule
130
+ } else {
131
+ parsedSchedule , err := cron .ParseStandard (scheduleRaw )
132
+ if err != nil {
133
+ return & HealthStatus {
134
+ Health : HealthUnhealthy ,
135
+ Message : fmt .Sprintf ("Bad schedule: %s" , scheduleRaw ),
136
+ Ready : true ,
137
+ }, nil
138
+ }
139
+
140
+ schedule = time .Until (parsedSchedule .Next (time .Now ()))
141
+ }
142
+
143
+ elapsed := time .Since (parsedLastRuntime )
144
+ if elapsed > schedule * 2 {
145
+ status .Health = HealthUnhealthy
146
+ status .Status = "Stale"
147
+ status .Message = fmt .Sprintf ("scraper hasn't run for %s" , duration .HumanDuration (elapsed ))
148
+ } else if elapsed > schedule && status .Health != HealthUnhealthy {
149
+ status .Health = HealthWarning
150
+ status .Status = "Stale"
151
+ status .Message = fmt .Sprintf ("scraper hasn't run for %s" , duration .HumanDuration (elapsed ))
152
+ }
153
+ }
154
+
111
155
return status , nil
112
156
}
113
157
0 commit comments