docs: add godoc and bilingual README
This commit is contained in:
102
traceback.go
102
traceback.go
@@ -2,59 +2,83 @@ package slog
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getTraceback() *MethodTraceback {
|
||||
caller, _, _, _ := runtime.Caller(5)
|
||||
details := runtime.FuncForPC(caller)
|
||||
signature := details.Name()
|
||||
path, line := details.FileLine(caller)
|
||||
splitPath := strings.Split(path, "/")
|
||||
var internalTracebackMethods = map[string]struct{}{
|
||||
"Infof": {},
|
||||
"Info": {},
|
||||
"Infoln": {},
|
||||
"Warnf": {},
|
||||
"Warn": {},
|
||||
"Warnln": {},
|
||||
"Errorf": {},
|
||||
"Error": {},
|
||||
"Errorln": {},
|
||||
"Fatalf": {},
|
||||
"Fatal": {},
|
||||
"Fatalln": {},
|
||||
"Debugf": {},
|
||||
"Debug": {},
|
||||
"Debugln": {},
|
||||
"print": {},
|
||||
"println": {},
|
||||
"reportWriterError": {},
|
||||
"getTraceback": {},
|
||||
"getFullTraceback": {},
|
||||
}
|
||||
|
||||
func getTraceback() *MethodTraceback {
|
||||
tracebacks := getFullTraceback(0)
|
||||
if len(tracebacks) == 0 {
|
||||
return nil
|
||||
}
|
||||
return tracebacks[0]
|
||||
}
|
||||
|
||||
func getFullTraceback(skip int) []*MethodTraceback {
|
||||
pc := make([]uintptr, 15)
|
||||
n := runtime.Callers(skip+2, pc)
|
||||
list := make([]*MethodTraceback, 0)
|
||||
frames := runtime.CallersFrames(pc[:n])
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
tb := buildMethodTraceback(frame.PC)
|
||||
if tb != nil && !isInternalTraceback(tb) {
|
||||
list = append(list, tb)
|
||||
}
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func buildMethodTraceback(pc uintptr) *MethodTraceback {
|
||||
details := runtime.FuncForPC(pc)
|
||||
if details == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
signature := details.Name()
|
||||
path, line := details.FileLine(pc)
|
||||
splitPath := strings.Split(path, "/")
|
||||
splitSignature := strings.Split(signature, ".")
|
||||
method := splitSignature[len(splitSignature)-1]
|
||||
|
||||
tb := &MethodTraceback{
|
||||
return &MethodTraceback{
|
||||
Filename: splitPath[len(splitPath)-1],
|
||||
FullPath: path,
|
||||
Line: line,
|
||||
Signature: signature,
|
||||
Method: method,
|
||||
}
|
||||
|
||||
return tb
|
||||
}
|
||||
func getFullTraceback(skip int) []*MethodTraceback {
|
||||
pc := make([]uintptr, 15)
|
||||
runtime.Callers(skip, pc)
|
||||
list := make([]*MethodTraceback, 0)
|
||||
frames := runtime.CallersFrames(pc)
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
details := runtime.FuncForPC(frame.PC)
|
||||
signature := details.Name()
|
||||
path, line := details.FileLine(frame.PC)
|
||||
splitPath := strings.Split(path, "/")
|
||||
|
||||
splitSignature := strings.Split(signature, ".")
|
||||
method := splitSignature[len(splitSignature)-1]
|
||||
|
||||
tb := &MethodTraceback{
|
||||
Filename: splitPath[len(splitPath)-1],
|
||||
FullPath: path,
|
||||
Line: line,
|
||||
Signature: signature,
|
||||
Method: method,
|
||||
}
|
||||
list = append(list, tb)
|
||||
func isInternalTraceback(tb *MethodTraceback) bool {
|
||||
if strings.HasPrefix(tb.Signature, "runtime.") {
|
||||
return true
|
||||
}
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
return j < i
|
||||
})
|
||||
return list
|
||||
_, ok := internalTracebackMethods[tb.Method]
|
||||
return ok
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user