Documentation
¶
Index ¶
- Variables
- func LimitConcurrencyByAuthSource(next http.Handler) http.Handler
- type App
- func (app *App) Context(ctx context.Context) context.Context
- func (a *App) DB() *sql.DB
- func (app *App) LogBackgroundContext() context.Context
- func (app *App) Pause(ctx context.Context) error
- func (app *App) Resume(ctx context.Context) error
- func (app *App) Run(ctx context.Context) error
- func (a *App) SMTPAddr() string
- func (app *App) Shutdown(ctx context.Context) error
- func (app *App) Trigger()
- func (a *App) URL() string
- func (a *App) WaitForStartup(ctx context.Context) error
- type Config
Constants ¶
This section is empty.
Variables ¶
var ErrDBRequired = validation.NewFieldError("db-url", "is required")
ErrDBRequired is returned when the DB URL is unset.
var RootCmd = &cobra.Command{ Use: "goalert", Short: "Alerting platform.", RunE: func(cmd *cobra.Command, args []string) error { l := log.FromContext(cmd.Context()) if viper.GetBool("json") { l.EnableJSON() } if viper.GetBool("verbose") { l.EnableDebug() } if viper.GetBool("log-errors-only") { l.ErrorsOnly() } if viper.GetBool("list-experimental") { fmt.Print(`Usage: goalert --experimental=<flag1>,<flag2> ... These flags are not guaranteed to be stable and may change or be removed at any time. They are used to enable in-development features and are not intended for production use. Available Flags: `) for _, f := range expflag.AllFlags() { fmt.Printf("\t%s\t\t%s", f, expflag.Description(f)) } return nil } err := viper.ReadInConfig() if err != nil && !isCfgNotFound(err) { return errors.Wrap(err, "read config") } err = initPromServer() if err != nil { return err } err = initPprofServer() if err != nil { return err } ctx := cmd.Context() cfg, err := getConfig(ctx) if err != nil { return err } doMigrations := func(url string) error { if cfg.APIOnly { err = migrate.VerifyAll(log.WithDebug(ctx), url) if err != nil { return errors.Wrap(err, "verify migrations") } return nil } s := time.Now() n, err := migrate.ApplyAll(log.WithDebug(ctx), url) if err != nil { return errors.Wrap(err, "apply migrations") } if n > 0 { log.Logf(ctx, "Applied %d migrations in %s.", n, time.Since(s)) } return nil } err = doMigrations(cfg.DBURL) if err != nil { return err } var pool *pgxpool.Pool if cfg.DBURLNext != "" { err = migrate.VerifyIsLatest(ctx, cfg.DBURL) if err != nil { return errors.Wrap(err, "verify db") } err = doMigrations(cfg.DBURLNext) if err != nil { return errors.Wrap(err, "nextdb") } mgr, err := swo.NewManager(swo.Config{ OldDBURL: cfg.DBURL, NewDBURL: cfg.DBURLNext, CanExec: !cfg.APIOnly, Logger: cfg.LegacyLogger, MaxOpen: cfg.DBMaxOpen, MaxIdle: cfg.DBMaxIdle, }) if err != nil { return errors.Wrap(err, "init switchover handler") } pool = mgr.Pool() cfg.SWO = mgr } else { appURL, err := sqldrv.AppURL(cfg.DBURL, fmt.Sprintf("GoAlert %s", version.GitVersion())) if err != nil { return errors.Wrap(err, "connect to postgres") } poolCfg, err := pgxpool.ParseConfig(appURL) if err != nil { return errors.Wrap(err, "parse db URL") } poolCfg.MaxConns = int32(cfg.DBMaxOpen) poolCfg.MinConns = int32(cfg.DBMaxIdle) sqldrv.SetConfigRetries(poolCfg) calllimiter.SetConfigQueryLimiterSupport(poolCfg) pool, err = pgxpool.NewWithConfig(context.Background(), poolCfg) if err != nil { return errors.Wrap(err, "connect to postgres") } } app, err := NewApp(cfg, pool) if err != nil { return errors.Wrap(err, "init app") } go handleShutdown(ctx, app.Shutdown) trigCh := make(chan os.Signal, 1) signal.Notify(trigCh, triggerSignals...) go func() { for range trigCh { app.Trigger() } }() return errors.Wrap(app.Run(ctx), "run app") }, }
RootCmd is the configuration for running the app binary.
Functions ¶
func LimitConcurrencyByAuthSource ¶ added in v0.31.0
LimitConcurrencyByAuthSource limits the number of concurrent requests per auth source. MaxHeld is 1, so only one request can be processed at a time per source (e.g., session key, integration key, etc).
Note: This is per source/ID combo, so only multiple requests via the SAME integration key would get queued. Separate keys go in separate buckets.
Types ¶
type App ¶
type App struct {
Logger *slog.Logger
EventBus *event.Bus
Engine *engine.Engine
AuthHandler *auth.Handler
ConfigStore *config.Store
AlertStore *alert.Store
AlertLogStore *alertlog.Store
AlertMetricsStore *alertmetrics.Store
AuthBasicStore *basic.Store
UserStore *user.Store
ContactMethodStore *contactmethod.Store
NotificationRuleStore *notificationrule.Store
FavoriteStore *favorite.Store
ServiceStore *service.Store
EscalationStore *escalation.Store
IntegrationKeyStore *integrationkey.Store
UIKHandler *uik.Handler
ScheduleRuleStore *rule.Store
NotificationStore *notification.Store
ScheduleStore *schedule.Store
RotationStore *rotation.Store
DestRegistry *nfydest.Registry
CalSubStore *calsub.Store
OverrideStore *override.Store
LimitStore *limit.Store
HeartbeatStore *heartbeat.Store
OAuthKeyring keyring.Keyring
SessionKeyring keyring.Keyring
APIKeyring keyring.Keyring
AuthLinkKeyring keyring.Keyring
NonceStore *nonce.Store
LabelStore *label.Store
OnCallStore *oncall.Store
NCStore *notificationchannel.Store
TimeZoneStore *timezone.Store
NoticeStore *notice.Store
AuthLinkStore *authlink.Store
APIKeyStore *apikey.Store
River *river.Client[pgx.Tx]
// RiverDBSQL is a river client that uses the old sql.DB driver for use while transitioning to pgx.
//
// This allows us to add jobs from transactions that are not using the pgx driver. This client is not used for any job or queue processing.
RiverDBSQL *river.Client[*sql.Tx]
RiverUI *riverui.Server
RiverWorkers *river.Workers
// contains filtered or unexported fields
}
App represents an instance of the GoAlert application.
func (*App) Context ¶ added in v0.31.0
Context returns a new context with the App's configuration for experimental flags and logger.
It should be used for calls from other packages to ensure that the correct configuration is used.
func (*App) LogBackgroundContext ¶ added in v0.29.0
LogBackgroundContext returns a context.Background with the application logger configured.
func (*App) Shutdown ¶
Shutdown will cause the App to begin a graceful shutdown, using the provided context for any cleanup operations.
func (*App) Trigger ¶
func (app *App) Trigger()
Trigger will start a processing cycle (normally ever ~5s)
type Config ¶ added in v0.25.0
type Config struct {
LegacyLogger *log.Logger
Logger *slog.Logger
ExpFlags expflag.FlagSet
ListenAddr string
Verbose bool
JSON bool
LogRequests bool
APIOnly bool
LogEngine bool
PublicURL string
TLSListenAddr string
TLSConfig *tls.Config
SysAPIListenAddr string
SysAPICertFile string
SysAPIKeyFile string
SysAPICAFile string
SMTPListenAddr string
SMTPListenAddrTLS string
SMTPMaxRecipients int
TLSConfigSMTP *tls.Config
SMTPAdditionalDomains string
EmailIntegrationDomain string
HTTPPrefix string
DBMaxOpen int
DBMaxIdle int
MaxReqBodyBytes int64
MaxReqHeaderBytes int
DisableHTTPSRedirect bool
EnableSecureHeaders bool
TwilioBaseURL string
SlackBaseURL string
DBURL string
DBURLNext string
StatusAddr string
EngineCycleTime time.Duration
EncryptionKeys keyring.Keys
RegionName string
StubNotifiers bool
UIDir string
// InitialConfig will be pushed into the config store
// if specified before the engine is started.
InitialConfig *config.Config
// SWO should be set to operate in switchover mode.
SWO *swo.Manager
}
Source Files
¶
- app.go
- cmd.go
- cmdcerts.go
- config.go
- context.go
- defaults.go
- getsetconfig.go
- healthcheck.go
- initauth.go
- initengine.go
- initgraphql.go
- inithttp.go
- inithttputil.go
- initriver.go
- initslack.go
- initsmtpsrv.go
- initstores.go
- initsysapi.go
- inittwilio.go
- limitconcurrencybyauthsource.go
- listenevents.go
- listenstatus.go
- metrics.go
- middleware.go
- middlewaregzip.go
- multilistener.go
- pause.go
- pprof.go
- prometheus.go
- runapp.go
- secureheaders.go
- shutdown.go
- shutdownsignals_unix.go
- startup.go
- tlsconfig.go
- trigger.go