Documentation
¶
Overview ¶
Package changes answers "what changed on this app recently" by merging the app event log, deploy attempts and the audit log into one ordered list.
Index ¶
- Constants
- func IsRollbackAttempt(a store.DeployAttempt, older []store.DeployAttempt) bool
- func MaxFromEnv() int
- func NotifyBlock(r Result, link string) string
- func NotifyLines(r Result) []string
- func WindowFromEnv() time.Duration
- type Aggregator
- type AuditSource
- type Change
- type DeploySource
- type EventSource
- type Kind
- type Result
Constants ¶
const ( EnvWindow = "APP_ALERT_CHANGE_WINDOW" EnvMaxEntries = "APP_ALERT_CHANGE_MAX" DefaultWindow = 30 * time.Minute DefaultMaxEntries = 20 )
Env vars that tune the window and the size cap.
const ( NotifyMaxLines = 5 NotifyLineCap = 120 )
Notification size limits: a message carries at most NotifyMaxLines changes, each clipped to NotifyLineCap runes.
Variables ¶
This section is empty.
Functions ¶
func IsRollbackAttempt ¶
func IsRollbackAttempt(a store.DeployAttempt, older []store.DeployAttempt) bool
IsRollbackAttempt reports whether a redeployed an image that an attempt older than its immediate predecessor had already deployed. older is newest first.
func NotifyBlock ¶
NotifyBlock renders the "Recent changes" section of a notification, ending with link when it is non-empty. It returns "" when nothing changed.
func NotifyLines ¶
NotifyLines renders the top NotifyMaxLines changes, newest first, plus an "and N more" line. It returns nil when there is nothing to say.
func WindowFromEnv ¶
WindowFromEnv reads APP_ALERT_CHANGE_WINDOW.
Types ¶
type Aggregator ¶
type Aggregator struct {
Events EventSource
Deploys DeploySource
Audit AuditSource
Window time.Duration
Max int
Logger *slog.Logger
}
Aggregator merges the sources. Any source may be nil.
func New ¶
func New(events EventSource, deploys DeploySource, audit AuditSource, logger *slog.Logger) *Aggregator
New builds an Aggregator with the window and cap taken from the environment.
type AuditSource ¶
type AuditSource interface {
ListAuditEntries(ctx context.Context, limit int, before *time.Time, filter store.AuditEntryFilter) ([]store.AuditEntry, error)
}
AuditSource lists audit entries newest first; *store.DB satisfies it.
type Change ¶
type Change struct {
At time.Time `json:"at"`
Kind Kind `json:"kind"`
Actor string `json:"actor"`
Title string `json:"title"`
Detail string `json:"detail,omitempty"`
Keys []string `json:"keys,omitempty"`
Ref string `json:"ref,omitempty"`
LikelyCause bool `json:"likely_cause,omitempty"`
// contains filtered or unexported fields
}
Change is one thing that happened to an app. Keys are names only, never values.
type DeploySource ¶
type DeploySource interface {
ListDeployAttempts(ctx context.Context, serviceName string) ([]store.DeployAttempt, error)
}
DeploySource lists deploy attempts newest first; *store.DB satisfies it.
type EventSource ¶
type EventSource interface {
ListAppEvents(ctx context.Context, name string, before *store.AppEventCursor, after time.Time, kinds []string, limit int) ([]store.AppEvent, error)
}
EventSource lists app events; *store.DB satisfies it.
type Kind ¶
type Kind string
Kind classifies a change.
const ( KindDeploy Kind = "deploy" KindRollback Kind = "rollback" KindConfig Kind = "config" KindEnv Kind = "env" KindSecret Kind = "secret" KindDomain Kind = "domain" KindScale Kind = "scale" KindLB Kind = "loadbalancer" KindFreeze Kind = "freeze" KindMaintenance Kind = "maintenance" KindLifecycle Kind = "lifecycle" )
Change kinds. Lifecycle, maintenance and freeze are reported but never suspected.
type Result ¶
type Result struct {
App string `json:"app"`
Since time.Time `json:"since"`
Until time.Time `json:"until"`
Window time.Duration `json:"-"`
WindowSec int64 `json:"window_seconds"`
Changes []Change `json:"changes"`
Total int `json:"total"`
Truncated bool `json:"truncated,omitempty"`
}
Result is the aggregator output: newest first, capped, with the suspect flagged.