Skip to content

Commit 9e9c6a1

Browse files
authored
Experimental: increase max frequency to 1 hour (#645)
Allow the maximum interval between successive check runs to be up to 1 hour. This will break some dashboards, because there are built-in assumptions about the maximum value being 2 minutes. In particular, it's going to be necessary to adjust the value we use for ranges, which is hard-coded to 5 minutes. If we change the queries, we still need to adjust values in Grafana, to prevent sampling values at intervals less than the frequency. This is going to be particularly visible in queries that use `increase`, `rate` and similar functions. Because of that, this is mostly about adding backend support for [issue #318](grafana/synthetic-monitoring-app#318). Signed-off-by: Marcelo E. Magallon <[email protected]>
1 parent 2d5af37 commit 9e9c6a1

File tree

2 files changed

+65
-37
lines changed

2 files changed

+65
-37
lines changed

pkg/pb/synthetic_monitoring/checks_extra.go

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"strings"
3131
"time"
3232

33+
"golang.org/x/exp/constraints"
3334
"golang.org/x/net/http/httpguts"
3435
)
3536

@@ -140,10 +141,18 @@ const (
140141
MaxMultiHttpVariables = 5 // Max variables per multi-http target.
141142

142143
// Frequencies (in milliseconds)
143-
MaxCheckFrequency = 120 * 1000 // Maximum value for the check's frequency.
144-
minCheckFrequency = 1 * 1000 // Minimum default value for the check's frequency.
145-
minTracerouteFrequency = 120 * 1000 // Minimum value for the traceroute check's frequency.
146-
minK6Frequency = 60 * 1000 // Minimum value for k6-class check's frequency.
144+
MaxCheckFrequency = 1 * 60 * 60 * 1000 // Maximum value for the check's frequency (1 hour).
145+
minCheckFrequency = 1 * 1000 // Minimum default value for the check's frequency (1 second).
146+
minTracerouteFrequency = 120 * 1000 // Minimum value for the traceroute check's frequency (2 min).
147+
minK6Frequency = 60 * 1000 // Minimum value for k6-class check's frequency (1 min).
148+
149+
// Timeouts (in milliseconds)
150+
minCheckTimeout = minCheckFrequency
151+
MaxCheckTimeout = 1 * 60 * 1000 // Maximum value for the check's timeout (1 minute).
152+
minScriptedTimeout = minCheckTimeout // Minimum timeout for scripted checks (1 second).
153+
maxScriptedTimeout = MaxCheckTimeout // Maximum timeout for scripted checks (1 minute).
154+
minTracerouteTimeout = 30 * 1000 // Minimum timeout for traceroute checks (30 second).
155+
maxTracerouteTimeout = 30 * 1000 // Minimum timeout for traceroute checks (30 second).
147156
)
148157

149158
type validatable interface {
@@ -316,57 +325,51 @@ func (c Check) validateTarget() error {
316325
}
317326

318327
func (c Check) validateFrequency() error {
319-
// All checks have a maximum frequency of MaxCheckFrequency.
320-
if c.Frequency > MaxCheckFrequency {
321-
return ErrInvalidCheckFrequency
322-
}
328+
var (
329+
minFrequency int64 = minCheckFrequency
330+
maxFrequency int64 = MaxCheckFrequency
331+
)
323332

324-
// Different check types have different minimum allowed values for the frequency.
333+
// Some check types have different allowed values for the frequency.
325334

326335
switch c.Type() {
327336
case CheckTypeTraceroute:
328-
if c.Frequency < minTracerouteFrequency {
329-
return ErrInvalidCheckFrequency
330-
}
337+
minFrequency = minTracerouteFrequency
331338

332339
case CheckTypeScripted, CheckTypeMultiHttp:
333-
if c.Frequency < minK6Frequency {
334-
return ErrInvalidCheckFrequency
335-
}
340+
minFrequency = minK6Frequency
341+
}
336342

337-
default:
338-
if c.Frequency < minCheckFrequency {
339-
return ErrInvalidCheckFrequency
340-
}
343+
if !inClosedRange(c.Frequency, minFrequency, maxFrequency) {
344+
return ErrInvalidCheckFrequency
341345
}
342346

343347
return nil
344348
}
345349

346350
func (c Check) validateTimeout() error {
351+
var minTimeout, maxTimeout int64
352+
347353
switch {
348354
case c.Settings.Traceroute != nil:
349-
// We are hardcoding traceroute frequency and timeout until we can get data on what the boundaries should be
350-
if c.Timeout != 30*1000 {
351-
return ErrInvalidCheckTimeout
352-
}
355+
minTimeout, maxTimeout = minTracerouteTimeout, min(c.Frequency, maxTracerouteTimeout)
353356

354-
case c.Settings.Scripted != nil || c.Settings.Multihttp != nil:
355-
// This is expirimental. A 30 second timeout means we have more
356-
// checks lingering around. timeout must be in [1, 30] seconds,
357-
// and it must be less than frequency (otherwise we can end up
358-
// running overlapping checks)
359-
if c.Timeout < 1*1000 || c.Timeout > 30*1000 || c.Timeout > c.Frequency {
360-
return ErrInvalidCheckTimeout
361-
}
362-
363-
default:
364-
// timeout must be in [1, 10] seconds, and it must be less than
357+
case c.Settings.Scripted != nil, c.Settings.Multihttp != nil:
358+
// This is experimental. A large timeout means we have more
359+
// checks lingering around. timeout must be less or equal than
365360
// frequency (otherwise we can end up running overlapping
366361
// checks)
367-
if c.Timeout < 1*1000 || c.Timeout > 10*1000 || c.Timeout > c.Frequency {
368-
return ErrInvalidCheckTimeout
369-
}
362+
minTimeout, maxTimeout = minScriptedTimeout, min(c.Frequency, maxScriptedTimeout)
363+
364+
default:
365+
// timeout must be within the defined limits, and it must be
366+
// less than frequency (otherwise we can end up running
367+
// overlapping checks)
368+
minTimeout, maxTimeout = minCheckTimeout, min(c.Frequency, MaxCheckTimeout)
369+
}
370+
371+
if !inClosedRange(c.Timeout, minTimeout, maxTimeout) {
372+
return ErrInvalidCheckTimeout
370373
}
371374

372375
return nil
@@ -1399,3 +1402,8 @@ func validateDnsLabel(label string, isLast bool) error {
13991402

14001403
return nil
14011404
}
1405+
1406+
// inClosedRange returns true if the value `v` is in [lower, upper].
1407+
func inClosedRange[T constraints.Ordered](v, lower, upper T) bool {
1408+
return v >= lower && v <= upper
1409+
}

pkg/pb/synthetic_monitoring/checks_extra_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,3 +2029,23 @@ func TestMultiHttpSettingsValidate(t *testing.T) {
20292029
},
20302030
})
20312031
}
2032+
2033+
func TestInClosedRange(t *testing.T) {
2034+
testcases := map[string]struct {
2035+
value int64
2036+
lower int64
2037+
upper int64
2038+
expected bool
2039+
}{
2040+
"too low": {value: 0, lower: 1, upper: 5, expected: false},
2041+
"lower bound": {value: 1, lower: 1, upper: 5, expected: true},
2042+
"in range": {value: 3, lower: 1, upper: 5, expected: true},
2043+
"upper bound": {value: 5, lower: 1, upper: 5, expected: true},
2044+
"too high": {value: 6, lower: 1, upper: 5, expected: false},
2045+
}
2046+
2047+
for name, tc := range testcases {
2048+
actual := inClosedRange(tc.value, tc.lower, tc.upper)
2049+
require.Equalf(t, tc.expected, actual, `%s`, name)
2050+
}
2051+
}

0 commit comments

Comments
 (0)