func parseLogFlags(args logOptionsType) error { var logOptCount int if *args.logLevel != "" { level, err := log.ParseLevel(*args.logLevel) if err != nil { return err } log.SetLevel(level) logOptCount++ } if *args.info { log.SetLevel(log.InfoLevel) logOptCount++ } if *args.debug { log.SetLevel(log.DebugLevel) logOptCount++ } if logOptCount > 1 { return errMsgIncompatibleLogOptions } else if logOptCount == 0 { // set info as a default log level log.SetLevel(log.InfoLevel) } if *args.logFile != "" { fd, err := os.Create(*args.logFile) if err != nil { return err } log.SetOutput(fd) } if *args.logModules != "" { modules := strings.Split(*args.logModules, ",") log.SetModuleFilter(modules) } if !*args.noSyslog { if err := log.AddSyslogHook(); err != nil { log.Warnf("Could not connect to syslog daemon: %s. "+ "(use -no-syslog to disable completely)", err.Error()) } } return nil }
func TestLoggingOptions(t *testing.T) { err := doMain([]string{"-commit", "-log-level", "crap"}) assert.Error(t, err, "'crap' log level should have given error") // Should have a reference to log level. assert.Contains(t, err.Error(), "Level") err = doMain([]string{"-info", "-log-level", "debug"}) assert.Error(t, err, "Incompatible log levels should have given error") assert.Contains(t, err.Error(), errMsgIncompatibleLogOptions.Error()) var buf bytes.Buffer oldOutput := log.Log.Out log.SetOutput(&buf) defer log.SetOutput(oldOutput) // Ignore errors for now, we just want to know if the logging level was // applied. log.SetLevel(log.DebugLevel) doMain([]string{"-log-level", "panic"}) log.Debugln("Should not show") doMain([]string{"-debug"}) log.Debugln("Should show") doMain([]string{"-info"}) log.Debugln("Should also not show") logdata := buf.String() assert.Contains(t, logdata, "Should show") assert.NotContains(t, logdata, "Should not show") assert.NotContains(t, logdata, "Should also not show") doMain([]string{"-log-modules", "main_test,MyModule"}) log.Errorln("Module filter should show main_test") log.PushModule("MyModule") log.Errorln("Module filter should show MyModule") log.PushModule("MyOtherModule") log.Errorln("Module filter should not show MyOtherModule") log.PopModule() log.PopModule() assert.True(t, strings.Index(buf.String(), "Module filter should show main_test") >= 0) assert.True(t, strings.Index(buf.String(), "Module filter should show MyModule") >= 0) assert.True(t, strings.Index(buf.String(), "Module filter should not show MyOtherModule") < 0) defer os.Remove("test.log") doMain([]string{"-log-file", "test.log"}) log.Errorln("Should be in log file") fd, err := os.Open("test.log") assert.NoError(t, err) var bytebuf [4096]byte n, err := fd.Read(bytebuf[:]) assert.True(t, err == nil) assert.True(t, strings.Index(string(bytebuf[0:n]), "Should be in log file") >= 0) err = doMain([]string{"-no-syslog"}) // Just check that the flag can be specified. assert.True(t, err != nil) assert.True(t, strings.Index(err.Error(), "syslog") < 0) }
func argsParse(args []string) (runOptionsType, error) { var runOptions runOptionsType parsing := flag.NewFlagSet("mender", flag.ContinueOnError) // FLAGS --------------------------------------------------------------- committing := parsing.Bool("commit", false, "Commit current update.") debug := parsing.Bool("debug", false, "Debug log level. This is a "+ "shorthand for '-l debug'.") info := parsing.Bool("info", false, "Info log level. This is a "+ "shorthand for '-l info'.") imageFile := parsing.String("rootfs", "", "Root filesystem URI to use for update. Can be either a local "+ "file or a URL.") logLevel := parsing.String("log-level", "", "Log level, which can be "+ "'debug', 'info', 'warning', 'error', 'fatal' or 'panic'. "+ "Earlier log levels will also log the subsequent levels (so "+ "'debug' will log everything). The default log level is "+ "'warning'.") logModules := parsing.String("log-modules", "", "Filter logging by "+ "module. This is a comma separated list of modules to log, "+ "other modules will be omitted. To see which modules are "+ "available, take a look at a non-filtered log and select "+ "the modules appropriate for you.") noSyslog := parsing.Bool("no-syslog", false, "Disable logging to "+ "syslog. Note that debug message are never logged to syslog.") logFile := parsing.String("log-file", "", "File to log to.") // PARSING ------------------------------------------------------------- if err := parsing.Parse(args); err != nil { return runOptions, err } // FLAG LOGIC ---------------------------------------------------------- var logOptCount int = 0 if *logLevel != "" { level, err := log.ParseLevel(*logLevel) if err != nil { return runOptions, err } log.SetLevel(level) logOptCount += 1 } if *info { log.SetLevel(log.InfoLevel) logOptCount += 1 } if *debug { log.SetLevel(log.DebugLevel) logOptCount += 1 } if logOptCount > 1 { return runOptions, errMsgIncompatibleLogOptions } else if logOptCount == 0 { // Default log level. log.SetLevel(log.WarnLevel) } if *logFile != "" { fd, err := os.Create(*logFile) if err != nil { return runOptions, err } log.SetOutput(fd) } if *logModules != "" { modules := strings.Split(*logModules, ",") log.SetModuleFilter(modules) } if !*noSyslog { if err := log.AddSyslogHook(); err != nil { log.Warnf("Could not connect to syslog daemon: %s. "+ "(use -no-syslog to disable completely)", err.Error()) } } if *imageFile == "" && !*committing { return runOptions, errMsgNoArgumentsGiven } runOptions.imageFile = *imageFile runOptions.committing = *committing return runOptions, nil }