Skip to content

Commit

Permalink
Use ctx everywhere & render exit errors properly
Browse files Browse the repository at this point in the history
The `context.Context` related changes are neccessary as otherwise you
will have to wait for 5m when having Icinga notification started with
invalid database config due to the internal database.Connect retrials.
Lastly, the logging related changes are useful as we want to properly
render the stack traces when we unexpectedly exit from the main function
instead of wrapping the error in a confusing `zap.Error()` json key.
  • Loading branch information
yhabteab committed May 29, 2024
1 parent 2fd0ecc commit cf958eb
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
27 changes: 14 additions & 13 deletions cmd/icinga-notifications-daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/icinga/icinga-notifications/internal/icinga2"
"github.com/icinga/icinga-notifications/internal/incident"
"github.com/icinga/icinga-notifications/internal/listener"
"go.uber.org/zap"
"github.com/pkg/errors"
"os"
"os/signal"
"runtime"
Expand Down Expand Up @@ -62,24 +62,25 @@ func main() {
}

logger := logs.GetLogger()
defer func() { _ = logger.Sync() }()

logger.Infof("Starting Icinga Notifications daemon (%s)", internal.Version.Version)
db, err := database.NewDbFromConfig(&conf.Database, logs.GetChildLogger("database"), database.RetryConnectorCallbacks{})
if err != nil {
logger.Fatalw("cannot create database connection from config", zap.Error(err))
logger.Fatalf("%+v", errors.Wrap(err, "cannot create database connection from config"))
}
defer db.Close()
{
logger.Infof("Connecting to database at '%s'", db.GetAddr())
if err := db.Ping(); err != nil {
logger.Fatalw("cannot connect to database", zap.Error(err))
}
}

channel.UpsertPlugins(conf.ChannelPluginDir, logs.GetChildLogger("channel"), db)

ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

logger.Infof("Connecting to database at '%s'", db.GetAddr())
if err := db.PingContext(ctx); err != nil {
logger.Fatalf("Cannot connect to the database: %+v", err)
}

channel.UpsertPlugins(ctx, conf.ChannelPluginDir, logs.GetChildLogger("channel"), db)

icinga2Launcher := &icinga2.Launcher{
Ctx: ctx,
Logs: logs,
Expand All @@ -89,7 +90,7 @@ func main() {

runtimeConfig := config.NewRuntimeConfig(icinga2Launcher.Launch, logs, db)
if err := runtimeConfig.UpdateFromDatabase(ctx); err != nil {
logger.Fatalw("failed to load config from database", zap.Error(err))
logger.Fatalf("Failed to load config from database %+v", err)
}

icinga2Launcher.RuntimeConfig = runtimeConfig
Expand All @@ -98,13 +99,13 @@ func main() {

err = incident.LoadOpenIncidents(ctx, db, logs.GetChildLogger("incident"), runtimeConfig)
if err != nil {
logger.Fatalw("Can't load incidents from database", zap.Error(err))
logger.Fatalf("%+v", errors.Wrap(err, "cannot load incidents from database"))
}

// Wait to load open incidents from the database before either starting Event Stream Clients or starting the Listener.
icinga2Launcher.Ready()
if err := listener.NewListener(db, runtimeConfig, logs).Run(ctx); err != nil {
logger.Errorw("Listener has finished with an error", zap.Error(err))
logger.Errorf("%+v", errors.Wrap(err, "listener has finished with an error"))
} else {
logger.Info("Listener has finished")
}
Expand Down
5 changes: 3 additions & 2 deletions internal/channel/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package channel

import (
"bufio"
"context"
"encoding/json"
"fmt"
"github.com/icinga/icinga-go-library/database"
Expand Down Expand Up @@ -166,7 +167,7 @@ func forwardLogs(errPipe io.Reader, logger *zap.SugaredLogger) {
}

// UpsertPlugins upsert the available_channel_type table with working plugins
func UpsertPlugins(channelPluginDir string, logger *logging.Logger, db *database.DB) {
func UpsertPlugins(ctx context.Context, channelPluginDir string, logger *logging.Logger, db *database.DB) {
logger.Debug("Updating available channel types")
files, err := os.ReadDir(channelPluginDir)
if err != nil {
Expand Down Expand Up @@ -209,7 +210,7 @@ func UpsertPlugins(channelPluginDir string, logger *logging.Logger, db *database
}

stmt, _ := db.BuildUpsertStmt(&plugin.Info{})
_, err = db.NamedExec(stmt, pluginInfos)
_, err = db.NamedExecContext(ctx, stmt, pluginInfos)
if err != nil {
logger.Errorw("Failed to update available channel types", zap.Error(err))
} else {
Expand Down

0 comments on commit cf958eb

Please sign in to comment.