notify

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package notify warns when a run fails.

It exists because it was the biggest gap against Kestra: the 51 flows in that repository each carried the SAME copied `errors: alert_slack` block -- twenty lines of payload repeated fifty times. Here the alert is a property of the INSTALLATION: configure the webhook once and every workflow starts warning, with the option to silence one.

The webhook does not come from the workflow's YAML, on purpose. It is a credential: whoever has the URL posts in the channel as if they were the platform, and a pipeline file is no place for that.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Alert added in v0.7.0

type Alert struct {
	Workflow    string
	RunID       string
	Status      string
	Trigger     string
	Attempts    int
	LogicalDate *time.Time
	Err         string

	// Step is the node that failed. It arrives as a field of its own, and not
	// only embedded in the error text, because it is the first thing whoever is
	// on call looks for: "which step?" before "why?".
	Step string

	// LogExcerpt is the last few lines of that step's output, read from
	// `task_runs.log`. Without it the alert says something failed; with it the
	// alert says what failed and why, without anyone opening the screen at
	// 4am.
	LogExcerpt string

	// The workflow's tags become the message's "Domain" and "Pipeline" fields --
	// in Kestra that came from `labels`, and it is what makes an alert
	// actionable without opening the screen.
	Tags []string

	// BaseURL of the UI, for the run's direct link. Empty means no link.
	BaseURL string
}

Alert is what gets told about a failure.

type Notificador

type Notificador interface {
	Failed(ctx context.Context, a Alert) error
}

Notificador sends the alert. A small interface so the dispatcher knows nothing of Slack -- and so the test needs no network.

type Report added in v0.8.0

type Report struct {
	From, To    time.Time
	Environment string

	Runs      int
	Succeeded int
	Failed    int

	// Workflows carries the per-pipeline numbers, and it is deliberately not a
	// map: the order is part of the message.
	Workflows []WorkflowInsight
}

Report is the periodic summary. It is NOT an Alert, and the two are kept apart on purpose.

They share a delivery channel and nothing else. An alert is triggered by an EVENT, is about one run, uses data already recorded, and is wanted NOW; a report is triggered by a SCHEDULE, is about everything in a window, is aggregated, and is wanted on Monday. One table serving both would make one access pattern serve two, and one delivery path carry two SLAs -- which is why a report does not go through the alerts outbox: losing an alert is an outage nobody hears about, and missing one week's summary is next week's summary.

func (Report) Slowest added in v0.8.0

func (r Report) Slowest(limit int) []WorkflowInsight

Slowest returns the pipelines that took longest, by their maximum. The maximum and not the average, because a report exists to surface the run that nearly did not finish, and an average hides it behind thirty fast ones.

func (Report) SuccessRate added in v0.8.0

func (r Report) SuccessRate() float64

SuccessRate for the whole window. Same rule.

func (Report) Worst added in v0.8.0

func (r Report) Worst(limit int) []WorkflowInsight

Worst returns the pipelines with failures, most first. They are the reason somebody opens the message.

type Reporter added in v0.8.0

type Reporter interface {
	Report(ctx context.Context, r Report) error
}

Reporter delivers a Report. A separate interface from Notificador because the two carry different promises: a lost alert is somebody not being woken up, a missed report is a week without a summary.

type Slack

type Slack struct {
	Webhook string
	Client  *http.Client

	// Ambiente appears in the header ("prod", "dev"). Without it, a staging
	// alert at three in the morning is indistinguishable from a production
	// one.
	Environment string
}

Slack posts to an Incoming Webhook.

func NovoSlack

func NovoSlack(webhook, environment string) *Slack

func (*Slack) Failed added in v0.7.0

func (s *Slack) Failed(ctx context.Context, a Alert) error

Failed posts the message.

func (*Slack) Report added in v0.8.0

func (s *Slack) Report(ctx context.Context, r Report) error

Report posts the summary.

type WorkflowInsight added in v0.8.0

type WorkflowInsight struct {
	Slug   string
	Runs   int
	Failed int

	// Durations of the runs that FINISHED. A run still going has no duration,
	// and counting it as zero would drag every average down at exactly the
	// moment something is stuck.
	Min, Avg, Max time.Duration

	// Rows and Bytes come from the SDK's stage numbers, summed over the
	// SUCCESSFUL attempts only. Counting a failed attempt's rows would report
	// work that was rolled back, and counting every attempt of a retried step
	// would report the same rows twice.
	//
	// Zero for a step that is not an SDK one, which is most of them, and that
	// is why the message leaves the column out rather than printing 0.
	Rows  int64
	Bytes int64
}

WorkflowInsight is one pipeline's week.

func (WorkflowInsight) SuccessRate added in v0.8.0

func (w WorkflowInsight) SuccessRate() float64

SuccessRate is a percentage, or -1 when there were no runs. A rate of 100% out of nothing is the most reassuring number a report can print and the least true one.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL