rclone/vendor/github.com/billziss-gh/cgofuse/examples/shared/trace.go
2017-05-15 16:56:47 +01:00

115 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)
}
}
}