Documentation
¶
Index ¶
- Constants
- func Literal(_ context.Context, value string) (string, error)
- func SampleMessage(msg hermod.Message) (payload string, truncated bool)
- type DeadLetterSample
- type DiscordNotificationProvider
- type EmailNotificationProvider
- type GenericWebhookProvider
- type LeveledProvider
- type NotificationSettings
- func (ns NotificationSettings) SendDiscord(ctx context.Context, title, message string, wf storage.Workflow) error
- func (ns NotificationSettings) SendEmail(ctx context.Context, title, message string, wf storage.Workflow) error
- func (ns NotificationSettings) SendGenericWebhook(ctx context.Context, title, message string, wf storage.Workflow) error
- func (ns NotificationSettings) SendPanmail(ctx context.Context, resolve Resolver, mail PanmailMail) error
- func (ns NotificationSettings) SendSlack(ctx context.Context, title, message string, wf storage.Workflow) error
- func (ns NotificationSettings) SendTelegram(ctx context.Context, title, message string, wf storage.Workflow) error
- func (ns NotificationSettings) Test(ctx context.Context) []TestResult
- func (ns NotificationSettings) TestWith(ctx context.Context, resolve Resolver) []TestResult
- type PanmailMail
- type PanmailNotificationProvider
- type Provider
- type Resolver
- type Service
- func (s *Service) AddProvider(p Provider)
- func (s *Service) DeadLettered(wf storage.Workflow, sample func() DeadLetterSample)
- func (s *Service) FlushDeadLetters()
- func (s *Service) Notify(ctx context.Context, title, message string, wf storage.Workflow)
- func (s *Service) NotifyLevel(ctx context.Context, level, title, message string, wf storage.Workflow)
- func (s *Service) SetLogger(l hermod.Logger)
- func (s *Service) SetResolver(r Resolver)
- func (s *Service) SetStorage(s2 storage.Storage)
- func (s *Service) Wait()
- func (s *Service) WaitFor(d time.Duration) bool
- type SlackNotificationProvider
- type TelegramNotificationProvider
- type TestResult
- type UINotificationProvider
- func (p *UINotificationProvider) Send(ctx context.Context, title, message string, wf storage.Workflow) error
- func (p *UINotificationProvider) SendLeveled(ctx context.Context, level, title, message string, wf storage.Workflow) error
- func (p *UINotificationProvider) SetStorage(s storage.Storage)
- func (p *UINotificationProvider) Type() string
Constants ¶
const ( LevelInfo = "INFO" LevelWarn = "WARN" LevelError = "ERROR" )
Severity levels for an alert. They exist because not every notification is a fault: a workflow an operator stopped, or a worker draining during a deploy, is routine. UINotificationProvider wrote every alert at ERROR, so adding lifecycle notifications would have filed routine events as errors in the log table and in the UI's error view.
const DeadLetterDigestWindow = time.Minute
DeadLetterDigestWindow is how long a workflow's dead letters gather before they are mailed. The first dead letter opens the window and the mail goes when it closes, so a workflow parking a thousand messages a second sends one mail a minute, not a thousand.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type DeadLetterSample ¶ added in v1.18.4
type DeadLetterSample struct {
MessageID string
NodeID string
SinkID string
Error string
FailedAt time.Time
// Payload is the message as text, already capped by payloadText.
Payload string
Truncated bool
}
DeadLetterSample is one dead-lettered message as a digest shows it.
func (DeadLetterSample) When ¶ added in v1.18.4
func (d DeadLetterSample) When() string
When is the failure time as the mail shows it.
func (DeadLetterSample) Where ¶ added in v1.18.4
func (d DeadLetterSample) Where() string
Where names the step that gave up on a message.
type DiscordNotificationProvider ¶
type DiscordNotificationProvider struct {
// contains filtered or unexported fields
}
func NewDiscordNotificationProvider ¶
func NewDiscordNotificationProvider(s storage.Storage) *DiscordNotificationProvider
func (*DiscordNotificationProvider) SetStorage ¶
func (p *DiscordNotificationProvider) SetStorage(s storage.Storage)
func (*DiscordNotificationProvider) Type ¶
func (p *DiscordNotificationProvider) Type() string
type EmailNotificationProvider ¶
type EmailNotificationProvider struct {
// contains filtered or unexported fields
}
func NewEmailNotificationProvider ¶
func NewEmailNotificationProvider(s storage.Storage) *EmailNotificationProvider
func (*EmailNotificationProvider) SetStorage ¶
func (p *EmailNotificationProvider) SetStorage(s storage.Storage)
func (*EmailNotificationProvider) Type ¶
func (p *EmailNotificationProvider) Type() string
type GenericWebhookProvider ¶
type GenericWebhookProvider struct {
// contains filtered or unexported fields
}
func NewGenericWebhookProvider ¶
func NewGenericWebhookProvider(s storage.Storage) *GenericWebhookProvider
func (*GenericWebhookProvider) SetStorage ¶
func (p *GenericWebhookProvider) SetStorage(s storage.Storage)
func (*GenericWebhookProvider) Type ¶
func (p *GenericWebhookProvider) Type() string
type LeveledProvider ¶ added in v1.11.0
type LeveledProvider interface {
SendLeveled(ctx context.Context, level, title, message string, wf storage.Workflow) error
}
LeveledProvider is the optional interface for a provider that records a severity. Providers that push to a human (Telegram, Slack, email) do not need one — the title carries the meaning there — so the interface stays optional rather than widening Provider for a single implementation.
type NotificationSettings ¶
type NotificationSettings struct {
SMTPHost string `json:"smtp_host"`
SMTPPort int `json:"smtp_port"`
SMTPUser string `json:"smtp_user"`
SMTPPassword string `json:"smtp_password"`
SMTPFrom string `json:"smtp_from"`
SMTPSSL bool `json:"smtp_ssl"`
DefaultEmail string `json:"default_email"`
TelegramToken string `json:"telegram_token"`
TelegramChatID string `json:"telegram_chat_id"`
SlackWebhook string `json:"slack_webhook"`
DiscordWebhook string `json:"discord_webhook"`
WebhookURL string `json:"webhook_url"`
BaseURL string `json:"base_url"`
// Panmail sends alerts through a panmail gateway. Each value may hold
// {{secret.NAME}} or {{env.NAME}} references, resolved at send time.
PanmailURL string `json:"panmail_url"`
PanmailAPIKey string `json:"panmail_api_key"`
PanmailProviderID string `json:"panmail_provider_id"`
PanmailFrom string `json:"panmail_from"`
// PanmailTo is a comma-separated list. Empty means DefaultEmail.
PanmailTo string `json:"panmail_to"`
// PanmailDeadLetters mails a digest of every dead-lettered message: the
// workflow, the node or sink, the error and the message, batched per
// workflow over DeadLetterDigestWindow.
PanmailDeadLetters bool `json:"panmail_dead_letters"`
// PanmailHidePayload leaves message contents out of those digests.
PanmailHidePayload bool `json:"panmail_hide_payload"`
// EmailDeadLetters and TelegramDeadLetters send the same dead-letter
// digest through SMTP and Telegram.
EmailDeadLetters bool `json:"email_dead_letters"`
TelegramDeadLetters bool `json:"telegram_dead_letters"`
// DeadLetterHidePayload leaves message contents out of the digest on
// every channel.
DeadLetterHidePayload bool `json:"dead_letter_hide_payload"`
}
func (NotificationSettings) SendDiscord ¶
func (NotificationSettings) SendGenericWebhook ¶
func (NotificationSettings) SendPanmail ¶ added in v1.18.4
func (ns NotificationSettings) SendPanmail(ctx context.Context, resolve Resolver, mail PanmailMail) error
SendPanmail sends mail through the panmail gateway. Every setting may hold {{secret.NAME}} or {{env.NAME}} references, which resolve here, at send time, so the stored settings never need to hold the api key itself.
func (NotificationSettings) SendTelegram ¶
func (NotificationSettings) Test ¶
func (ns NotificationSettings) Test(ctx context.Context) []TestResult
func (NotificationSettings) TestWith ¶ added in v1.18.4
func (ns NotificationSettings) TestWith(ctx context.Context, resolve Resolver) []TestResult
TestWith is Test with the resolver panmail's references are read through.
type PanmailMail ¶ added in v1.18.4
type PanmailMail struct {
Subject string
Text string
HTML string
// IdempotencyKey lets the gateway answer a repeated send with the mail it
// already took, which is what makes a retry after a timeout safe.
IdempotencyKey string
}
PanmailMail is one mail to the configured recipients.
type PanmailNotificationProvider ¶ added in v1.18.4
type PanmailNotificationProvider struct {
// contains filtered or unexported fields
}
PanmailNotificationProvider sends alerts through the panmail gateway.
func NewPanmailNotificationProvider ¶ added in v1.18.4
func NewPanmailNotificationProvider(s storage.Storage) *PanmailNotificationProvider
func (*PanmailNotificationProvider) SetResolver ¶ added in v1.18.4
func (p *PanmailNotificationProvider) SetResolver(r Resolver)
SetResolver is how Service.SetResolver reaches this provider.
func (*PanmailNotificationProvider) SetStorage ¶ added in v1.18.4
func (p *PanmailNotificationProvider) SetStorage(s storage.Storage)
func (*PanmailNotificationProvider) Type ¶ added in v1.18.4
func (p *PanmailNotificationProvider) Type() string
type Resolver ¶ added in v1.18.4
Resolver expands the secret and env references in one settings value. The registry supplies one that reads the global secret manager; without one, only env references (HERMOD_ENV_*) resolve.
The settings are global and only an administrator writes them, so they are resolved without a vhost on purpose: a vhost secret of the same name must not be able to redirect the gateway, or the key, that every alert uses.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func (*Service) AddProvider ¶
func (*Service) DeadLettered ¶ added in v1.18.4
func (s *Service) DeadLettered(wf storage.Workflow, sample func() DeadLetterSample)
DeadLettered records that wf parked a message. sample builds what the mail shows of it and is called only while the digest still has room to show it, so a burst costs a counter increment per message past the first few.
It runs on the engine's write path and never blocks on the network.
func (*Service) FlushDeadLetters ¶ added in v1.18.4
func (s *Service) FlushDeadLetters()
FlushDeadLetters mails every open window now. Shutdown calls it so the dead letters of the last minute are not lost with the process; Wait or WaitFor then waits for the sends.
func (*Service) Notify ¶
Notify raises an alert at ERROR. Most alerts are faults; the ones that are not go through NotifyLevel.
func (*Service) NotifyLevel ¶ added in v1.11.0
func (s *Service) NotifyLevel(ctx context.Context, level, title, message string, wf storage.Workflow)
NotifyLevel raises an alert at an explicit severity.
func (*Service) SetLogger ¶ added in v1.11.0
SetLogger routes provider failures to the process log.
They went to fmt.Printf, so a rejected Telegram token or a webhook returning 500 appeared on stdout and nowhere else: not in the structured log, not in the log table, not in the UI. The one thing an operator needs to know about an alerting channel is that it has stopped working.
func (*Service) SetResolver ¶ added in v1.18.4
SetResolver sets how secret and env references in the settings resolve. Call it while wiring up, before alerts flow: providers read it unlocked.
func (*Service) SetStorage ¶
func (*Service) Wait ¶ added in v1.11.0
func (s *Service) Wait()
Wait blocks until every dispatched notification has finished. It exists for shutdown and for tests; the send path itself never waits.
func (*Service) WaitFor ¶ added in v1.11.0
WaitFor blocks until in-flight notifications finish or d elapses, and reports whether they finished.
Shutdown needs this. The fan-out runs on its own goroutine, so the alert saying a worker is going down was raced by the process exiting — dispatched, never sent. Waiting without a bound is the opposite mistake: an unreachable channel would hold the shutdown open for the full send timeout.
type SlackNotificationProvider ¶
type SlackNotificationProvider struct {
// contains filtered or unexported fields
}
func NewSlackNotificationProvider ¶
func NewSlackNotificationProvider(s storage.Storage) *SlackNotificationProvider
func (*SlackNotificationProvider) SetStorage ¶
func (p *SlackNotificationProvider) SetStorage(s storage.Storage)
func (*SlackNotificationProvider) Type ¶
func (p *SlackNotificationProvider) Type() string
type TelegramNotificationProvider ¶
type TelegramNotificationProvider struct {
// contains filtered or unexported fields
}
func NewTelegramNotificationProvider ¶
func NewTelegramNotificationProvider(s storage.Storage) *TelegramNotificationProvider
func (*TelegramNotificationProvider) SetStorage ¶
func (p *TelegramNotificationProvider) SetStorage(s storage.Storage)
func (*TelegramNotificationProvider) Type ¶
func (p *TelegramNotificationProvider) Type() string
type TestResult ¶
type UINotificationProvider ¶
type UINotificationProvider struct {
// contains filtered or unexported fields
}
func NewUINotificationProvider ¶
func NewUINotificationProvider(s storage.Storage) *UINotificationProvider
func (*UINotificationProvider) SendLeveled ¶ added in v1.11.0
func (p *UINotificationProvider) SendLeveled(ctx context.Context, level, title, message string, wf storage.Workflow) error
SendLeveled records the alert in the log table at the severity it was raised with, so a routine stop does not read as a failure.
func (*UINotificationProvider) SetStorage ¶
func (p *UINotificationProvider) SetStorage(s storage.Storage)
func (*UINotificationProvider) Type ¶
func (p *UINotificationProvider) Type() string