github.com/micro/go-micro/examples@v0.0.0-20210105173217-bf4ab679e18b/client/wrapper/wrapper.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"context"
     8  	example "github.com/micro/go-micro/examples/server/proto/example"
     9  	"github.com/micro/go-micro/v2/client"
    10  	"github.com/micro/go-micro/v2/config/cmd"
    11  	"github.com/micro/go-micro/v2/metadata"
    12  	"github.com/micro/go-micro/v2/registry"
    13  )
    14  
    15  // wrapper example code
    16  
    17  // log wrapper logs every time a request is made
    18  type logWrapper struct {
    19  	client.Client
    20  }
    21  
    22  func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
    23  	md, _ := metadata.FromContext(ctx)
    24  	fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Endpoint())
    25  	return l.Client.Call(ctx, req, rsp)
    26  }
    27  
    28  // trace wrapper attaches a unique trace ID - timestamp
    29  type traceWrapper struct {
    30  	client.Client
    31  }
    32  
    33  func (t *traceWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
    34  	ctx = metadata.NewContext(ctx, map[string]string{
    35  		"X-Trace-Id": fmt.Sprintf("%d", time.Now().Unix()),
    36  	})
    37  	return t.Client.Call(ctx, req, rsp)
    38  }
    39  
    40  // Implements client.Wrapper as logWrapper
    41  func logWrap(c client.Client) client.Client {
    42  	return &logWrapper{c}
    43  }
    44  
    45  // Implements client.Wrapper as traceWrapper
    46  func traceWrap(c client.Client) client.Client {
    47  	return &traceWrapper{c}
    48  }
    49  
    50  func metricsWrap(cf client.CallFunc) client.CallFunc {
    51  	return func(ctx context.Context, node *registry.Node, req client.Request, rsp interface{}, opts client.CallOptions) error {
    52  		t := time.Now()
    53  		err := cf(ctx, node, req, rsp, opts)
    54  		fmt.Printf("[Metrics Wrapper] called: %v %s.%s duration: %v\n", node, req.Service(), req.Endpoint(), time.Since(t))
    55  		return err
    56  	}
    57  }
    58  
    59  func call(i int) {
    60  	// Create new request to service go.micro.srv.example, method Example.Call
    61  	req := client.NewRequest("go.micro.srv.example", "Example.Call", &example.Request{
    62  		Name: "John",
    63  	})
    64  
    65  	// create context with metadata
    66  	ctx := metadata.NewContext(context.Background(), map[string]string{
    67  		"X-User-Id": "john",
    68  		"X-From-Id": "script",
    69  	})
    70  
    71  	rsp := &example.Response{}
    72  
    73  	// Call service
    74  	if err := client.Call(ctx, req, rsp); err != nil {
    75  		fmt.Println("call err: ", err, rsp)
    76  		return
    77  	}
    78  
    79  	fmt.Println("Call:", i, "rsp:", rsp.Msg)
    80  }
    81  
    82  func main() {
    83  	cmd.Init()
    84  
    85  	fmt.Println("\n--- Log Wrapper example ---")
    86  
    87  	// Wrap the default client
    88  	client.DefaultClient = logWrap(client.DefaultClient)
    89  
    90  	call(0)
    91  
    92  	fmt.Println("\n--- Log+Trace Wrapper example ---")
    93  
    94  	// Wrap using client.Wrap option
    95  	client.DefaultClient = client.NewClient(
    96  		client.Wrap(traceWrap),
    97  		client.Wrap(logWrap),
    98  	)
    99  
   100  	call(1)
   101  
   102  	fmt.Println("\n--- Metrics Wrapper example ---")
   103  
   104  	// Wrap using client.Wrap option
   105  	client.DefaultClient = client.NewClient(
   106  		client.WrapCall(metricsWrap),
   107  	)
   108  
   109  	call(2)
   110  }