Skip to content

Commit 34d00d8

Browse files
Merge pull request #418 from SumoLogic/feature/SUMO-191578-monitor-configurable-resolution-window-support
SUMO-191578, Added configurable resolution window field on triggers a…
2 parents a01b107 + 565de12 commit 34d00d8

File tree

6 files changed

+79
-45
lines changed

6 files changed

+79
-45
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
## 2.19.1 (Unreleased)
2+
FEATURES:
3+
* Add new optional `resolution_window` field to resource/sumologic_monitor (GH-418)
24

35
## 2.19.0 (September 20, 2022)
46
FEATURES:

sumologic/resource_sumologic_monitors_library_monitor.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ func resourceSumologicMonitorsLibraryMonitor() *schema.Resource {
127127
"LogsMissingDataCondition", "MetricsMissingDataCondition", "SloSliCondition",
128128
"SloBurnRateCondition"}, false),
129129
},
130+
"resolution_window": {
131+
Type: schema.TypeString,
132+
Optional: true,
133+
ValidateFunc: validation.StringMatch(regexp.MustCompile(`-?(\d)+[smhd]`), "Time range must be in the format '-?\\d+[smhd]'. Examples: -15m, 1d, etc."),
134+
},
130135
},
131136
},
132137
},
@@ -381,8 +386,9 @@ var logsStaticTriggerConditionSchema = map[string]*schema.Schema{
381386
"threshold_type": &thresholdTypeSchema,
382387
}),
383388
"resolution": nested(false, schemaMap{
384-
"threshold": &thresholdSchema,
385-
"threshold_type": &thresholdTypeSchema,
389+
"threshold": &thresholdSchema,
390+
"threshold_type": &thresholdTypeSchema,
391+
"resolution_window": &timeRangeSchema,
386392
}),
387393
}),
388394
"warning": nested(true, schemaMap{
@@ -392,8 +398,9 @@ var logsStaticTriggerConditionSchema = map[string]*schema.Schema{
392398
"threshold_type": &thresholdTypeSchema,
393399
}),
394400
"resolution": nested(false, schemaMap{
395-
"threshold": &thresholdSchema,
396-
"threshold_type": &thresholdTypeSchema,
401+
"threshold": &thresholdSchema,
402+
"threshold_type": &thresholdTypeSchema,
403+
"resolution_window": &timeRangeSchema,
397404
}),
398405
}),
399406
}
@@ -642,6 +649,7 @@ func resourceSumologicMonitorsLibraryMonitorRead(d *schema.ResourceData, meta in
642649
d.Set("alert_name", monitor.AlertName)
643650
d.Set("slo_id", monitor.SloID)
644651
d.Set("notification_group_fields", monitor.NotificationGroupFields)
652+
645653
// set notifications
646654
notifications := make([]interface{}, len(monitor.Notifications))
647655
for i, n := range monitor.Notifications {
@@ -706,13 +714,14 @@ func resourceSumologicMonitorsLibraryMonitorRead(d *schema.ResourceData, meta in
706714
triggers := make([]interface{}, len(monitor.Triggers))
707715
for i, t := range monitor.Triggers {
708716
triggers[i] = map[string]interface{}{
709-
"time_range": t.PositiveTimeRange(),
710-
"trigger_type": t.TriggerType,
711-
"threshold": t.Threshold,
712-
"threshold_type": t.ThresholdType,
713-
"occurrence_type": t.OccurrenceType,
714-
"trigger_source": t.TriggerSource,
715-
"detection_method": t.DetectionMethod,
717+
"time_range": t.PositiveTimeRange(),
718+
"trigger_type": t.TriggerType,
719+
"threshold": t.Threshold,
720+
"threshold_type": t.ThresholdType,
721+
"occurrence_type": t.OccurrenceType,
722+
"trigger_source": t.TriggerSource,
723+
"detection_method": t.DetectionMethod,
724+
"resolution_window": t.PositiveResolutionWindow(),
716725
}
717726
}
718727
if err := d.Set("triggers", triggers); err != nil {
@@ -862,13 +871,14 @@ func getTriggers(d *schema.ResourceData) []TriggerCondition {
862871
for i := range rawTriggers {
863872
triggerDict := rawTriggers[i].(map[string]interface{})
864873
triggers[i] = TriggerCondition{
865-
TriggerType: triggerDict["trigger_type"].(string),
866-
Threshold: triggerDict["threshold"].(float64),
867-
ThresholdType: triggerDict["threshold_type"].(string),
868-
TimeRange: triggerDict["time_range"].(string),
869-
OccurrenceType: triggerDict["occurrence_type"].(string),
870-
TriggerSource: triggerDict["trigger_source"].(string),
871-
DetectionMethod: triggerDict["detection_method"].(string),
874+
TriggerType: triggerDict["trigger_type"].(string),
875+
Threshold: triggerDict["threshold"].(float64),
876+
ThresholdType: triggerDict["threshold_type"].(string),
877+
TimeRange: triggerDict["time_range"].(string),
878+
OccurrenceType: triggerDict["occurrence_type"].(string),
879+
TriggerSource: triggerDict["trigger_source"].(string),
880+
DetectionMethod: triggerDict["detection_method"].(string),
881+
ResolutionWindow: triggerDict["resolution_window"].(string),
872882
}
873883
}
874884
return triggers
@@ -1073,6 +1083,7 @@ func jsonToLogsStaticConditionBlock(conditions []TriggerCondition) map[string]in
10731083
criticalDict["time_range"] = condition.PositiveTimeRange()
10741084
criticalRslv["threshold"] = condition.Threshold
10751085
criticalRslv["threshold_type"] = condition.ThresholdType
1086+
criticalRslv["resolution_window"] = condition.PositiveResolutionWindow()
10761087
case "Warning":
10771088
hasWarning = true
10781089
warningDict["time_range"] = condition.PositiveTimeRange()
@@ -1083,6 +1094,7 @@ func jsonToLogsStaticConditionBlock(conditions []TriggerCondition) map[string]in
10831094
warningDict["time_range"] = condition.PositiveTimeRange()
10841095
warningRslv["threshold"] = condition.Threshold
10851096
warningRslv["threshold_type"] = condition.ThresholdType
1097+
warningRslv["resolution_window"] = condition.PositiveResolutionWindow()
10861098
}
10871099
}
10881100
if !hasCritical {
@@ -1443,6 +1455,8 @@ func (condition *TriggerCondition) readFrom(block map[string]interface{}) {
14431455
condition.SLIThreshold = v.(float64)
14441456
case "burn_rate_threshold":
14451457
condition.BurnRateThreshold = v.(float64)
1458+
case "resolution_window":
1459+
condition.ResolutionWindow = v.(string)
14461460
default:
14471461
}
14481462
}
@@ -1574,5 +1588,9 @@ func (t *TriggerCondition) PositiveBaselineWindow() string {
15741588
return strings.TrimPrefix(t.BaselineWindow, "-")
15751589
}
15761590

1591+
func (t *TriggerCondition) PositiveResolutionWindow() string {
1592+
return strings.TrimPrefix(t.ResolutionWindow, "-")
1593+
}
1594+
15771595
type schemaMap = map[string]*schema.Schema
15781596
type dict = map[string]interface{}

sumologic/resource_sumologic_monitors_library_monitor_test.go

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,14 @@ func TestAccSumologicMonitorsLibraryMonitor_create(t *testing.T) {
156156
DetectionMethod: "StaticCondition",
157157
},
158158
{
159-
ThresholdType: "LessThanOrEqual",
160-
Threshold: 40.0,
161-
TimeRange: "15m",
162-
OccurrenceType: "ResultCount",
163-
TriggerSource: "AllResults",
164-
TriggerType: "ResolvedCritical",
165-
DetectionMethod: "StaticCondition",
159+
ThresholdType: "LessThanOrEqual",
160+
Threshold: 40.0,
161+
TimeRange: "15m",
162+
OccurrenceType: "ResultCount",
163+
TriggerSource: "AllResults",
164+
TriggerType: "ResolvedCritical",
165+
DetectionMethod: "StaticCondition",
166+
ResolutionWindow: "5m",
166167
},
167168
}
168169
recipients := []string{"[email protected]"}
@@ -211,6 +212,7 @@ func TestAccSumologicMonitorsLibraryMonitor_create(t *testing.T) {
211212
resource.TestCheckResourceAttr("sumologic_monitor.test", "queries.0.row_id", testQueries[0].RowID),
212213
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.0.trigger_type", testTriggers[0].TriggerType),
213214
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.0.time_range", testTriggers[0].TimeRange),
215+
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.1.resolution_window", testTriggers[1].ResolutionWindow),
214216
resource.TestCheckResourceAttr("sumologic_monitor.test", "notifications.0.notification.0.connection_type", testNotifications[0].Notification.(EmailNotification).ConnectionType),
215217
resource.TestCheckResourceAttr("sumologic_monitor.test", "alert_name", testAlertName),
216218
resource.TestCheckResourceAttr("sumologic_monitor.test", "notification_group_fields.0", testGroupFields[0]),
@@ -278,13 +280,14 @@ func TestAccSumologicMonitorsLibraryMonitor_update(t *testing.T) {
278280
DetectionMethod: "StaticCondition",
279281
},
280282
{
281-
ThresholdType: "LessThanOrEqual",
282-
Threshold: 40.0,
283-
TimeRange: "15m",
284-
OccurrenceType: "ResultCount",
285-
TriggerSource: "AllResults",
286-
TriggerType: "ResolvedCritical",
287-
DetectionMethod: "StaticCondition",
283+
ThresholdType: "LessThanOrEqual",
284+
Threshold: 40.0,
285+
TimeRange: "15m",
286+
OccurrenceType: "ResultCount",
287+
TriggerSource: "AllResults",
288+
TriggerType: "ResolvedCritical",
289+
DetectionMethod: "StaticCondition",
290+
ResolutionWindow: "5m",
288291
},
289292
}
290293
recipients := []string{"[email protected]"}
@@ -339,13 +342,14 @@ func TestAccSumologicMonitorsLibraryMonitor_update(t *testing.T) {
339342
DetectionMethod: "StaticCondition",
340343
},
341344
{
342-
ThresholdType: "LessThanOrEqual",
343-
Threshold: 40.0,
344-
TimeRange: "30m",
345-
OccurrenceType: "ResultCount",
346-
TriggerSource: "AllResults",
347-
TriggerType: "ResolvedCritical",
348-
DetectionMethod: "StaticCondition",
345+
ThresholdType: "LessThanOrEqual",
346+
Threshold: 40.0,
347+
TimeRange: "30m",
348+
OccurrenceType: "ResultCount",
349+
TriggerSource: "AllResults",
350+
TriggerType: "ResolvedCritical",
351+
DetectionMethod: "StaticCondition",
352+
ResolutionWindow: "15m",
349353
},
350354
}
351355
updatedRecipients := []string{"[email protected]"}
@@ -394,6 +398,7 @@ func TestAccSumologicMonitorsLibraryMonitor_update(t *testing.T) {
394398
resource.TestCheckResourceAttr("sumologic_monitor.test", "queries.0.row_id", testQueries[0].RowID),
395399
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.0.trigger_type", testTriggers[0].TriggerType),
396400
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.0.time_range", testTriggers[0].TimeRange),
401+
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.1.resolution_window", testTriggers[1].ResolutionWindow),
397402
resource.TestCheckResourceAttr("sumologic_monitor.test", "notifications.0.notification.0.connection_type", testNotifications[0].Notification.(EmailNotification).ConnectionType),
398403
resource.TestCheckResourceAttr("sumologic_monitor.test", "playbook", testPlaybook),
399404
resource.TestCheckResourceAttr("sumologic_monitor.test", "alert_name", testAlertName),
@@ -416,6 +421,7 @@ func TestAccSumologicMonitorsLibraryMonitor_update(t *testing.T) {
416421
resource.TestCheckResourceAttr("sumologic_monitor.test", "queries.0.row_id", testUpdatedQueries[0].RowID),
417422
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.0.trigger_type", testUpdatedTriggers[0].TriggerType),
418423
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.0.time_range", testUpdatedTriggers[0].TimeRange),
424+
resource.TestCheckResourceAttr("sumologic_monitor.test", "triggers.1.resolution_window", testUpdatedTriggers[1].ResolutionWindow),
419425
resource.TestCheckResourceAttr("sumologic_monitor.test", "notifications.0.notification.0.connection_type", testUpdatedNotifications[0].Notification.(EmailNotification).ConnectionType),
420426
resource.TestCheckResourceAttr("sumologic_monitor.test", "playbook", testUpdatedPlaybook),
421427
resource.TestCheckResourceAttr("sumologic_monitor.test", "alert_name", testUpdatedAlertName),
@@ -482,7 +488,7 @@ func TestAccSumologicMonitorsLibraryMonitor_driftingCorrectionFGP(t *testing.T)
482488
})
483489
}
484490

485-
func TestAccSumologicMonitorsLibraryMonitor_update_folder(t *testing.T) {
491+
func TestAccSumologicMonitorsLibraryMonitor_folder_update(t *testing.T) {
486492
var monitorsLibraryMonitor MonitorsLibraryMonitor
487493
testNameSuffix := acctest.RandString(16)
488494

@@ -670,6 +676,7 @@ resource "sumologic_monitor" "test" {
670676
trigger_source = "AllResults"
671677
trigger_type = "ResolvedCritical"
672678
detection_method = "StaticCondition"
679+
resolution_window = "5m"
673680
}
674681
notifications {
675682
notification {
@@ -755,6 +762,7 @@ resource "sumologic_monitor" "test" {
755762
trigger_source = "AllResults"
756763
trigger_type = "ResolvedCritical"
757764
detection_method = "StaticCondition"
765+
resolution_window = "15m"
758766
}
759767
notifications {
760768
notification {
@@ -960,6 +968,7 @@ var exampleLogsStaticTriggerConditionBlock = `
960968
resolution {
961969
threshold = 90
962970
threshold_type = "LessThanOrEqual"
971+
resolution_window = "15m"
963972
}
964973
}
965974
field = "field"

sumologic/sumologic_monitors_library_folder.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package sumologic
33
import (
44
"encoding/json"
55
"fmt"
6-
"log"
76
)
87

98
// ---------- ENDPOINTS ----------
@@ -26,7 +25,7 @@ func (s *Client) CreateMonitorsLibraryFolder(monitorsLibraryFolder MonitorsLibra
2625
if err != nil {
2726
return "", err
2827
}
29-
log.Printf("created monitor response: %v", data)
28+
//log.Printf("created monitor response: %v", data)
3029

3130
var createdMonitorsLibraryFolder MonitorsLibraryFolder
3231

sumologic/sumologic_monitors_library_monitor.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package sumologic
33
import (
44
"encoding/json"
55
"fmt"
6-
"log"
76
)
87

98
// ---------- ENDPOINTS ----------
@@ -26,8 +25,7 @@ func (s *Client) CreateMonitorsLibraryMonitor(monitorsLibraryMonitor MonitorsLib
2625
if err != nil {
2726
return "", err
2827
}
29-
log.Printf("created monitor response: %v", data)
30-
28+
3129
var createdMonitorsLibraryMonitor MonitorsLibraryMonitor
3230

3331
err = json.Unmarshal(data, &createdMonitorsLibraryMonitor)
@@ -166,6 +164,7 @@ type TriggerCondition struct {
166164
OccurrenceType string `json:"occurrenceType"`
167165
TriggerSource string `json:"triggerSource"`
168166
DetectionMethod string `json:"detectionMethod"`
167+
ResolutionWindow string `json:"resolutionWindow,omitempty"`
169168
Field string `json:"field,omitempty"`
170169
Window int `json:"window,omitempty"`
171170
BaselineWindow string `json:"baselineWindow,omitempty"`

website/docs/r/monitor.html.markdown

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ resource "sumologic_monitor" "tf_logs_monitor_2" {
259259
resolution {
260260
threshold = 40.0
261261
threshold_type = "LessThanOrEqual"
262+
resolution_window = "5m"
262263
}
263264
}
264265
}
@@ -317,6 +318,7 @@ The following arguments are supported:
317318
- `slo_id` - (Optional) Identifier of the SLO definition for the monitor. This is only applicable & required for Slo `monitor_type`.
318319
- `queries` - (Required) All queries from the monitor.
319320
- `trigger_conditions` - (Required if not using `triggers`) Defines the conditions of when to send notifications. NOTE: `trigger_conditions` supplants the `triggers` argument.
321+
- `resolution_window` - The resolution window that the recovery condition must be met in each evaluation that happens within this entire duration before the alert is recovered (resolved). If not specified, the time range of your trigger will be used.
320322
- `triggers` - (Deprecated) Defines the conditions of when to send notifications.
321323
- `notifications` - (Optional) The notifications the monitor will send when the respective trigger condition is met.
322324
- `group_notifications` - (Optional) Whether or not to group notifications for individual items that meet the trigger condition. Defaults to true.
@@ -360,6 +362,7 @@ trigger_conditions {
360362
resolution {
361363
threshold = 90
362364
threshold_type = "LessThanOrEqual"
365+
resolution_window = "5m"
363366
}
364367
}
365368
warning {
@@ -371,6 +374,7 @@ trigger_conditions {
371374
resolution {
372375
threshold = 75
373376
threshold_type = "LessThanOrEqual"
377+
resolution_window = "5m"
374378
}
375379
}
376380
}
@@ -403,6 +407,7 @@ Here is a summary of arguments for each condition type (fields which are not mar
403407
- `resolution` (Required)
404408
- `threshold`
405409
- `threshold_type`
410+
- `resolution_window`
406411
- `warning`
407412
- `time_range` (Required)
408413
- `alert` (Required)
@@ -411,6 +416,7 @@ Here is a summary of arguments for each condition type (fields which are not mar
411416
- `resolution` (Required)
412417
- `threshold`
413418
- `threshold_type`
419+
- `resolution_window`
414420
#### metrics_static_condition
415421
- `critical`
416422
- `time_range` (Required)
@@ -501,6 +507,7 @@ resource "sumologic_monitor" "tf_logs_monitor_1" {
501507
trigger_source = "AllResults"
502508
trigger_type = "ResolvedCritical"
503509
detection_method = "StaticCondition"
510+
resolution_window = "5m"
504511
}
505512
notifications {
506513
notification {

0 commit comments

Comments
 (0)