func (s *Greeter) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) {
	callIdx := s.recordCall(Unary)
	if in.GetName() == "__record_metadata__" {
		mdval := ""
		md, ok := metadata.FromIncomingContext(ctx)
		if ok {
			for k, v := range md {
				if k == "token" {
					mdval = mdval + k + ":"
					for _, vv := range v {
						mdval = mdval + vv
					}
				}
			}
		}
		newReq := &HelloRequest{Name: in.GetName() + "||" + mdval}
		s.recordMessage(Unary, callIdx, newReq)
	} else {
		s.recordMessage(Unary, callIdx, in)
	}
	randomSleep(4)
	return &HelloReply{Message: "Hello " + in.Name}, nil
}
SayHello implements helloworld.GreeterServer
package helloworld
import (
	"fmt"
	"io"
	"math/rand"
	"strings"
	"sync"
	"time"
	context "golang.org/x/net/context"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/stats"
)
type CallType string
var Unary CallType = "unary"
var ClientStream CallType = "cs"
var ServerStream CallType = "ss"
var Bidi CallType = "bidi"
type Greeter struct {
	StreamData []*HelloReply
	Stats *HWStatsHandler
	mutex      *sync.RWMutex
	callCounts map[CallType]int
	calls      map[CallType][][]*HelloRequest
	sendMutex  *sync.RWMutex
	sendCounts map[CallType]map[int]int
}
func randomSleep(max int) {
	msCount := rand.Intn(max) + 1
	time.Sleep(time.Millisecond * time.Duration(msCount))
}
func (s *Greeter) recordCall(ct CallType) int {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	s.callCounts[ct]++
	var messages []*HelloRequest
	s.calls[ct] = append(s.calls[ct], messages)
	return len(s.calls[ct]) - 1
}
func (s *Greeter) recordMessage(ct CallType, callIdx int, msg *HelloRequest) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	s.calls[ct][callIdx] = append(s.calls[ct][callIdx], msg)
}
func (s *Greeter) recordStreamSendCounter(ct CallType, callIdx int) {
	s.sendMutex.Lock()
	defer s.sendMutex.Unlock()
	s.sendCounts[ct][callIdx] = s.sendCounts[ct][callIdx] + 1
}