Skip to content

Commit

Permalink
feat: add fields to BigPanda alert
Browse files Browse the repository at this point in the history
  • Loading branch information
rhajek committed Dec 17, 2020
1 parent 78c9515 commit b7f14b8
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 17 deletions.
4 changes: 3 additions & 1 deletion alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,9 @@ func newAlertNode(et *ExecutingTask, n *pipeline.AlertNode, d NodeDiagnostic) (a

for _, s := range n.BigPandaHandlers {
c := bigpanda.HandlerConfig{
AppKey: s.AppKey,
AppKey: s.AppKey,
PrimaryProperty: s.PrimaryProperty,
SecondaryProperty: s.SecondaryProperty,
}
h, err := et.tm.BigPandaService.Handler(c, ctx...)
if err != nil {
Expand Down
13 changes: 11 additions & 2 deletions pipeline/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,7 @@ type DiscordHandler struct {
// enabled = true
// app-key = "my-app-key"
// token = "your-api-key"
// url = "BigPanda alert webhook url"
//
// In order to not post a message every alert interval
// use AlertNode.StateChangesOnly so that only events
Expand All @@ -1654,11 +1655,13 @@ type DiscordHandler struct {
// |alert()
// .bigPanda()
// .appKey('my-application')
// .primaryProperty('property1')
// .secondaryProperty('property2')
//
// send alerts with custom appKey
// send alerts with custom appKey, primary and secondary property
//
// If the 'bigpanda' section in the configuration has the option: global = true
// then all alerts are sent to BigpPanda without the need to explicitly state it
// then all alerts are sent to BigPanda without the need to explicitly state it
// in the TICKscript.
//
// Example:
Expand Down Expand Up @@ -1690,6 +1693,12 @@ type BigPandaHandler struct {
// Application id
// If empty uses the default config
AppKey string `json:"app-key"`

// Custom primary BigPanda property
PrimaryProperty string `json:"primary-property"`

// Custom secondary BigPanda property
SecondaryProperty string `json:"secondary-property"`
}

// Send the alert to Telegram.
Expand Down
13 changes: 8 additions & 5 deletions services/bigpanda/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Config struct {
// Whether BigPanda integration is enabled.
Enabled bool `toml:"enabled" override:"enabled"`

// Whether all alerts should automatically post to Teams.
// Whether all alerts should automatically post to BigPanda.
Global bool `toml:"global" override:"global"`

//Each integration must have an App Key in BigPanda to identify it as a unique source.
Expand All @@ -29,17 +29,20 @@ type Config struct {
// Whether to skip the tls verification of the alerta host
InsecureSkipVerify bool `toml:"insecure-skip-verify" override:"insecure-skip-verify"`

//Optional alert api URL, if not specified https://api.bigpanda.io/data/v2/alerts is used
// BigPanda Alert webhook URL,
// https://api.bigpanda.io/data/v2/alerts
URL string `toml:"url" override:"url"`
}

func NewConfig() Config {
return Config{
URL: defaultBigPandaAlertApi,
}
return Config{}
}

func (c Config) Validate() error {
if c.Enabled && c.URL == "" {
return errors.New("must specify the BigPanda webhook URL")
}

if c.Enabled && c.AppKey == "" {
return errors.New("must specify BigPanda app-key")
}
Expand Down
46 changes: 37 additions & 9 deletions services/bigpanda/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,14 @@ func (s *Service) Test(options interface{}) error {
if !ok {
return fmt.Errorf("unexpected options type %T", options)
}
return s.Alert(o.AppKey, "", o.Message, "", o.Level, o.Timestamp, o.Data)
hc := &HandlerConfig{
AppKey: o.AppKey,
}
return s.Alert("", o.Message, "", o.Level, o.Timestamp, o.Data, hc)
}

func (s *Service) Alert(appKey, id string, message string, details string, level alert.Level, timestamp time.Time, data alert.EventData) error {
req, err := s.preparePost(appKey, id, message, details, level, timestamp, data)
func (s *Service) Alert(id string, message string, details string, level alert.Level, timestamp time.Time, data alert.EventData, hc *HandlerConfig) error {
req, err := s.preparePost(id, message, details, level, timestamp, data, hc)

if err != nil {
return err
Expand Down Expand Up @@ -173,7 +176,7 @@ curl -X POST -H "Content-Type: application/json" \
"primary_property": "application",
"secondary_property": "host"
*/
func (s *Service) preparePost(appKey, id string, message string, details string, level alert.Level, timestamp time.Time, data alert.EventData) (*http.Request, error) {
func (s *Service) preparePost(id string, message string, details string, level alert.Level, timestamp time.Time, data alert.EventData, hc *HandlerConfig) (*http.Request, error) {
c := s.config()
if !c.Enabled {
return nil, errors.New("service is not enabled")
Expand Down Expand Up @@ -215,10 +218,19 @@ func (s *Service) preparePost(appKey, id string, message string, details string,
bpData["timestamp"] = timestamp.Unix()
bpData["status"] = status

if appKey == "" {
appKey = c.AppKey
// primary and secondary property
if hc.PrimaryProperty != "" {
bpData["primary_property"] = hc.PrimaryProperty
}
if hc.SecondaryProperty != "" {
bpData["secondary_property"] = hc.SecondaryProperty
}

if hc.AppKey != "" {
bpData["app_key"] = hc.AppKey
} else {
bpData["app_key"] = c.AppKey
}
bpData["app_key"] = appKey

if len(data.Tags) > 0 {
for k, v := range data.Tags {
Expand All @@ -238,7 +250,13 @@ func (s *Service) preparePost(appKey, id string, message string, details string,
return nil, err
}

alertUrl, err := url.Parse(c.URL)
var bpUrl string
if hc.URL != "" {
bpUrl = hc.URL
} else {
bpUrl = c.URL
}
alertUrl, err := url.Parse(bpUrl)
if err != nil {
return nil, err
}
Expand All @@ -254,7 +272,17 @@ func (s *Service) preparePost(appKey, id string, message string, details string,

// HandlerConfig defines the high-level struct required to connect to BigPanda
type HandlerConfig struct {
// BigPanda AppKey
AppKey string `mapstructure:"app-key"`

// webhook URL used to post alert.
// If empty uses the service URL from the configuration.
URL string `mapstructure:"url"`

// custom primary BigPanda property
PrimaryProperty string `mapstructure:"primary-property"`
// custom secondary BigPanda property
SecondaryProperty string `mapstructure:"secondary-property"`
}

type handler struct {
Expand All @@ -273,13 +301,13 @@ func (s *Service) Handler(c HandlerConfig, ctx ...keyvalue.T) (alert.Handler, er

func (h *handler) Handle(event alert.Event) {
if err := h.s.Alert(
h.c.AppKey,
event.State.ID,
event.State.Message,
event.State.Details,
event.State.Level,
event.State.Time,
event.Data,
&h.c,
); err != nil {
h.diag.Error("failed to send event to BigPanda", err)
}
Expand Down

0 comments on commit b7f14b8

Please sign in to comment.