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

Commit 76afa80

Browse files
committed
Implement alert manager for telegram
1 parent e4dafdf commit 76afa80

File tree

6 files changed

+50
-10
lines changed

6 files changed

+50
-10
lines changed

docs/alert-routing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Pessimism currently supports the following alert destinations:
3636
|-----------|-------------------------------------|
3737
| slack | Sends alerts to a Slack channel |
3838
| pagerduty | Sends alerts to a PagerDuty service |
39-
| pagerduty | Sends alerts to a PagerDuty service |
39+
| telegram | Sends alerts to a Telegram service |
4040

4141
## Alert Severity
4242

internal/alert/manager.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,35 @@ func (am *alertManager) handlePagerDutyPost(alert core.Alert) error {
142142
return nil
143143
}
144144

145+
func (am *alertManager) handleTelegramPost(alert core.Alert, policy *core.AlertPolicy) error {
146+
telegramClients := am.cm.GetTelegramClients(alert.Sev)
147+
if telegramClients == nil {
148+
am.logger.Warn("No telegram clients defined for criticality", zap.Any("alert", alert))
149+
return nil
150+
}
151+
152+
// Create Telegram event trigger
153+
event := &client.AlertEventTrigger{
154+
Message: am.interpolator.TelegramMessage(alert, policy.Msg),
155+
Severity: alert.Sev,
156+
}
157+
158+
for _, tc := range telegramClients {
159+
resp, err := tc.PostEvent(am.ctx, event)
160+
if err != nil {
161+
return err
162+
}
163+
164+
if resp.Status != core.SuccessStatus {
165+
return fmt.Errorf("client %s could not post to telegram: %s", tc.GetName(), resp.Message)
166+
}
167+
am.logger.Debug("Successfully posted to Telegram", zap.String("resp", resp.Message))
168+
am.metrics.RecordAlertGenerated(alert, core.Telegram, tc.GetName())
169+
}
170+
171+
return nil
172+
}
173+
145174
// EventLoop ... Event loop for alert manager subsystem
146175
func (am *alertManager) EventLoop() error {
147176
ticker := time.NewTicker(time.Second * 1)
@@ -202,6 +231,10 @@ func (am *alertManager) HandleAlert(alert core.Alert, policy *core.AlertPolicy)
202231
if err := am.handlePagerDutyPost(alert); err != nil {
203232
am.logger.Error("could not post to pagerduty", zap.Error(err))
204233
}
234+
235+
if err := am.handleTelegramPost(alert, policy); err != nil {
236+
am.logger.Error("could not post to telegram", zap.Error(err))
237+
}
205238
}
206239

207240
// Shutdown ... Shuts down the alert manager subsystem

internal/alert/routing.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ func (rd *routingDirectory) paramsToRouteDirectory(acc *core.AlertClientCfg, sev
109109
if acc.Telegram != nil {
110110
for name, cfg := range acc.Telegram {
111111
conf := &client.TelegramConfig{
112-
Bot: cfg.Bot.String(),
113-
Token: cfg.Token.String(),
112+
ChatID: cfg.ChatID.String(),
113+
Token: cfg.Token.String(),
114114
}
115115
client := client.NewTelegramClient(conf, name)
116116
rd.telegramClients[sev] = append(rd.telegramClients[sev], client)

internal/client/telegram.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@ type TelegramConfig struct {
2222
}
2323

2424
type telegramClient struct {
25+
name string
2526
token string
2627
chatID string
2728
client *http.Client
2829
}
2930

30-
func NewTelegramClient(cfg *TelegramConfig) TelegramClient {
31+
func NewTelegramClient(cfg *TelegramConfig, name string) TelegramClient {
3132
if cfg.Token == "" {
3233
logging.NoContext().Warn("No Telegram token provided")
3334
}
3435

3536
return &telegramClient{
3637
token: cfg.Token,
3738
chatID: cfg.ChatID,
39+
name: name,
3840
client: &http.Client{},
3941
}
4042
}
@@ -101,5 +103,5 @@ func (tc *telegramClient) PostEvent(ctx context.Context, data *AlertEventTrigger
101103
}
102104

103105
func (tc *telegramClient) GetName() string {
104-
return "TelegramClient"
106+
return tc.name
105107
}

internal/core/alert.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,9 @@ type AlertClientCfg struct {
141141

142142
// AlertConfig ... The config for an alert client
143143
type AlertConfig struct {
144-
URL StringFromEnv `yaml:"url"`
145-
Channel StringFromEnv `yaml:"channel"`
146-
IntegrationKey StringFromEnv `yaml:"integration_key"`
147-
TelegramBotToken StringFromEnv `yaml:"telegram_bot_token"`
148-
TelegramChatID StringFromEnv `yaml:"telegram_chat_id"`
144+
URL StringFromEnv `yaml:"url"`
145+
Channel StringFromEnv `yaml:"channel"`
146+
IntegrationKey StringFromEnv `yaml:"integration_key"`
147+
Token StringFromEnv `yaml:"telegram_bot_token"`
148+
ChatID StringFromEnv `yaml:"telegram_chat_id"`
149149
}

internal/core/constants.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ const (
173173
Slack AlertDestination = iota + 1
174174
PagerDuty
175175
ThirdParty
176+
Telegram
176177
)
177178

178179
// String ... Converts an alerting destination type to a string
@@ -182,6 +183,8 @@ func (ad AlertDestination) String() string {
182183
return "slack"
183184
case PagerDuty:
184185
return "pager_duty"
186+
case Telegram:
187+
return "telegram"
185188
case ThirdParty:
186189
return "third_party"
187190
default:
@@ -196,6 +199,8 @@ func StringToAlertingDestType(stringType string) AlertDestination {
196199
return Slack
197200
case "pager_duty":
198201
return PagerDuty
202+
case "telegram":
203+
return Telegram
199204
case "third_party":
200205
return ThirdParty
201206
}

0 commit comments

Comments
 (0)