diff --git a/config/basic_config.go b/config/basic_config.go new file mode 100644 index 0000000..ce4a716 --- /dev/null +++ b/config/basic_config.go @@ -0,0 +1,113 @@ +package config + +import ( + "context" + "flag" + + "github.com/safing/portbase/log" +) + +// Configuration Keys. +var ( + CfgDevModeKey = "core/devMode" + defaultDevMode bool + + CfgLogLevel = "core/log/level" + defaultLogLevel = log.InfoLevel.String() + logLevel StringOption +) + +func init() { + flag.BoolVar(&defaultDevMode, "devmode", false, "enable development mode") +} + +func registerBasicOptions() error { + // Get the default log level from the log package. + defaultLogLevel = log.GetLogLevel().Name() + + // Register logging setting. + // The log package cannot do that, as it would trigger and import loop. + if err := Register(&Option{ + Name: "Log Level", + Key: CfgLogLevel, + Description: "Configure the logging level.", + OptType: OptTypeString, + ExpertiseLevel: ExpertiseLevelDeveloper, + ReleaseLevel: ReleaseLevelStable, + DefaultValue: defaultLogLevel, + Annotations: Annotations{ + DisplayOrderAnnotation: 513, + DisplayHintAnnotation: DisplayHintOneOf, + CategoryAnnotation: "Development", + }, + PossibleValues: []PossibleValue{ + { + Name: "Critical", + Value: "critical", + Description: "The critical level only logs errors that lead to a partial, but imminent failure.", + }, + { + Name: "Error", + Value: "error", + Description: "The error level logs errors that potentially break functionality. Everything logged by the critical level is included here too.", + }, + { + Name: "Warning", + Value: "warning", + Description: "The warning level logs minor errors and worse. Everything logged by the error level is included here too.", + }, + { + Name: "Info", + Value: "info", + Description: "The info level logs the main events that are going on and are interesting to the user. Everything logged by the warning level is included here too.", + }, + { + Name: "Debug", + Value: "debug", + Description: "The debug level logs some additional debugging details. Everything logged by the info level is included here too.", + }, + { + Name: "Trace", + Value: "trace", + Description: "The trace level logs loads of detailed information as well as operation and request traces. Everything logged by the debug level is included here too.", + }, + }, + }); err != nil { + return err + } + logLevel = GetAsString(CfgLogLevel, defaultLogLevel) + + // Register to hook to update the log level. + if err := module.RegisterEventHook( + "config", + configChangeEvent, + "update log level", + setLogLevel, + ); err != nil { + return err + } + + return Register(&Option{ + Name: "Development Mode", + Key: CfgDevModeKey, + Description: "In Development Mode, security restrictions are lifted/softened to enable unrestricted access for debugging and testing purposes.", + OptType: OptTypeBool, + ExpertiseLevel: ExpertiseLevelDeveloper, + ReleaseLevel: ReleaseLevelStable, + DefaultValue: defaultDevMode, + Annotations: Annotations{ + DisplayOrderAnnotation: 512, + CategoryAnnotation: "Development", + }, + }) +} + +func loadLogLevel() { + setDefaultConfigOption(CfgLogLevel, log.GetLogLevel().Name(), false) +} + +func setLogLevel(ctx context.Context, data interface{}) error { + log.SetLogLevel(log.ParseLevel(logLevel())) + + return nil +} diff --git a/config/devmode.go b/config/devmode.go deleted file mode 100644 index 7dbd190..0000000 --- a/config/devmode.go +++ /dev/null @@ -1,39 +0,0 @@ -package config - -import ( - "flag" - - "github.com/safing/portbase/log" -) - -// Configuration Keys. -var ( - CfgDevModeKey = "core/devMode" - defaultDevMode bool -) - -func init() { - flag.BoolVar(&defaultDevMode, "devmode", false, "enable development mode") -} - -func logDevModeOverride() { - if defaultDevMode { - log.Warning("config: development mode is enabled by default by the -devmode flag") - } -} - -func registerDevModeOption() error { - return Register(&Option{ - Name: "Development Mode", - Key: CfgDevModeKey, - Description: "In Development Mode, security restrictions are lifted/softened to enable unrestricted access for debugging and testing purposes.", - OptType: OptTypeBool, - ExpertiseLevel: ExpertiseLevelDeveloper, - ReleaseLevel: ReleaseLevelStable, - DefaultValue: defaultDevMode, - Annotations: Annotations{ - DisplayOrderAnnotation: 512, - CategoryAnnotation: "Development", - }, - }) -} diff --git a/config/main.go b/config/main.go index 2857ce8..b064b95 100644 --- a/config/main.go +++ b/config/main.go @@ -47,18 +47,15 @@ func prep() error { modules.SetCmdLineOperation(exportConfigCmd) } - logDevModeOverride() - err := registerDevModeOption() - if err != nil { - return err - } - - return nil + return registerBasicOptions() } func start() error { configFilePath = filepath.Join(dataRoot.Path, "config.json") + // Load log level from log package after it started. + loadLogLevel() + err := registerAsDatabase() if err != nil && !os.IsNotExist(err) { return err diff --git a/config/set.go b/config/set.go index 6e1ef4b..b9b11ff 100644 --- a/config/set.go +++ b/config/set.go @@ -192,5 +192,7 @@ func setDefaultConfigOption(key string, value interface{}, push bool) (err error // finalize change, activate triggers signalChanges() - return saveConfig() + // Do not save the configuration, as it only saves the active values, not the + // active default value. + return nil } diff --git a/log/logging.go b/log/logging.go index 2af4390..27439dd 100644 --- a/log/logging.go +++ b/log/logging.go @@ -102,7 +102,7 @@ var ( logBuffer chan *logLine forceEmptyingOfBuffer = make(chan struct{}) - logLevelInt = uint32(3) + logLevelInt = uint32(InfoLevel) logLevel = &logLevelInt pkgLevelsActive = abool.NewBool(false) @@ -134,11 +134,36 @@ func UnSetPkgLevels() { pkgLevelsActive.UnSet() } +// GetLogLevel returns the current log level. +func GetLogLevel() Severity { + return Severity(atomic.LoadUint32(logLevel)) +} + // SetLogLevel sets a new log level. Only effective after Start(). func SetLogLevel(level Severity) { atomic.StoreUint32(logLevel, uint32(level)) } +// Name returns the name of the log level. +func (s Severity) Name() string { + switch s { + case TraceLevel: + return "trace" + case DebugLevel: + return "debug" + case InfoLevel: + return "info" + case WarningLevel: + return "warning" + case ErrorLevel: + return "error" + case CriticalLevel: + return "critical" + default: + return "none" + } +} + // ParseLevel returns the level severity of a log level name. func ParseLevel(level string) Severity { switch strings.ToLower(level) {