diff --git a/pkg/async/async.go b/pkg/async/async.go new file mode 100644 index 000000000..ac4b71abb --- /dev/null +++ b/pkg/async/async.go @@ -0,0 +1,24 @@ +package async + +import ( + "context" + + "github.com/go-eagle/eagle/pkg/log" + "github.com/go-eagle/eagle/pkg/utils" +) + +// Go 异步执行 asyncFunc() 函数,会进行 recover() 操作,如果出现 panic() 则会记录日志 +// name 用于 recover 后的日志和 metrics 统计 +func Go(ctx context.Context, name string, asyncFunc func()) { + go func() { + defer func() { + if err := recover(); err != nil { + stack := utils.StackTrace(name, err) + log.WithContext(ctx).Errorf("async: name: %s panic: %s stack: %s", name, err, stack) + // TODO: metrics + } + }() + + asyncFunc() + }() +} diff --git a/pkg/utils/debug.go b/pkg/utils/debug.go index 6518e8d2a..c05a7ac19 100644 --- a/pkg/utils/debug.go +++ b/pkg/utils/debug.go @@ -5,8 +5,8 @@ import ( "runtime" ) -// PrintStackTrace print stack info -func PrintStackTrace(msg string, err interface{}) string { +// StackTrace return stack info +func StackTrace(msg string, err interface{}) string { buf := make([]byte, 64*1024) buf = buf[:runtime.Stack(buf, false)] return fmt.Sprintf("%s, err: %s\nstack: %s", msg, err, buf) diff --git a/pkg/utils/debug_test.go b/pkg/utils/debug_test.go index ac0f8ba8c..211d29850 100644 --- a/pkg/utils/debug_test.go +++ b/pkg/utils/debug_test.go @@ -7,14 +7,14 @@ import ( func TestPrintStackTrace(t *testing.T) { t.Run("mock a error", func(t *testing.T) { - err := PrintStackTrace("mock a error", errors.New("throw a error")) + err := StackTrace("mock a error", errors.New("throw a error")) t.Log(err) }) t.Run("mock a recover", func(t *testing.T) { defer func() { if r := recover(); r != nil { - err := PrintStackTrace("mock a recover", r) + err := StackTrace("mock a recover", r) t.Log(err) } }() diff --git a/pkg/utils/string.go b/pkg/utils/string.go index 64fec4f7a..85312250d 100644 --- a/pkg/utils/string.go +++ b/pkg/utils/string.go @@ -5,6 +5,8 @@ import ( "strconv" "strings" "unsafe" + + jsoniter "github.com/json-iterator/go" ) // IsEmpty 是否是空字符串 @@ -94,3 +96,17 @@ func StringToBytes(s string) []byte { h := [3]uintptr{x[0], x[1], x[1]} return *(*[]byte)(unsafe.Pointer(&h)) } + +// 对于序列化和反序列化场景较多的服务可以使用性能更高的json-iterator +// https://github.com/json-iterator/go +var Json = jsoniter.Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, + UseNumber: true, +}.Froze() + +func Stringify(obj interface{}) string { + b, _ := Json.MarshalToString(obj) + return b +}