Skip to content

Commit

Permalink
internal/app: rework to load configuration file
Browse files Browse the repository at this point in the history
  • Loading branch information
joelrebel committed May 4, 2023
1 parent 4a1c32b commit 47e7071
Show file tree
Hide file tree
Showing 2 changed files with 363 additions and 39 deletions.
100 changes: 61 additions & 39 deletions internal/app/app.go
Original file line number Diff line number Diff line change
@@ -1,81 +1,103 @@
package app

import (
"context"
"log"
"net/http"
"os"
"os/signal"
"sync"
"syscall"
"time"

runtime "github.com/banzaicloud/logrus-runtime-formatter"
"github.com/metal-toolbox/flasher/internal/model"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"

// nolint:gosec // pprof path is only exposed over localhost
_ "net/http/pprof"
)

var (
ErrAppInit = errors.New("error initializing app")
)

const (
ProfilingEndpoint = "localhost:9091"
)

// Config holds configuration data when running mctl
// App holds attributes for the mtl application
type App struct {
// Sync waitgroup to wait for running go routines on termination.
SyncWG *sync.WaitGroup
// Viper loads configuration parameters.
v *viper.Viper
// Flasher configuration.
Config *model.Config
// TermCh is the channel to terminate the app based on a signal
TermCh chan os.Signal
Config *Configuration
// Logger is the app logger
Logger *logrus.Logger
// Kind is the type of application - worker
Kind model.AppKind
}

// New returns returns a new instance of the flasher app
func New(ctx context.Context, appKind model.AppKind, inventorySourceKind, cfgFile string, loglevel int) (*App, error) {
// load configuration
cfg := &model.Config{
AppKind: appKind,
InventorySource: inventorySourceKind,
}

if err := cfg.Load(cfgFile); err != nil {
return nil, err
func New(appKind model.AppKind, storeKind model.StoreKind, cfgFile, loglevel string, profiling bool) (*App, <-chan os.Signal, error) {
if appKind != model.AppKindWorker {
return nil, nil, errors.Wrap(ErrAppInit, "invalid app kind: "+string(appKind))
}

app := &App{
Config: cfg,
SyncWG: &sync.WaitGroup{},
v: viper.New(),
Kind: appKind,
Config: &Configuration{},
Logger: logrus.New(),
TermCh: make(chan os.Signal),
}

runtimeFormatter := &runtime.Formatter{
ChildFormatter: &logrus.JSONFormatter{},
File: true,
Line: true,
BaseNameOnly: true,
if err := app.LoadConfiguration(cfgFile, storeKind); err != nil {
return nil, nil, err
}

// set log level, format
switch loglevel {
switch model.LogLevel(loglevel) {
case model.LogLevelDebug:
app.Logger.Level = logrus.DebugLevel

// set runtime formatter options
runtimeFormatter.BaseNameOnly = true
runtimeFormatter.File = true
runtimeFormatter.Line = true

case model.LogLevelTrace:
app.Logger.Level = logrus.TraceLevel

// set runtime formatter options
runtimeFormatter.File = true
runtimeFormatter.Line = true
runtimeFormatter.Package = true
default:
app.Logger.Level = logrus.InfoLevel
}

runtimeFormatter := &runtime.Formatter{
ChildFormatter: &logrus.JSONFormatter{},
File: true,
Line: true,
BaseNameOnly: true,
}

app.Logger.SetFormatter(runtimeFormatter)

termCh := make(chan os.Signal, 1)

// register for SIGINT, SIGTERM
signal.Notify(app.TermCh, syscall.SIGINT, syscall.SIGTERM)
signal.Notify(termCh, syscall.SIGINT, syscall.SIGTERM)

if profiling {
enableProfilingEndpoint()
}

return app, termCh, nil
}

// enableProfilingEndpoint enables the profiling endpoint
func enableProfilingEndpoint() {
go func() {
server := &http.Server{
Addr: "",
ReadHeaderTimeout: 2 * time.Second, // nolint:gomnd // time duration value is clear as is.
}

if err := server.ListenAndServe(); err != nil {
log.Println(err)
}
}()

return app, nil
log.Println("profiling enabled: " + ProfilingEndpoint + "/debug/pprof")
}
Loading

0 comments on commit 47e7071

Please sign in to comment.