/* * 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 := "" 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) } } }