[chore] simplify generating log entry caller information (#863)
* vastly simplify logging caller information Signed-off-by: kim <grufwub@gmail.com> * fix failing test due to multiple calls to processor.Start() Signed-off-by: kim <grufwub@gmail.com> Signed-off-by: kim <grufwub@gmail.com>
This commit is contained in:
parent
a156188b3e
commit
2f22780800
|
@ -292,15 +292,6 @@ func (suite *InboxPostTestSuite) TestPostUpdate() {
|
||||||
federator := testrig.NewTestFederator(suite.db, tc, suite.storage, suite.mediaManager, fedWorker)
|
federator := testrig.NewTestFederator(suite.db, tc, suite.storage, suite.mediaManager, fedWorker)
|
||||||
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
|
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
|
||||||
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender, suite.mediaManager, clientWorker, fedWorker)
|
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender, suite.mediaManager, clientWorker, fedWorker)
|
||||||
if err := processor.Start(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := processor.Stop(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
userModule := user.New(processor).(*user.Module)
|
userModule := user.New(processor).(*user.Module)
|
||||||
suite.NoError(processor.Start())
|
suite.NoError(processor.Start())
|
||||||
|
|
||||||
|
|
|
@ -21,69 +21,39 @@ package log
|
||||||
import (
|
import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// fnCache is a cache of PCs to their calculated function names.
|
|
||||||
fnCache = map[uintptr]string{}
|
|
||||||
|
|
||||||
// strCache is a cache of strings to the originally allocated version
|
|
||||||
// of that string contents. so we don't have hundreds of the same instances
|
|
||||||
// of string floating around in memory.
|
|
||||||
strCache = map[string]string{}
|
|
||||||
|
|
||||||
// cacheMu protects fnCache and strCache.
|
|
||||||
cacheMu sync.Mutex
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Caller fetches the calling function name, skipping 'depth'. Results are cached per PC.
|
// Caller fetches the calling function name, skipping 'depth'. Results are cached per PC.
|
||||||
func Caller(depth int) string {
|
func Caller(depth int) string {
|
||||||
var rpc [1]uintptr
|
var pcs [1]uintptr
|
||||||
|
|
||||||
// Fetch pcs of callers
|
// Fetch calling function using calldepth
|
||||||
n := runtime.Callers(depth, rpc[:])
|
_ = runtime.Callers(depth, pcs[:])
|
||||||
|
fn := runtime.FuncForPC(pcs[0])
|
||||||
|
|
||||||
if n > 0 {
|
if fn == nil {
|
||||||
// Look for value in cache
|
return ""
|
||||||
cacheMu.Lock()
|
|
||||||
fn, ok := fnCache[rpc[0]]
|
|
||||||
cacheMu.Unlock()
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
return fn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch frame info for caller pc
|
// return formatted name
|
||||||
frame, _ := runtime.CallersFrames(rpc[:]).Next()
|
return callername(fn)
|
||||||
|
}
|
||||||
|
|
||||||
if frame.PC != 0 {
|
// callername generates a human-readable calling function name.
|
||||||
name := frame.Function
|
func callername(fn *runtime.Func) string {
|
||||||
|
name := fn.Name()
|
||||||
|
|
||||||
// Drop all but the package name and function name, no mod path
|
// Drop all but the package name and function name, no mod path
|
||||||
if idx := strings.LastIndex(name, "/"); idx >= 0 {
|
if idx := strings.LastIndex(name, "/"); idx >= 0 {
|
||||||
name = name[idx+1:]
|
name = name[idx+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const params = `[...]`
|
||||||
|
|
||||||
// Drop any generic type parameter markers
|
// Drop any generic type parameter markers
|
||||||
if idx := strings.Index(name, "[...]"); idx >= 0 {
|
if idx := strings.Index(name, params); idx >= 0 {
|
||||||
name = name[:idx] + name[idx+5:]
|
name = name[:idx] + name[idx+len(params):]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache this func name
|
return name
|
||||||
cacheMu.Lock()
|
|
||||||
fn, ok := strCache[name]
|
|
||||||
if !ok {
|
|
||||||
// Cache ptr to this allocated str
|
|
||||||
strCache[name] = name
|
|
||||||
fn = name
|
|
||||||
}
|
|
||||||
fnCache[rpc[0]] = fn
|
|
||||||
cacheMu.Unlock()
|
|
||||||
|
|
||||||
return fn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "???"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package log_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"codeberg.org/gruf/go-atomics"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// noopt exists to prevent certain optimisations during benching.
|
|
||||||
var noopt = atomics.NewString()
|
|
||||||
|
|
||||||
func BenchmarkCaller(b *testing.B) {
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
|
||||||
for pb.Next() {
|
|
||||||
name := log.Caller(2)
|
|
||||||
noopt.Store(name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkCallerNoCache(b *testing.B) {
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
|
||||||
for pb.Next() {
|
|
||||||
var rpc [1]uintptr
|
|
||||||
|
|
||||||
// Fetch pcs of callers
|
|
||||||
n := runtime.Callers(2, rpc[:])
|
|
||||||
|
|
||||||
if n > 0 {
|
|
||||||
// Fetch frame info for caller pc
|
|
||||||
frame, _ := runtime.CallersFrames(rpc[:]).Next()
|
|
||||||
|
|
||||||
if frame.PC != 0 {
|
|
||||||
name := frame.Function
|
|
||||||
|
|
||||||
// Drop all but the package name and function name, no mod path
|
|
||||||
if idx := strings.LastIndex(name, "/"); idx >= 0 {
|
|
||||||
name = name[idx+1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop any generic type parameter markers
|
|
||||||
if idx := strings.Index(name, "[...]"); idx >= 0 {
|
|
||||||
name = name[:idx] + name[idx+5:]
|
|
||||||
}
|
|
||||||
|
|
||||||
noopt.Store(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
Reference in New Issue