11package api
22
33import (
4+ "bytes"
45 "encoding/json"
56 "fmt"
7+ "strconv"
68 "strings"
79)
810
@@ -46,17 +48,18 @@ func (a AlertType) GetId() int64 {
4648
4749// AlertTrigger defines what Triggers an Alert of AlertType
4850type AlertTrigger struct {
49- ID int64
50- Name string // Unique
51- Description string
52- AutoResolve int64 `json:"autoresolveSeconds"` // Optional
53- Metric int64
54- Config string
55- OnApp bool
56- GroupID int64 // Optional
57- ServerID int64 // Optional
58- Source string
59- Version int64
51+ ID int64
52+ Name string // Unique
53+ Description string
54+ AutoResolve int64 `json:"autoresolveSeconds"` // Optional
55+ DimensionSpecs string // The dimension specs for the selected metric.
56+ Metric int64
57+ Config string
58+ OnApp bool
59+ GroupID int64 // Optional
60+ ServerID int64 // Optional
61+ Source string
62+ Version int64
6063}
6164
6265// GetId returns the id of the AlertTrigger.
@@ -161,7 +164,7 @@ func (api *Api) GetTriggers(alertTypeID int64) (string, error) {
161164}
162165
163166// CreateTrigger is used to add a new Trigger for alerts.
164- func (api * Api ) CreateTrigger (name , description , config string , alertTypeID , autoResolve , metricID , serverID , serverGroupID int64 , onApp bool ) (string , error ) {
167+ func (api * Api ) CreateTrigger (name , description , config , dimensionSpecs string , alertTypeID , autoResolve , metricID , serverID , serverGroupID int64 , onApp bool ) (string , error ) {
165168
166169 data := map [string ][]string {
167170 "name" : {name },
@@ -172,6 +175,13 @@ func (api *Api) CreateTrigger(name, description, config string, alertTypeID, aut
172175 "source" : {GetSource ()},
173176 }
174177
178+ parsedDimensionSpecs , err := ParseDimensionSpecs (dimensionSpecs )
179+ if err != nil {
180+ return "" , err
181+ }
182+
183+ data ["dimensionSpecs" ] = []string {parsedDimensionSpecs }
184+
175185 // Set the option values if they have value.
176186 if serverID != - 1 {
177187 data ["server" ] = []string {fmt .Sprintf ("%d" , serverID )}
@@ -196,12 +206,13 @@ func (api *Api) CreateTrigger(name, description, config string, alertTypeID, aut
196206func (api * Api ) UpdateTrigger (typeID int64 , trigger * AlertTrigger ) (string , error ) {
197207
198208 data := map [string ][]string {
199- "name" : {trigger .Name },
200- "description" : {trigger .Description },
201- "config" : {trigger .Config },
202- "onApp" : {fmt .Sprintf ("%t" , trigger .OnApp )},
203- "source" : {trigger .Source },
204- "version" : {fmt .Sprintf ("%d" , trigger .Version )},
209+ "name" : {trigger .Name },
210+ "description" : {trigger .Description },
211+ "dimensionSpecs" : {trigger .DimensionSpecs },
212+ "config" : {trigger .Config },
213+ "onApp" : {fmt .Sprintf ("%t" , trigger .OnApp )},
214+ "source" : {trigger .Source },
215+ "version" : {fmt .Sprintf ("%d" , trigger .Version )},
205216 }
206217
207218 // Set the option values if they have value.
@@ -267,3 +278,75 @@ func ParseHandle(handle string) (string, error) {
267278 jsonHandle , err := json .Marshal (result )
268279 return string (jsonHandle ), err
269280}
281+
282+ // ParseDimensionSpecs is used to parse the dimensions specs for a metric.
283+ func ParseDimensionSpecs (format string ) (string , error ) {
284+ var js interface {}
285+ // Check if the specs are already provided in JSON format.
286+ if err := json .Unmarshal ([]byte (format ), & js ); err == nil {
287+ return format , nil
288+ }
289+ var buffer bytes.Buffer
290+
291+ formatParts := strings .Split (format , ";" )
292+
293+ buffer .WriteString ("[" )
294+ for i , formatPart := range formatParts {
295+ if i > 0 {
296+ buffer .WriteString ("," )
297+ }
298+ buffer .WriteString ("[" )
299+
300+ elements := strings .Split (formatPart , ":" )
301+
302+ var dimPart , dimValsPart , aggregatorPart string
303+ if len (elements ) == 2 {
304+ dimPart = elements [0 ]
305+ dimValsPart = elements [1 ]
306+ } else if len (elements ) == 3 {
307+ dimPart = elements [0 ]
308+ aggregatorPart = strings .ToUpper (elements [1 ])
309+ dimValsPart = elements [2 ]
310+ } else {
311+ return "" , fmt .Errorf ("Failed to parse dimension specs format: %s" , formatPart )
312+ }
313+
314+ if len (dimPart ) == 0 || len (dimValsPart ) == 0 {
315+ return "" , fmt .Errorf ("Failed to parse dimension specs format: %s" , formatPart )
316+ }
317+
318+ dimID , err := strconv .ParseInt (dimPart , 10 , 64 )
319+ if err != nil {
320+ return "" , fmt .Errorf ("Failed to parse dimension specs format: %s" , formatPart )
321+ }
322+ buffer .WriteString (fmt .Sprintf (`%d,"` , dimID ))
323+
324+ // Just check if is valid format.
325+ if dimValsPart != "*" {
326+ for _ , dimVal := range strings .Split (dimValsPart , "," ) {
327+ _ , err := strconv .ParseInt (dimVal , 10 , 64 )
328+ if err != nil {
329+ return "" , fmt .Errorf ("Failed to parse dimension values ids: %s" , formatPart )
330+ }
331+ }
332+ }
333+
334+ if len (aggregatorPart ) > 0 {
335+ buffer .WriteString (aggregatorPart )
336+ buffer .WriteString ("(" )
337+ buffer .WriteString (dimValsPart )
338+ buffer .WriteString (")" )
339+ } else {
340+ buffer .WriteString (dimValsPart )
341+ }
342+ buffer .WriteString (`"]` )
343+ }
344+ buffer .WriteString ("]" )
345+
346+ // Check the format is valid.
347+ if err := json .Unmarshal ([]byte (buffer .Bytes ()), & js ); err != nil {
348+ return "" , err
349+ }
350+
351+ return buffer .String (), nil
352+ }
0 commit comments