Skip to content
This repository has been archived by the owner on May 29, 2024. It is now read-only.

Commit

Permalink
Implement alert manager for telegram
Browse files Browse the repository at this point in the history
  • Loading branch information
richardgreg committed Feb 27, 2024
1 parent e4dafdf commit 76afa80
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 10 deletions.
2 changes: 1 addition & 1 deletion docs/alert-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Pessimism currently supports the following alert destinations:
|-----------|-------------------------------------|
| slack | Sends alerts to a Slack channel |
| pagerduty | Sends alerts to a PagerDuty service |
| pagerduty | Sends alerts to a PagerDuty service |
| telegram | Sends alerts to a Telegram service |

## Alert Severity

Expand Down
33 changes: 33 additions & 0 deletions internal/alert/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,35 @@ func (am *alertManager) handlePagerDutyPost(alert core.Alert) error {
return nil
}

func (am *alertManager) handleTelegramPost(alert core.Alert, policy *core.AlertPolicy) error {
telegramClients := am.cm.GetTelegramClients(alert.Sev)
if telegramClients == nil {
am.logger.Warn("No telegram clients defined for criticality", zap.Any("alert", alert))
return nil
}

// Create Telegram event trigger
event := &client.AlertEventTrigger{
Message: am.interpolator.TelegramMessage(alert, policy.Msg),
Severity: alert.Sev,
}

for _, tc := range telegramClients {
resp, err := tc.PostEvent(am.ctx, event)
if err != nil {
return err
}

if resp.Status != core.SuccessStatus {
return fmt.Errorf("client %s could not post to telegram: %s", tc.GetName(), resp.Message)
}
am.logger.Debug("Successfully posted to Telegram", zap.String("resp", resp.Message))
am.metrics.RecordAlertGenerated(alert, core.Telegram, tc.GetName())
}

return nil
}

// EventLoop ... Event loop for alert manager subsystem
func (am *alertManager) EventLoop() error {
ticker := time.NewTicker(time.Second * 1)
Expand Down Expand Up @@ -202,6 +231,10 @@ func (am *alertManager) HandleAlert(alert core.Alert, policy *core.AlertPolicy)
if err := am.handlePagerDutyPost(alert); err != nil {
am.logger.Error("could not post to pagerduty", zap.Error(err))
}

if err := am.handleTelegramPost(alert, policy); err != nil {
am.logger.Error("could not post to telegram", zap.Error(err))
}
}

// Shutdown ... Shuts down the alert manager subsystem
Expand Down
4 changes: 2 additions & 2 deletions internal/alert/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ func (rd *routingDirectory) paramsToRouteDirectory(acc *core.AlertClientCfg, sev
if acc.Telegram != nil {
for name, cfg := range acc.Telegram {
conf := &client.TelegramConfig{
Bot: cfg.Bot.String(),
Token: cfg.Token.String(),
ChatID: cfg.ChatID.String(),
Token: cfg.Token.String(),
}
client := client.NewTelegramClient(conf, name)
rd.telegramClients[sev] = append(rd.telegramClients[sev], client)
Expand Down
6 changes: 4 additions & 2 deletions internal/client/telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@ type TelegramConfig struct {
}

type telegramClient struct {
name string
token string
chatID string
client *http.Client
}

func NewTelegramClient(cfg *TelegramConfig) TelegramClient {
func NewTelegramClient(cfg *TelegramConfig, name string) TelegramClient {
if cfg.Token == "" {
logging.NoContext().Warn("No Telegram token provided")
}

return &telegramClient{
token: cfg.Token,
chatID: cfg.ChatID,
name: name,
client: &http.Client{},
}
}
Expand Down Expand Up @@ -101,5 +103,5 @@ func (tc *telegramClient) PostEvent(ctx context.Context, data *AlertEventTrigger
}

func (tc *telegramClient) GetName() string {
return "TelegramClient"
return tc.name
}
10 changes: 5 additions & 5 deletions internal/core/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ type AlertClientCfg struct {

// AlertConfig ... The config for an alert client
type AlertConfig struct {
URL StringFromEnv `yaml:"url"`
Channel StringFromEnv `yaml:"channel"`
IntegrationKey StringFromEnv `yaml:"integration_key"`
TelegramBotToken StringFromEnv `yaml:"telegram_bot_token"`
TelegramChatID StringFromEnv `yaml:"telegram_chat_id"`
URL StringFromEnv `yaml:"url"`
Channel StringFromEnv `yaml:"channel"`
IntegrationKey StringFromEnv `yaml:"integration_key"`
Token StringFromEnv `yaml:"telegram_bot_token"`
ChatID StringFromEnv `yaml:"telegram_chat_id"`
}
5 changes: 5 additions & 0 deletions internal/core/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ const (
Slack AlertDestination = iota + 1
PagerDuty
ThirdParty
Telegram
)

// String ... Converts an alerting destination type to a string
Expand All @@ -182,6 +183,8 @@ func (ad AlertDestination) String() string {
return "slack"
case PagerDuty:
return "pager_duty"
case Telegram:
return "telegram"
case ThirdParty:
return "third_party"
default:
Expand All @@ -196,6 +199,8 @@ func StringToAlertingDestType(stringType string) AlertDestination {
return Slack
case "pager_duty":
return PagerDuty
case "telegram":
return Telegram
case "third_party":
return ThirdParty
}
Expand Down

0 comments on commit 76afa80

Please sign in to comment.