Skip to content

Commit

Permalink
internal/lg: make LogLevel a flag.Value; refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
mreiferson committed Mar 3, 2019
1 parent c888ddd commit ad5ed66
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 95 deletions.
2 changes: 2 additions & 0 deletions internal/app/float_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

type FloatArray []float64

func (a *FloatArray) Get() interface{} { return []float64(*a) }

func (a *FloatArray) Set(param string) error {
for _, s := range strings.Split(param, ",") {
v, err := strconv.ParseFloat(s, 64)
Expand Down
2 changes: 2 additions & 0 deletions internal/app/string_array.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (

type StringArray []string

func (a *StringArray) Get() interface{} { return []string(*a) }

func (a *StringArray) Set(s string) error {
*a = append(*a, s)
return nil
Expand Down
52 changes: 28 additions & 24 deletions internal/lg/lg.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"strings"
)

type LogLevel int

const (
DEBUG = LogLevel(1)
INFO = LogLevel(2)
Expand All @@ -30,43 +28,49 @@ func (l NilLogger) Output(maxdepth int, s string) error {
return nil
}

func (l LogLevel) String() string {
switch l {
case 1:
type LogLevel int

func (l *LogLevel) Get() interface{} { return *l }

func (l *LogLevel) Set(s string) error {
lvl, err := ParseLogLevel(s)
if err != nil {
return err
}
*l = lvl
return nil
}

func (l *LogLevel) String() string {
switch *l {
case DEBUG:
return "DEBUG"
case 2:
case INFO:
return "INFO"
case 3:
case WARN:
return "WARNING"
case 4:
case ERROR:
return "ERROR"
case 5:
case FATAL:
return "FATAL"
}
panic("invalid LogLevel")
return "invalid"
}

func ParseLogLevel(levelstr string, verbose bool) (LogLevel, error) {
lvl := INFO

func ParseLogLevel(levelstr string) (LogLevel, error) {
switch strings.ToLower(levelstr) {
case "debug":
lvl = DEBUG
return DEBUG, nil
case "info":
lvl = INFO
return INFO, nil
case "warn":
lvl = WARN
return WARN, nil
case "error":
lvl = ERROR
return ERROR, nil
case "fatal":
lvl = FATAL
default:
return lvl, fmt.Errorf("invalid log-level '%s'", levelstr)
}
if verbose {
lvl = DEBUG
return FATAL, nil
}
return lvl, nil
return 0, fmt.Errorf("invalid log level '%s' (debug, info, warn, error, fatal)", levelstr)
}

func Logf(logger Logger, cfgLevel LogLevel, msgLevel LogLevel, f string, args ...interface{}) {
Expand Down
74 changes: 3 additions & 71 deletions internal/lg/lg_test.go
Original file line number Diff line number Diff line change
@@ -1,53 +1,11 @@
package lg

import (
"log"
"os"
"testing"

"github.com/nsqio/nsq/internal/test"
)

type options struct {
LogLevel string `flag:"log-level"`
Verbose bool `flag:"verbose"` // for backwards compatibility
Logger Logger
logLevel LogLevel // private, not really an option
}

func newOptions() *options {
return &options{
LogLevel: "info",
}
}

type app struct {
opts *options
}

func (n *app) logf(level LogLevel, f string, args ...interface{}) {
Logf(n.opts.Logger, n.opts.logLevel, level, f, args)
}

func newApp(opts *options) *app {
if opts.Logger == nil {
opts.Logger = log.New(os.Stderr, "[app] ", log.Ldate|log.Ltime|log.Lmicroseconds)
}
n := &app{
opts: opts,
}

var err error
opts.logLevel, err = ParseLogLevel(opts.LogLevel, opts.Verbose)
if err != nil {
n.logf(FATAL, "%s", err)
os.Exit(1)
}

n.logf(INFO, "app 0.1")
return n
}

type mockLogger struct {
Count int
}
Expand All @@ -59,51 +17,25 @@ func (l *mockLogger) Output(maxdepth int, s string) error {

func TestLogging(t *testing.T) {
logger := &mockLogger{}
opts := newOptions()
opts.Logger = logger

// Test only fatal get through
opts.LogLevel = "FaTaL"
nsqd := newApp(opts)
logger.Count = 0
for i := 1; i <= 5; i++ {
nsqd.logf(LogLevel(i), "Test")
Logf(logger, FATAL, LogLevel(i), "Test")
}
test.Equal(t, 1, logger.Count)

// Test only warnings or higher get through
opts.LogLevel = "WARN"
nsqd = newApp(opts)
logger.Count = 0
for i := 1; i <= 5; i++ {
nsqd.logf(LogLevel(i), "Test")
Logf(logger, WARN, LogLevel(i), "Test")
}
test.Equal(t, 3, logger.Count)

// Test everything gets through
opts.LogLevel = "debuG"
nsqd = newApp(opts)
logger.Count = 0
for i := 1; i <= 5; i++ {
nsqd.logf(LogLevel(i), "Test")
}
test.Equal(t, 5, logger.Count)

// Test everything gets through with verbose = true
opts.LogLevel = "fatal"
opts.Verbose = true
nsqd = newApp(opts)
logger.Count = 0
for i := 1; i <= 5; i++ {
nsqd.logf(LogLevel(i), "Test")
Logf(logger, DEBUG, LogLevel(i), "Test")
}
test.Equal(t, 5, logger.Count)
}

func TestNoLogger(t *testing.T) {
opts := newOptions()
opts.Logger = NilLogger{}
app := newApp(opts)

app.logf(ERROR, "should never be logged")
}

0 comments on commit ad5ed66

Please sign in to comment.