github.com/brownsys/tracing-framework-go@v0.0.0-20161210174012-0542a62412fe/other/trace/trace.go (about)

     1  package trace
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"runtime"
     7  
     8  	"golang.org/x/net/context"
     9  
    10  	"github.com/brownsys/tracing-framework-go/trace/internal/instrument"
    11  )
    12  
    13  func GetType(f interface{}) (typ reflect.Type, ok bool) {
    14  	return instrument.GetType(f)
    15  }
    16  
    17  func GetTypeName(fname string) (typ reflect.Type, ok bool) {
    18  	return instrument.GetTypeName(fname)
    19  }
    20  
    21  func Instrument(f interface{}, callback func(ctx context.Context, args []reflect.Value)) {
    22  	InstrumentName(interfaceToName(f, "Instrument"), callback)
    23  }
    24  
    25  func InstrumentName(fname string, callback func(ctx context.Context, args []reflect.Value)) {
    26  	typ, _ := instrument.GetTypeName(fname)
    27  	f := func(args []reflect.Value) []reflect.Value {
    28  		var ctx context.Context
    29  		if c := runtime.GetLocal(); c != nil {
    30  			ctx = c.(context.Context)
    31  		}
    32  		callback(ctx, args)
    33  		return nil
    34  	}
    35  	instrument.InstrumentName(fname, reflect.MakeFunc(typ, f).Interface())
    36  }
    37  
    38  func Uninstrument(f interface{}) {
    39  	instrument.Uninstrument(f)
    40  }
    41  
    42  func UninstrumentName(fname string) {
    43  	instrument.UninstrumentName(fname)
    44  }
    45  
    46  // f is the function whose name should be retreived,
    47  // and fname is the name of the top-level function
    48  // that is calling interfaceToName (used in panic
    49  // messages)
    50  func interfaceToName(f interface{}, fname string) string {
    51  	v := reflect.ValueOf(f)
    52  	if v.Kind() != reflect.Func {
    53  		panic(fmt.Errorf("trace: %v with non-func %v", fname, v.Type()))
    54  	}
    55  	return runtime.FuncForPC(v.Pointer()).Name()
    56  }