Updates functions so they actually work :P

This commit is contained in:
Hyatt 2023-11-04 13:10:29 -05:00
parent f19ecf52c2
commit e12f3b844d
Signed by: nhyatt
GPG Key ID: C50D0BBB5BC40BEA
4 changed files with 96 additions and 46 deletions

@ -203,7 +203,7 @@ func typeConversion(t, v string) (interface{}, error) {
return nil, fmt.Errorf("Unable to identify type.") return nil, fmt.Errorf("Unable to identify type.")
} }
func (cfg *Config) parseFlags(cfgInfo []structInfo) { func (cfg *Config) parseFlags(cfgInfo []structInfo) error {
for _, info := range cfgInfo { for _, info := range cfgInfo {
switch info.Type.String() { switch info.Type.String() {
case "string": case "string":
@ -223,21 +223,19 @@ func (cfg *Config) parseFlags(cfgInfo []structInfo) {
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*bool) p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*bool)
retVal, err := getEnvBool(info.Alt, dv) retVal, err := getEnvBool(info.Alt, dv)
if err != nil { if err != nil {
cfg.Log.Error("Error Encountered", "error", err) return err
os.Exit(1)
} }
flag.BoolVar(p, info.Name, retVal, info.Info) flag.BoolVar(p, info.Name, retVal, info.Info)
case "int": case "int":
var dv int var dv int
if info.DefaultValue != nil { if info.DefaultValue != nil {
dv = info.DefaultValue.(int) dv = int(info.DefaultValue.(int64))
} }
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int) p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int)
retVal, err := getEnvInt(info.Alt, dv) retVal, err := getEnvInt(info.Alt, dv)
if err != nil { if err != nil {
cfg.Log.Error("Error Encountered", "error", err) return err
os.Exit(1)
} }
flag.IntVar(p, info.Name, retVal, info.Info) flag.IntVar(p, info.Name, retVal, info.Info)
case "int64": case "int64":
@ -249,8 +247,7 @@ func (cfg *Config) parseFlags(cfgInfo []structInfo) {
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int64) p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int64)
retVal, err := getEnvInt64(info.Alt, dv) retVal, err := getEnvInt64(info.Alt, dv)
if err != nil { if err != nil {
cfg.Log.Error("Error Encountered", "error", err) return err
os.Exit(1)
} }
flag.Int64Var(p, info.Name, retVal, info.Info) flag.Int64Var(p, info.Name, retVal, info.Info)
case "float64": case "float64":
@ -262,11 +259,11 @@ func (cfg *Config) parseFlags(cfgInfo []structInfo) {
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*float64) p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*float64)
retVal, err := getEnvFloat64(info.Alt, dv) retVal, err := getEnvFloat64(info.Alt, dv)
if err != nil { if err != nil {
cfg.Log.Error("Error Encountered", "error", err) return err
os.Exit(1)
} }
flag.Float64Var(p, info.Name, retVal, info.Info) flag.Float64Var(p, info.Name, retVal, info.Info)
} }
} }
flag.Parse() flag.Parse()
return nil
} }

@ -1,36 +1,81 @@
package config package config
import ( import (
"log/slog"
"os" "os"
"reflect"
"strconv"
"time" "time"
) )
func Init() *Config { type Config struct {
cfg := New() // time configuration
TimeFormat string `default:"2006-01-02 15:04:05" env:"time_format"`
TimeZoneLocal string `default:"America/Chicago" env:"time_zone"`
TZLocal *time.Location `ignored:"true"`
TZUTC *time.Location `ignored:"true"`
cfgInfo, err := getStructInfo(cfg) // logging
if err != nil { LogLevel int `default:"50" env:"log_level"`
cfg.Log.Error("Unable to initialize program parameters", "error", err) Log *slog.Logger `ignored:"true"`
os.Exit(1) SLogLevel *slog.LevelVar `ignored:"true"`
// webserver
WebServerPort int `default:"8080" env:"webserver_port"`
WebServerIP string `default:"0.0.0.0" env:"webserver_ip"`
WebServerReadTimeout int `default:"5" env:"webserver_read_timeout"`
WebServerWriteTimeout int `default:"1" env:"webserver_write_timeout"`
WebServerIdleTimeout int `default:"2" env:"webserver_idle_timeout"`
} }
// get command line flags // New initializes the config variable for use with a prepared set of defaults.
cfg.parseFlags(cfgInfo) func New() Config {
cfg := Config{
// set logging Level SLogLevel: new(slog.LevelVar),
setLogLevel(cfg)
// set timezone & time format
cfg.TZUTC, _ = time.LoadLocation("UTC")
cfg.TZLocal, err = time.LoadLocation(cfg.TimeZoneLocal)
if err != nil {
cfg.Log.Error("Unable to parse timezone string", "error", err)
os.Exit(1)
} }
// print running config cfg.Log = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
printRunningConfig(cfg, cfgInfo) Level: cfg.SLogLevel,
}))
// return configuration
return cfg return cfg
} }
func setLogLevel(cfg *Config) {
switch {
// error
case cfg.LogLevel <= 20:
cfg.SLogLevel.Set(slog.LevelError)
cfg.Log.Info("Log level updated", "level", slog.LevelError)
// warning
case cfg.LogLevel > 20 && cfg.LogLevel <= 40:
cfg.SLogLevel.Set(slog.LevelWarn)
cfg.Log.Info("Log level updated", "level", slog.LevelWarn)
// info
case cfg.LogLevel > 40 && cfg.LogLevel <= 60:
cfg.SLogLevel.Set(slog.LevelInfo)
cfg.Log.Info("Log level updated", "level", slog.LevelInfo)
// debug
case cfg.LogLevel > 60:
cfg.SLogLevel.Set(slog.LevelDebug)
cfg.Log.Info("Log level updated", "level", slog.LevelDebug)
}
// set default logger
slog.SetDefault(cfg.Log)
}
func printRunningConfig(cfg *Config, cfgInfo []structInfo) {
for _, info := range cfgInfo {
switch info.Type.String() {
case "string":
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*string)
cfg.Log.Debug("Running Configuration", info.Alt, *p)
case "bool":
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*bool)
cfg.Log.Debug("Running Configuration", info.Alt, strconv.FormatBool(*p))
case "int":
p := reflect.ValueOf(cfg).Elem().FieldByName(info.Name).Addr().Interface().(*int)
cfg.Log.Debug("Running Configuration", info.Alt, strconv.FormatInt(int64(*p), 10))
}
}
}

@ -2,6 +2,7 @@ package config
import ( import (
"log/slog" "log/slog"
"os"
"reflect" "reflect"
"strconv" "strconv"
"time" "time"
@ -9,14 +10,15 @@ import (
type Config struct { type Config struct {
// time configuration // time configuration
TimeFormat string `default:"2006-01-02 15:04:05" env:"TIME_FORMAT"` TimeFormat string `default:"2006-01-02 15:04:05" env:"time_format"`
TimeZoneLocal string `default:"America/Chicago" env:"TIME_ZONE"` TimeZoneLocal string `default:"America/Chicago" env:"time_zone"`
TZLocal *time.Location `ignored:"true"` TZLocal *time.Location `ignored:"true"`
TZUTC *time.Location `ignored:"true"` TZUTC *time.Location `ignored:"true"`
// logging // logging
LogLevel int `default:"50" env:"log_level"` LogLevel int `default:"50" env:"log_level"`
Log *slog.Logger `ignored:"true"` Log *slog.Logger `ignored:"true"`
SLogLevel *slog.LevelVar `ignored:"true"`
// webserver // webserver
WebServerPort int `default:"8080" env:"webserver_port"` WebServerPort int `default:"8080" env:"webserver_port"`
@ -27,29 +29,35 @@ type Config struct {
} }
// New initializes the config variable for use with a prepared set of defaults. // New initializes the config variable for use with a prepared set of defaults.
func New() *Config { func New() Config {
return &Config{} cfg := Config{
SLogLevel: new(slog.LevelVar),
}
cfg.Log = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: cfg.SLogLevel,
}))
return cfg
} }
func setLogLevel(cfg *Config) { func setLogLevel(cfg *Config) {
logLevel := &slog.LevelVar{}
switch { switch {
// error // error
case cfg.LogLevel <= 20: case cfg.LogLevel <= 20:
logLevel.Set(slog.LevelError) cfg.SLogLevel.Set(slog.LevelError)
cfg.Log.Info("Log level updated", "level", slog.LevelError) cfg.Log.Info("Log level updated", "level", slog.LevelError)
// warning // warning
case cfg.LogLevel > 20 && cfg.LogLevel <= 40: case cfg.LogLevel > 20 && cfg.LogLevel <= 40:
logLevel.Set(slog.LevelWarn) cfg.SLogLevel.Set(slog.LevelWarn)
cfg.Log.Info("Log level updated", "level", slog.LevelWarn) cfg.Log.Info("Log level updated", "level", slog.LevelWarn)
// info // info
case cfg.LogLevel > 40 && cfg.LogLevel <= 60: case cfg.LogLevel > 40 && cfg.LogLevel <= 60:
logLevel.Set(slog.LevelInfo) cfg.SLogLevel.Set(slog.LevelInfo)
cfg.Log.Info("Log level updated", "level", slog.LevelInfo) cfg.Log.Info("Log level updated", "level", slog.LevelInfo)
// debug // debug
case cfg.LogLevel > 60: case cfg.LogLevel > 60:
logLevel.Set(slog.LevelDebug) cfg.SLogLevel.Set(slog.LevelDebug)
cfg.Log.Info("Log level updated", "level", slog.LevelDebug) cfg.Log.Info("Log level updated", "level", slog.LevelDebug)
} }
// set default logger // set default logger

@ -11,7 +11,7 @@ This is a base repository for starting a GoLang project. It includes a set of li
## Usage ## Usage
Clone this repository and run the following command: Clone this repository and update [`go.mod`](./go.mod)
```bash ```bash
PRJCT="example.com/newproject" PRJCT="example.com/newproject"