app

package
v0.30.1 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2022 License: Apache-2.0 Imports: 111 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrDBRequired = validation.NewFieldError("db-url", "is required")

ErrDBRequired is returned when the DB URL is unset.

View Source
var ErrLockerShutdown = errors.New("context locker is already shutdown")

ErrLockerShutdown is returned when attempting to acquire a lock after being shutdown.

View Source
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()
		}

		err := viper.ReadInConfig()

		if err != nil && !isCfgNotFound(err) {
			return errors.Wrap(err, "read config")
		}

		err = initPromServer()
		if err != nil {
			return err
		}
		ctx := cmd.Context()

		cfg, err := getConfig(ctx)
		if err != nil {
			return err
		}

		wrappedDriver := sqldrv.NewRetryDriver(&stdlib.Driver{}, 10)

		u, err := url.Parse(cfg.DBURL)
		if err != nil {
			return errors.Wrap(err, "parse old URL")
		}
		q := u.Query()
		if cfg.DBURLNext != "" {
			q.Set("application_name", fmt.Sprintf("GoAlert %s (S/O Mode)", version.GitVersion()))
		} else {
			q.Set("application_name", fmt.Sprintf("GoAlert %s", version.GitVersion()))
		}
		q.Set("enable_seqscan", "off")
		u.RawQuery = q.Encode()
		cfg.DBURL = u.String()

		if cfg.APIOnly {
			err = migrate.VerifyAll(log.WithDebug(ctx), cfg.DBURL)
			if err != nil {
				return errors.Wrap(err, "verify migrations")
			}
		} else {
			s := time.Now()
			n, err := migrate.ApplyAll(log.WithDebug(ctx), cfg.DBURL)
			if err != nil {
				return errors.Wrap(err, "apply migrations")
			}
			if n > 0 {
				log.Logf(ctx, "Applied %d migrations in %s.", n, time.Since(s))
			}
		}

		dbc, err := wrappedDriver.OpenConnector(cfg.DBURL)
		if err != nil {
			return errors.Wrap(err, "connect to postgres")
		}
		var db *sql.DB
		var h *switchover.Handler
		if cfg.DBURLNext != "" {
			u, err := url.Parse(cfg.DBURLNext)
			if err != nil {
				return errors.Wrap(err, "parse next URL")
			}
			q := u.Query()
			q.Set("application_name", fmt.Sprintf("GoAlert %s (S/O Mode)", version.GitVersion()))
			q.Set("enable_seqscan", "off")
			u.RawQuery = q.Encode()
			cfg.DBURLNext = u.String()

			dbcNext, err := wrappedDriver.OpenConnector(cfg.DBURLNext)
			if err != nil {
				return errors.Wrap(err, "connect to postres (next)")
			}
			h, err = switchover.NewHandler(ctx, l, dbc, dbcNext, cfg.DBURL, cfg.DBURLNext)
			if err != nil {
				return errors.Wrap(err, "init changeover handler")
			}
			db = h.DB()
		} else {
			db = sql.OpenDB(dbc)
		}

		app, err := NewApp(cfg, db)
		if err != nil {
			return errors.Wrap(err, "init app")
		}
		if h != nil {
			h.SetApp(app)
		}

		go handleShutdown(ctx, func(ctx context.Context) error {
			if h != nil {
				h.Abort()
			}
			return app.Shutdown(ctx)
		})

		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

This section is empty.

Types

type App

type App struct {
	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
	ScheduleRuleStore   *rule.Store
	NotificationStore   *notification.Store
	ScheduleStore       *schedule.Store
	RotationStore       *rotation.Store

	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
	// contains filtered or unexported fields
}

App represents an instance of the GoAlert application.

func NewApp

func NewApp(c Config, db *sql.DB) (*App, error)

NewApp constructs a new App and binds the listening socket.

func (*App) ActiveRequests

func (a *App) ActiveRequests() int

ActiveRequests returns the current number of active requests, not including pending ones during pause.

func (*App) DB added in v0.25.0

func (a *App) DB() *sql.DB

DB returns the sql.DB instance used by the application.

func (*App) LogBackgroundContext added in v0.29.0

func (app *App) LogBackgroundContext() context.Context

LogBackgroundContext returns a context.Background with the application logger configured.

func (*App) Now added in v0.30.0

func (a *App) Now() time.Time

Now returns the current time for the application.

func (*App) Pause

func (app *App) Pause(ctx context.Context) error

func (*App) Resume

func (app *App) Resume()

func (*App) Run

func (app *App) Run(ctx context.Context) error

Run will start the application and start serving traffic.

func (*App) SetTimeOffset added in v0.30.0

func (a *App) SetTimeOffset(dur time.Duration)

SetTimeOffset sets the current time offset for the application.

func (*App) Shutdown

func (app *App) Shutdown(ctx context.Context) error

Shutdown will cause the App to begin a graceful shutdown, using the provided context for any cleanup operations.

func (*App) Status

func (a *App) Status() lifecycle.Status

Status returns the current lifecycle status of the App.

func (*App) Trigger

func (app *App) Trigger()

Trigger will start a processing cycle (normally ever ~5s)

func (*App) URL added in v0.25.0

func (a *App) URL() string

URL returns the non-TLS listener URL of the application.

func (*App) WaitForStartup added in v0.25.0

func (a *App) WaitForStartup(ctx context.Context) error

WaitForStartup will wait until the startup sequence is completed or the context is expired.

type Config added in v0.25.0

type Config struct {
	Logger *log.Logger

	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

	HTTPPrefix string

	DBMaxOpen int
	DBMaxIdle int

	MaxReqBodyBytes   int64
	MaxReqHeaderBytes int

	DisableHTTPSRedirect bool

	TwilioBaseURL string
	SlackBaseURL  string

	DBURL     string
	DBURLNext string

	KubernetesCooldown time.Duration
	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
}

func Defaults added in v0.25.0

func Defaults() Config

Defaults returns the default app config.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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