Denmaseno 9 vuotta sitten
vanhempi
commit
21f579b555
4 muutettua tiedostoa jossa 182 lisäystä ja 58 poistoa
  1. 119 0
      dump.go
  2. 38 0
      dump_test.go
  3. 23 56
      log.go
  4. 2 2
      log_test.go

+ 119 - 0
dump.go

@@ -0,0 +1,119 @@
+package log
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"strings"
+
+	util "github.com/senomas/go-util"
+)
+
+const (
+	// MaxFieldLen const
+	MaxFieldLen = 100
+	// MaxSliceLen const
+	MaxSliceLen = 100
+	tabSpace    = "  "
+)
+
+// Dump value
+func Dump(v interface{}) string {
+	var bb bytes.Buffer
+	fdump(&bb, 0, 0, "", reflect.ValueOf(v))
+	return bb.String()
+}
+
+// Fdump value
+// func Fdump(w io.Writer, v interface{}) {
+// 	fdump(w, 0, 0, "", reflect.ValueOf(v), "", "")
+// }
+
+func fdump(w io.Writer, rx int, rd int, tab string, value reflect.Value) {
+	rx++
+	if rx > 100 {
+		fmt.Fprint(w, "/* too many recursive */")
+	}
+	if rd > 10 {
+		fmt.Fprint(w, "/* too deep */")
+	}
+	if value.Kind() == reflect.Interface && !value.IsNil() {
+		elm := value.Elem()
+		if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
+			value = elm
+		}
+	}
+	if value.Kind() == reflect.Ptr {
+		value = value.Elem()
+	}
+	if value.Kind() == reflect.String {
+		fmt.Fprintf(w, "\"%s\" /* Type:%s */", value, value.Type().String())
+	} else if kindIn(value.Kind(), reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64) {
+		fmt.Fprintf(w, "%+v /* Type:%s */", value, value.Type().String())
+	} else if kindIn(value.Kind(), reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64) {
+		fmt.Fprintf(w, "%+v /* Type:%s */", value, value.Type().String())
+	} else if value.Kind() == reflect.Struct {
+		ntab := tab + tabSpace
+		fmt.Fprintf(w, "{")
+		il := value.NumField()
+		for i, j := 0, 0; i < il && i < MaxFieldLen; i++ {
+			tf := value.Type().Field(i)
+			tag := strings.Split(value.Type().Field(i).Tag.Get("dump"), ",")
+			if !util.InStringSlice("ignore", tag...) {
+				if j > 0 {
+					fmt.Fprintf(w, ",\n%s\"%s\": ", ntab, tf.Name)
+				} else {
+					fmt.Fprintf(w, "\n%s\"%s\": ", ntab, tf.Name)
+				}
+				vf := value.Field(i)
+				fdump(w, rx, rd+1, ntab, vf)
+				j++
+			}
+		}
+		fmt.Fprintf(w, "\n%s}", tab)
+	} else if value.Kind() == reflect.Slice {
+		ntab := tab + tabSpace
+		fmt.Fprintf(w, "[ /* Type:%s Length:%v */\n%s", value.Type().String(), value.Len(), ntab)
+		il := value.Len()
+		for i := 0; i < il && i < MaxSliceLen; i++ {
+			vi := value.Index(i)
+			if i > 0 {
+				fmt.Fprintf(w, ",\n%s/* Index:%v */ ", ntab, i)
+			} else {
+				fmt.Fprint(w, "/* Index:0 */ ")
+			}
+			fdump(w, rx, rd+1, ntab, vi)
+		}
+		if il > MaxSliceLen {
+			fmt.Fprintf(w, "\n%s/* too many items */", ntab)
+		}
+		fmt.Fprintf(w, "\n%s]%s", tab, "")
+		// } else if value.CanInterface() {
+		// 	fmt.Fprintf(w, "%+v \\\\ Type:%s", value.Interface(), value.Type().String())
+	} else if value.Kind() == reflect.Map {
+		ntab := tab + tabSpace
+		fmt.Fprintf(w, "{ /* Type:%s */\n%s", value.Type().String(), ntab)
+		keys := value.MapKeys()
+		for k, kv := range keys {
+			if k > 0 {
+				fmt.Fprintf(w, ",\n%s\"%v\": ", ntab, kv)
+			} else {
+				fmt.Fprintf(w, "\"%v\": ", kv)
+			}
+			fdump(w, rx, rd+1, ntab, value.MapIndex(kv))
+		}
+		fmt.Fprintf(w, "\n%s}%s", tab, "")
+	} else {
+		fmt.Fprintf(w, "undefined /* Type:%s Value:[%v] */", value.Type().String(), value)
+	}
+}
+
+func kindIn(value reflect.Kind, list ...reflect.Kind) bool {
+	for _, v := range list {
+		if value == v {
+			return true
+		}
+	}
+	return false
+}

+ 38 - 0
dump_test.go

@@ -0,0 +1,38 @@
+package log
+
+import (
+	"fmt"
+	"testing"
+)
+
+type Struct1 struct {
+	Name   string
+	secret string `dump:"ignore"`
+	Codes  []string
+	Config map[string]*Address
+	Age    uint
+}
+
+type Address struct {
+	Street string
+	City   string
+}
+
+func (address Address) String() string {
+	return Dump(address)
+}
+
+// TestDump test
+func TestDump(t *testing.T) {
+	t.Logf("dump string(TEST) %s\n", Dump("TEST"))
+	t.Logf("dump int(12) %s\n", Dump(12))
+	config := make(map[string]*Address)
+	config["kampung"] = &Address{"Jalan", "Solo"}
+	config["rumah"] = &Address{"Kampret1", "Jakarta"}
+	config["kantor"] = &Address{"Kampret2", "Jakarta"}
+	t.Logf("dump Struct1{}\n%s\n", Dump(Struct1{"seno", "secret",
+		[]string{"sono", "keling"},
+		config,
+		17}))
+	t.Logf("fmt.Sprintf %s", fmt.Sprintf("HERE\n%v", &Address{"seno", "solo"}))
+}

+ 23 - 56
log.go

@@ -2,7 +2,6 @@ package log
 
 import (
 	"fmt"
-	"github.com/davecgh/go-spew/spew"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -32,41 +31,9 @@ const (
 	FATAL = 5
 )
 
-// Stringer interface
-type Stringer interface {
-	LogString() string
-}
-
-// Init logger
-func Init(plevel int) {
-	level = plevel
-	spew.Config.DisableMethods = true
-	spew.Config.Indent = "   "
-}
-
-// Dumpf object
-func Dumpf(format string, a ...interface{}) string {
-	return spew.Sprintf(format, a...)
-}
-
-// Dump object
-func Dump(a ...interface{}) string {
-	return spew.Sdump(a...)
-}
-
-func dump(a ...interface{}) []interface{} {
-	for ai, av := range a {
-		if avf, ok := av.(func() string); ok {
-			a[ai] = avf()
-		} else if avf, ok := av.(Stringer); ok {
-			a[ai] = avf.LogString()
-		} else if avf, ok := av.(fmt.GoStringer); ok {
-			a[ai] = avf.GoString()
-		} else if avf, ok := av.(fmt.Stringer); ok {
-			a[ai] = avf.String()
-		}
-	}
-	return a
+// IsDebugEnable func
+func IsDebugEnable() bool {
+	return level <= DEBUG
 }
 
 // Trace log
@@ -78,7 +45,7 @@ func Trace(a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+					fmt.Fprintf(os.Stderr, "TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 					return
 				}
 			} else {
@@ -87,7 +54,7 @@ func Trace(a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+		fmt.Printf("TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 	}
 }
 
@@ -100,7 +67,7 @@ func Tracef(format string, a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+					fmt.Fprintf(os.Stderr, "TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 					return
 				}
 			} else {
@@ -109,7 +76,7 @@ func Tracef(format string, a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+		fmt.Printf("TRACE: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 	}
 }
 
@@ -122,7 +89,7 @@ func Debug(a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+					fmt.Fprintf(os.Stderr, "DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 					return
 				}
 			} else {
@@ -131,7 +98,7 @@ func Debug(a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+		fmt.Printf("DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 	}
 }
 
@@ -144,7 +111,7 @@ func Debugf(format string, a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+					fmt.Fprintf(os.Stderr, "DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 					return
 				}
 			} else {
@@ -153,7 +120,7 @@ func Debugf(format string, a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+		fmt.Printf("DEBUG: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 	}
 }
 
@@ -166,7 +133,7 @@ func Info(a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+					fmt.Fprintf(os.Stderr, "INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 					return
 				}
 			} else {
@@ -175,7 +142,7 @@ func Info(a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+		fmt.Printf("INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 	}
 }
 
@@ -188,7 +155,7 @@ func Infof(format string, a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+					fmt.Fprintf(os.Stderr, "INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 					return
 				}
 			} else {
@@ -197,7 +164,7 @@ func Infof(format string, a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+		fmt.Printf("INFO: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 	}
 }
 
@@ -210,7 +177,7 @@ func Warning(a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+					fmt.Fprintf(os.Stderr, "WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 					return
 				}
 			} else {
@@ -219,7 +186,7 @@ func Warning(a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+		fmt.Printf("WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 	}
 }
 
@@ -232,7 +199,7 @@ func Warningf(format string, a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+					fmt.Fprintf(os.Stderr, "WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 					return
 				}
 			} else {
@@ -241,7 +208,7 @@ func Warningf(format string, a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Printf("WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+		fmt.Printf("WARN: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 	}
 }
 
@@ -254,7 +221,7 @@ func Error(a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+					fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 					return
 				}
 			} else {
@@ -263,7 +230,7 @@ func Error(a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(dump(a...)...))
+		fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprint(a...))
 	}
 }
 
@@ -276,7 +243,7 @@ func Errorf(format string, a ...interface{}) {
 				if strings.HasSuffix(path, "/libexec/src/runtime/panic.go") {
 					_, path, line, _ := runtime.Caller(i + 1)
 					_, file := filepath.Split(path)
-					fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+					fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 					return
 				}
 			} else {
@@ -285,6 +252,6 @@ func Errorf(format string, a ...interface{}) {
 		}
 		_, path, line, _ := runtime.Caller(1)
 		_, file := filepath.Split(path)
-		fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, dump(a...)...))
+		fmt.Fprintf(os.Stderr, "ERROR: %s %v:%v: %s\n", time.Now().Format("01:04:05.000"), file, line, fmt.Sprintf(format, a...))
 	}
 }

+ 2 - 2
log_test.go

@@ -4,8 +4,8 @@ import (
 	"testing"
 )
 
-// TestSimple1 test
-func TestSimple1(t *testing.T) {
+// TestLogger test
+func TestLogger(t *testing.T) {
 	t.Log("test simple1")
 
 	var fx func() string