Vishal Rana пре 9 година
родитељ
комит
722aa12d41
3 измењених фајлова са 125 додато и 43 уклоњено
  1. 17 6
      glide.lock
  2. 96 31
      log/log.go
  3. 12 6
      log/log_test.go

+ 17 - 6
glide.lock

@@ -1,18 +1,29 @@
 hash: e55ed1b26ebd131b2a6f7bb5bcbac90529cccd68976513e2648f38fe55fdd807
-updated: 2016-04-24T08:29:37.021386935-07:00
+updated: 2016-06-08T15:29:54.93330773-07:00
 imports:
 - name: github.com/mattn/go-colorable
-  version: bc69d6cebca8dd5675346a34a1c545b67dc74d5e
+  version: 9056b7a9f2d1f2d96498d6d146acd1f9d5ed3d59
 - name: github.com/mattn/go-isatty
   version: 56b76bdf51f7708750eac80fa38b952bb9f32639
 - name: github.com/stretchr/testify
-  version: c5d7a69bf8a2c9c374798160849c071093e41dd1
+  version: 8d64eb7173c7753d6419fd4a9caf057398611364
   subpackages:
   - assert
 - name: github.com/valyala/fasttemplate
   version: 3b874956e03f1636d171bda64b130f9135f42cff
-- name: golang.org/x/sys
-  version: f64b50fbea64174967a8882830d621a18ee1548e
+- name: gopkg.in/bsm/ratelimit.v1
+  version: db14e161995a5177acef654cb0dd785e8ee8bc22
+- name: gopkg.in/mgo.v2
+  version: b6e2fa371e64216a45e61072a96d4e3859f169da
   subpackages:
-  - unix
+  - bson
+  - internal/sasl
+  - internal/scram
+- name: gopkg.in/redis.v3
+  version: 5183f8dcde9737db7583dbfa9881800dba26e3fa
+  subpackages:
+  - internal
+  - internal/consistenthash
+  - internal/hashtag
+  - internal/pool
 devImports: []

+ 96 - 31
log/log.go

@@ -23,7 +23,7 @@ import (
 type (
 	Logger struct {
 		prefix     string
-		level      uint8
+		level      Lvl
 		output     io.Writer
 		template   *fasttemplate.Template
 		levels     []string
@@ -32,11 +32,13 @@ type (
 		mutex      sync.Mutex
 	}
 
-	Fields map[string]interface{}
+	Lvl uint8
+
+	JSON map[string]interface{}
 )
 
 const (
-	DEBUG uint8 = iota
+	DEBUG Lvl = iota
 	INFO
 	WARN
 	ERROR
@@ -46,15 +48,15 @@ const (
 
 var (
 	global        = New("-")
-	defaultFormat = `{"time":"${time_rfc3339}","level":"${level}","prefix":"${prefix}",` +
-		`"file":"${short_file}","line":"${line}","message":"${message}"}` + "\n"
+	defaultHeader = `{"time":"${time_rfc3339}","level":"${level}","prefix":"${prefix}",` +
+		`"file":"${short_file}","line":"${line}"}`
 )
 
 func New(prefix string) (l *Logger) {
 	l = &Logger{
 		level:    INFO,
 		prefix:   prefix,
-		template: l.newTemplate(defaultFormat),
+		template: l.newTemplate(defaultHeader),
 		color:    color.New(),
 		bufferPool: sync.Pool{
 			New: func() interface{} {
@@ -99,11 +101,11 @@ func (l *Logger) SetPrefix(p string) {
 	l.prefix = p
 }
 
-func (l *Logger) Level() uint8 {
+func (l *Logger) Level() Lvl {
 	return l.level
 }
 
-func (l *Logger) SetLevel(v uint8) {
+func (l *Logger) SetLevel(v Lvl) {
 	l.level = v
 }
 
@@ -111,8 +113,8 @@ func (l *Logger) Output() io.Writer {
 	return l.output
 }
 
-func (l *Logger) SetFormat(f string) {
-	l.template = l.newTemplate(f)
+func (l *Logger) SetHeader(h string) {
+	l.template = l.newTemplate(h)
 }
 
 func (l *Logger) SetOutput(w io.Writer) {
@@ -131,6 +133,10 @@ func (l *Logger) Printf(format string, args ...interface{}) {
 	fmt.Fprintf(l.output, f, args...)
 }
 
+func (l *Logger) Printj(j JSON) {
+	json.NewEncoder(l.output).Encode(j)
+}
+
 func (l *Logger) Debug(i ...interface{}) {
 	l.log(DEBUG, "", i...)
 }
@@ -139,6 +145,10 @@ func (l *Logger) Debugf(format string, args ...interface{}) {
 	l.log(DEBUG, format, args...)
 }
 
+func (l *Logger) Debugj(j JSON) {
+	l.log(DEBUG, "json", j)
+}
+
 func (l *Logger) Info(i ...interface{}) {
 	l.log(INFO, "", i...)
 }
@@ -147,6 +157,10 @@ func (l *Logger) Infof(format string, args ...interface{}) {
 	l.log(INFO, format, args...)
 }
 
+func (l *Logger) Infoj(j JSON) {
+	l.log(INFO, "json", j)
+}
+
 func (l *Logger) Warn(i ...interface{}) {
 	l.log(WARN, "", i...)
 }
@@ -155,6 +169,10 @@ func (l *Logger) Warnf(format string, args ...interface{}) {
 	l.log(WARN, format, args...)
 }
 
+func (l *Logger) Warnj(j JSON) {
+	l.log(WARN, "json", j)
+}
+
 func (l *Logger) Error(i ...interface{}) {
 	l.log(ERROR, "", i...)
 }
@@ -163,6 +181,10 @@ func (l *Logger) Errorf(format string, args ...interface{}) {
 	l.log(ERROR, format, args...)
 }
 
+func (l *Logger) Errorj(j JSON) {
+	l.log(ERROR, "json", j)
+}
+
 func (l *Logger) Fatal(i ...interface{}) {
 	l.log(FATAL, "", i...)
 	os.Exit(1)
@@ -173,6 +195,10 @@ func (l *Logger) Fatalf(format string, args ...interface{}) {
 	os.Exit(1)
 }
 
+func (l *Logger) Fatalj(j JSON) {
+	l.log(FATAL, "json", j)
+}
+
 func DisableColor() {
 	global.DisableColor()
 }
@@ -189,11 +215,11 @@ func SetPrefix(p string) {
 	global.SetPrefix(p)
 }
 
-func Level() uint8 {
+func Level() Lvl {
 	return global.Level()
 }
 
-func SetLevel(v uint8) {
+func SetLevel(v Lvl) {
 	global.SetLevel(v)
 }
 
@@ -205,8 +231,8 @@ func SetOutput(w io.Writer) {
 	global.SetOutput(w)
 }
 
-func SetFormat(f string) {
-	global.SetFormat(f)
+func SetHeader(h string) {
+	global.SetHeader(h)
 }
 
 func Print(i ...interface{}) {
@@ -217,6 +243,10 @@ func Printf(format string, args ...interface{}) {
 	global.Printf(format, args...)
 }
 
+func Printj(j JSON) {
+	global.Printj(j)
+}
+
 func Debug(i ...interface{}) {
 	global.Debug(i...)
 }
@@ -225,6 +255,10 @@ func Debugf(format string, args ...interface{}) {
 	global.Debugf(format, args...)
 }
 
+func Debugj(j JSON) {
+	global.Debugj(j)
+}
+
 func Info(i ...interface{}) {
 	global.Info(i...)
 }
@@ -233,6 +267,10 @@ func Infof(format string, args ...interface{}) {
 	global.Infof(format, args...)
 }
 
+func Infoj(j JSON) {
+	global.Infoj(j)
+}
+
 func Warn(i ...interface{}) {
 	global.Warn(i...)
 }
@@ -241,6 +279,10 @@ func Warnf(format string, args ...interface{}) {
 	global.Warnf(format, args...)
 }
 
+func Warnj(j JSON) {
+	global.Warnj(j)
+}
+
 func Error(i ...interface{}) {
 	global.Error(i...)
 }
@@ -249,6 +291,10 @@ func Errorf(format string, args ...interface{}) {
 	global.Errorf(format, args...)
 }
 
+func Errorj(j JSON) {
+	global.Errorj(j)
+}
+
 func Fatal(i ...interface{}) {
 	global.Fatal(i...)
 }
@@ -257,7 +303,11 @@ func Fatalf(format string, args ...interface{}) {
 	global.Fatalf(format, args...)
 }
 
-func (l *Logger) log(v uint8, format string, args ...interface{}) {
+func Fatalj(j JSON) {
+	global.Fatalj(j)
+}
+
+func (l *Logger) log(v Lvl, format string, args ...interface{}) {
 	l.mutex.Lock()
 	defer l.mutex.Unlock()
 	buf := l.bufferPool.Get().(*bytes.Buffer)
@@ -269,14 +319,20 @@ func (l *Logger) log(v uint8, format string, args ...interface{}) {
 		message := ""
 		if format == "" {
 			message = fmt.Sprint(args...)
+		} else if format == "json" {
+			b, err := json.Marshal(args[0])
+			if err != nil {
+				panic(err)
+			}
+			message = string(b)
 		} else {
 			message = fmt.Sprintf(format, args...)
 		}
-		if v == FATAL {
-			stack := make([]byte, 4<<10)
-			length := runtime.Stack(stack, true)
-			message = message + "\n" + string(stack[:length])
+
+		if v >= ERROR {
+			// panic(message)
 		}
+
 		_, err := l.template.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
 			switch tag {
 			case "time_rfc3339":
@@ -291,22 +347,31 @@ func (l *Logger) log(v uint8, format string, args ...interface{}) {
 				return w.Write([]byte(path.Base(file)))
 			case "line":
 				return w.Write([]byte(strconv.Itoa(line)))
-			case "message":
-				return w.Write([]byte(message))
-			default:
-				return w.Write([]byte(fmt.Sprintf("[unknown tag %s]", tag)))
 			}
+			return 0, nil
 		})
+
 		if err == nil {
+			s := buf.String()
+			i := buf.Len() - 1
+			if s[i] == '}' {
+				// JSON header
+				buf.Truncate(i)
+				buf.WriteByte(',')
+				if format == "json" {
+					buf.WriteString(message[1:])
+				} else {
+					buf.WriteString(`"message":"`)
+					buf.WriteString(message)
+					buf.WriteString(`"}`)
+				}
+			} else {
+				// Text header
+				buf.WriteByte(' ')
+				buf.WriteString(message)
+			}
+			buf.WriteByte('\n')
 			l.output.Write(buf.Bytes())
 		}
 	}
 }
-
-func JSON(f Fields) string {
-	s, err := json.Marshal(f)
-	if err != nil {
-		panic(err)
-	}
-	return string(s)
-}

+ 12 - 6
log/log_test.go

@@ -89,19 +89,25 @@ func loggerFatalTest(t *testing.T, env string, contains string) {
 	t.Fatalf("process ran with err %v, want exit status 1", err)
 }
 
+func TestNoFormat(t *testing.T) {
+}
+
 func TestFormat(t *testing.T) {
 	l := New("test")
-	l.SetFormat("${level} | ${message}")
+	l.SetHeader("${level} | ${prefix}")
 	b := new(bytes.Buffer)
 	l.SetOutput(b)
-	l.Info("test")
-	assert.Equal(t, "INFO | test", b.String())
+	l.Info("info")
+	assert.Equal(t, "INFO | test info\n", b.String())
 }
 
 func TestJSON(t *testing.T) {
-	Info(JSON(Fields{
-		"foo": "bar",
-	}))
+	l := New("test")
+	b := new(bytes.Buffer)
+	l.SetOutput(b)
+	l.SetLevel(DEBUG)
+	l.Debugj(JSON{"name": "value"})
+	assert.Contains(t, b.String(), `"name":"value"`)
 }
 
 func BenchmarkLog(b *testing.B) {