Bladeren bron

Enable color only for stdout if it supports

Signed-off-by: Vishal Rana <vr@labstack.com>
Vishal Rana 10 jaren geleden
bovenliggende
commit
1e3c62a3d8
5 gewijzigde bestanden met toevoegingen van 123 en 64 verwijderingen
  1. 14 13
      gytes/gytes.go
  2. 1 0
      log/.envrc
  3. 1 0
      log/README.md
  4. 98 49
      log/log.go
  5. 9 2
      log/log_test.go

+ 14 - 13
gytes/gytes.go

@@ -35,26 +35,27 @@ func (g *Gytes) Format(b uint64) string {
 	}
 	if b < unit {
 		return strconv.FormatUint(b, 10) + " B"
-	} else {
-		b := float64(b)
-		unit := float64(unit)
-		x := math.Floor(math.Log(b) / math.Log(unit))
-		pre := make([]byte, 1, 2)
-		pre[0] = "KMGTPE"[uint8(x)-1]
-		if g.iec {
-			pre = pre[:2]
-			pre[1] = 'i'
-		}
-		// TODO: Improve performance?
-		return fmt.Sprintf("%.02f %sB", b/math.Pow(unit, x), pre)
 	}
+	bb := float64(b)
+	uu := float64(unit)
+	x := math.Floor(math.Log(bb) / math.Log(uu))
+	pre := make([]byte, 1, 2)
+	pre[0] = "KMGTPE"[uint8(x)-1]
+	if g.iec {
+		pre = pre[:2]
+		pre[1] = 'i'
+	}
+	// TODO: Improve performance?
+	return fmt.Sprintf("%.02f %sB", bb/math.Pow(uu, x), pre)
+
 }
 
+// BinaryPrefix wraps global Gytes's BinaryPrefix function.
 func BinaryPrefix(on bool) {
 	global.SetBinaryPrefix(on)
 }
 
-// Format wraps default instance's Format function.
+// Format wraps global Gytes's Format function.
 func Format(b uint64) string {
 	return global.Format(b)
 }

+ 1 - 0
log/.envrc

@@ -0,0 +1 @@
+export GOPATH=$GOPATH:`pwd`

+ 1 - 0
log/README.md

@@ -0,0 +1 @@
+# WORK IN PROGRESS!

+ 98 - 49
log/log.go

@@ -1,41 +1,41 @@
 package log
 
 import (
-	"bytes"
 	"fmt"
 	"io"
 	"os"
-	"runtime"
 	"sync"
 
 	"github.com/labstack/gommon/color"
+	"github.com/mattn/go-colorable"
+	"github.com/mattn/go-isatty"
 )
 
 type (
-	Log struct {
+	Logger struct {
 		level  Level
 		out    io.Writer
 		err    io.Writer
 		prefix string
 		sync.Mutex
-		color color.Color
-		lock  bool
+		// lock bool
 	}
 	Level uint8
 )
 
 const (
-	Trace = iota
-	Debug
-	Info
-	Notice
-	Warn
-	Error
-	Fatal
-	Off = 10
+	trace = iota
+	debug
+	info
+	notice
+	warn
+	err
+	fatal
+	off = 10
 )
 
 var (
+	global = New("-")
 	levels = []string{
 		color.Cyan("TRACE"),
 		color.Blue("DEBUG"),
@@ -47,72 +47,121 @@ var (
 	}
 )
 
-func New(prefix string) (l *Log) {
-	l = &Log{
-		level:  Debug,
-		out:    os.Stdout,
-		err:    os.Stderr,
+func New(prefix string) (l *Logger) {
+	l = &Logger{
+		level:  info,
+		out:    colorable.NewColorableStdout(),
+		err:    colorable.NewColorableStderr(),
 		prefix: prefix,
 	}
-	if runtime.GOOS == "windows" {
-		l.lock = true
-		color.Disable()
+
+	if isatty.IsTerminal(os.Stdout.Fd()) {
+		color.Enable()
 	}
+
 	return
 }
 
-func (l *Log) SetLevel(v Level) {
+func (l *Logger) SetPrefix(p string) {
+	l.prefix = p
+}
+
+func (l *Logger) SetLevel(v Level) {
 	l.level = v
 }
 
-func (l *Log) SetOutput(w io.Writer) {
+func (l *Logger) SetOutput(w io.Writer) {
 	l.out = w
 	l.err = w
 
-	switch w.(type) {
+	switch w := w.(type) {
 	case *os.File:
-	case *bytes.Buffer:
-		l.lock = true
-		color.Disable()
-	default:
-		l.lock = false
+		if isatty.IsTerminal(w.Fd()) {
+			color.Enable()
+		}
 	}
 }
 
-func (l *Log) Trace(i interface{}) {
-	l.log(Trace, l.out, i)
+func (l *Logger) Trace(msg interface{}, args ...interface{}) {
+	l.log(trace, l.out, msg, args...)
 }
 
-func (l *Log) Debug(i interface{}) {
-	l.log(Debug, l.out, i)
+func (l *Logger) Debug(msg interface{}, args ...interface{}) {
+	l.log(debug, l.out, msg, args...)
 }
 
-func (l *Log) Info(i interface{}) {
-	l.log(Info, l.out, i)
+func (l *Logger) Info(msg interface{}, args ...interface{}) {
+	l.log(info, l.out, msg, args...)
 }
 
-func (l *Log) Notice(i interface{}) {
-	l.log(Notice, l.out, i)
+func (l *Logger) Notice(msg interface{}, args ...interface{}) {
+	l.log(notice, l.out, msg, args...)
 }
 
-func (l *Log) Warn(i interface{}) {
-	l.log(Warn, l.out, i)
+func (l *Logger) Warn(msg interface{}, args ...interface{}) {
+	l.log(warn, l.out, msg, args...)
 }
 
-func (l *Log) Error(i interface{}) {
-	l.log(Error, l.err, i)
+func (l *Logger) Error(msg interface{}, args ...interface{}) {
+	l.log(err, l.err, msg, args...)
 }
 
-func (l *Log) Fatal(i interface{}) {
-	l.log(Fatal, l.err, i)
+func (l *Logger) Fatal(msg interface{}, args ...interface{}) {
+	l.log(fatal, l.err, msg, args...)
 }
 
-func (l *Log) log(v Level, w io.Writer, i interface{}) {
-	if l.lock {
-		l.Lock()
-		defer l.Unlock()
-	}
+func SetPrefix(p string) {
+	global.SetPrefix(p)
+}
+
+func SetLevel(v Level) {
+	global.SetLevel(v)
+}
+
+func SetOutput(w io.Writer) {
+	global.SetOutput(w)
+}
+
+func Trace(msg interface{}, args ...interface{}) {
+	global.Trace(msg, args...)
+}
+
+func Debug(msg interface{}, args ...interface{}) {
+	global.Debug(msg, args...)
+}
+
+func Info(msg interface{}, args ...interface{}) {
+	global.Info(msg, args...)
+}
+
+func Notice(msg interface{}, args ...interface{}) {
+	global.Notice(msg, args...)
+}
+
+func Warn(msg interface{}, args ...interface{}) {
+	global.Warn(msg, args...)
+}
+
+func Error(msg interface{}, args ...interface{}) {
+	global.Error(msg, args...)
+}
+
+func Fatal(msg interface{}, args ...interface{}) {
+	global.Fatal(msg, args...)
+}
+
+func (l *Logger) log(v Level, w io.Writer, msg interface{}, args ...interface{}) {
+	// if l.lock {
+	l.Lock()
+	defer l.Unlock()
+	// }
 	if v >= l.level {
-		fmt.Fprintf(w, "%s|%s|%v\n", levels[v], l.prefix, i)
+		// TODO: Improve performance
+		f := fmt.Sprintf("%s|%s|%s\n", levels[v], l.prefix, msg)
+		fmt.Fprintf(w, f, args...)
 	}
 }
+
+func init() {
+	color.Disable()
+}

+ 9 - 2
log/log_test.go

@@ -3,8 +3,15 @@ package log
 import "testing"
 
 func TestLog(t *testing.T) {
-	l := New("log")
-	l.SetLevel(Trace)
+	l := New("test")
+	test(l, trace, t)
+	test(global, trace, t)
+	test(l, notice, t)
+	test(global, notice, t)
+}
+
+func test(l *Logger, v Level, t *testing.T) {
+	l.SetLevel(trace)
 	l.Trace("trace")
 	l.Debug("debug")
 	l.Info("info")