116 lines
2.3 KiB
Go
116 lines
2.3 KiB
Go
|
/*
|
||
|
* trace.go
|
||
|
*
|
||
|
* Copyright 2017 Bill Zissimopoulos
|
||
|
*/
|
||
|
/*
|
||
|
* This file is part of Cgofuse.
|
||
|
*
|
||
|
* It is licensed under the MIT license. The full license text can be found
|
||
|
* in the License.txt file at the root of this project.
|
||
|
*/
|
||
|
|
||
|
package shared
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"runtime"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
TracePattern = os.Getenv("CGOFUSE_TRACE")
|
||
|
)
|
||
|
|
||
|
func traceJoin(deref bool, vals []interface{}) string {
|
||
|
rslt := ""
|
||
|
for _, v := range vals {
|
||
|
if deref {
|
||
|
switch i := v.(type) {
|
||
|
case *bool:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *int:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *int8:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *int16:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *int32:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *int64:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *uint:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *uint8:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *uint16:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *uint32:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *uint64:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *uintptr:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *float32:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *float64:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *complex64:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *complex128:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
case *string:
|
||
|
rslt += fmt.Sprintf(", %#v", *i)
|
||
|
default:
|
||
|
rslt += fmt.Sprintf(", %#v", v)
|
||
|
}
|
||
|
} else {
|
||
|
rslt += fmt.Sprintf(", %#v", v)
|
||
|
}
|
||
|
}
|
||
|
if len(rslt) > 0 {
|
||
|
rslt = rslt[2:]
|
||
|
}
|
||
|
return rslt
|
||
|
}
|
||
|
|
||
|
func Trace(skip int, prfx string, vals ...interface{}) func(vals ...interface{}) {
|
||
|
if "" == TracePattern {
|
||
|
return func(vals ...interface{}) {
|
||
|
}
|
||
|
}
|
||
|
pc, _, _, ok := runtime.Caller(skip + 1)
|
||
|
name := "<UNKNOWN>"
|
||
|
if ok {
|
||
|
fn := runtime.FuncForPC(pc)
|
||
|
name = fn.Name()
|
||
|
if m, _ := filepath.Match(TracePattern, name); !m {
|
||
|
return func(vals ...interface{}) {
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if "" != prfx {
|
||
|
prfx = prfx + ": "
|
||
|
}
|
||
|
args := traceJoin(false, vals)
|
||
|
return func(vals ...interface{}) {
|
||
|
form := "%v%v(%v) = %v"
|
||
|
rslt := ""
|
||
|
rcvr := recover()
|
||
|
if nil != rcvr {
|
||
|
rslt = fmt.Sprintf("!PANIC:%v", rcvr)
|
||
|
} else {
|
||
|
if len(vals) != 1 {
|
||
|
form = "%v%v(%v) = (%v)"
|
||
|
}
|
||
|
rslt = traceJoin(true, vals)
|
||
|
}
|
||
|
log.Printf(form, prfx, name, args, rslt)
|
||
|
if nil != rcvr {
|
||
|
panic(rcvr)
|
||
|
}
|
||
|
}
|
||
|
}
|