Add basic webserver skeleton with healthcheck
This commit is contained in:
128
internal/config/config.go
Normal file
128
internal/config/config.go
Normal file
@@ -0,0 +1,128 @@
|
||||
// Package config provides application configuration using smartconfig.
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.eeqj.de/sneak/smartconfig"
|
||||
"go.uber.org/fx"
|
||||
"sneak.berlin/go/pixa/internal/globals"
|
||||
"sneak.berlin/go/pixa/internal/logger"
|
||||
)
|
||||
|
||||
// ConfigParams defines dependencies for Config.
|
||||
type ConfigParams struct {
|
||||
fx.In
|
||||
Globals *globals.Globals
|
||||
Logger *logger.Logger
|
||||
}
|
||||
|
||||
// Config holds application configuration values.
|
||||
type Config struct {
|
||||
Debug bool
|
||||
MaintenanceMode bool
|
||||
MetricsPassword string
|
||||
MetricsUsername string
|
||||
Port int
|
||||
SentryDSN string
|
||||
StateDir string
|
||||
DBURL string
|
||||
}
|
||||
|
||||
// New creates a new Config instance by loading configuration from file.
|
||||
func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||
log := params.Logger.Get()
|
||||
name := params.Globals.Appname
|
||||
|
||||
var sc *smartconfig.Config
|
||||
var err error
|
||||
|
||||
// Try loading config from standard locations
|
||||
configPaths := []string{
|
||||
fmt.Sprintf("/etc/%s/config.yml", name),
|
||||
fmt.Sprintf("/etc/%s/config.yaml", name),
|
||||
filepath.Join(os.Getenv("HOME"), ".config", name, "config.yml"),
|
||||
filepath.Join(os.Getenv("HOME"), ".config", name, "config.yaml"),
|
||||
"config.yml",
|
||||
"config.yaml",
|
||||
}
|
||||
|
||||
for _, path := range configPaths {
|
||||
if _, statErr := os.Stat(path); statErr == nil {
|
||||
sc, err = smartconfig.NewFromConfigPath(path)
|
||||
if err == nil {
|
||||
log.Info("loaded config file", "path", path)
|
||||
|
||||
break
|
||||
}
|
||||
log.Warn("failed to parse config file", "path", path, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
if sc == nil {
|
||||
log.Info("no config file found, using defaults")
|
||||
}
|
||||
|
||||
c := &Config{
|
||||
Debug: getBool(sc, "debug", false),
|
||||
MaintenanceMode: getBool(sc, "maintenance_mode", false),
|
||||
Port: getInt(sc, "port", 8080),
|
||||
StateDir: getString(sc, "state_dir", "./data"),
|
||||
SentryDSN: getString(sc, "sentry_dsn", ""),
|
||||
MetricsUsername: getString(sc, "metrics.username", ""),
|
||||
MetricsPassword: getString(sc, "metrics.password", ""),
|
||||
}
|
||||
|
||||
// Build DBURL from StateDir if not explicitly set
|
||||
c.DBURL = getString(sc, "db_url", "")
|
||||
if c.DBURL == "" {
|
||||
c.DBURL = fmt.Sprintf("file:%s/state.sqlite3?_journal_mode=WAL", c.StateDir)
|
||||
}
|
||||
|
||||
if c.Debug {
|
||||
params.Logger.EnableDebugLogging()
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func getString(sc *smartconfig.Config, key, defaultVal string) string {
|
||||
if sc == nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
val, err := sc.GetString(key)
|
||||
if err != nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func getInt(sc *smartconfig.Config, key string, defaultVal int) int {
|
||||
if sc == nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
val, err := sc.GetInt(key)
|
||||
if err != nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func getBool(sc *smartconfig.Config, key string, defaultVal bool) bool {
|
||||
if sc == nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
val, err := sc.GetBool(key)
|
||||
if err != nil {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
Reference in New Issue
Block a user