github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/trace.go (about)

     1  /*
     2   *
     3   * Copyright 2015 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package grpc
    20  
    21  import (
    22  	"bytes"
    23  	"fmt"
    24  	"io"
    25  	"net"
    26  	"strings"
    27  	"sync"
    28  	"time"
    29  
    30  	"github.com/hxx258456/ccgo/net/trace"
    31  )
    32  
    33  // EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package.
    34  // This should only be set before any RPCs are sent or received by this program.
    35  var EnableTracing bool
    36  
    37  // methodFamily returns the trace family for the given method.
    38  // It turns "/pkg.Service/GetFoo" into "pkg.Service".
    39  func methodFamily(m string) string {
    40  	m = strings.TrimPrefix(m, "/") // remove leading slash
    41  	if i := strings.Index(m, "/"); i >= 0 {
    42  		m = m[:i] // remove everything from second slash
    43  	}
    44  	return m
    45  }
    46  
    47  // traceInfo contains tracing information for an RPC.
    48  type traceInfo struct {
    49  	tr        trace.Trace
    50  	firstLine firstLine
    51  }
    52  
    53  // firstLine is the first line of an RPC trace.
    54  // It may be mutated after construction; remoteAddr specifically may change
    55  // during client-side use.
    56  type firstLine struct {
    57  	mu         sync.Mutex
    58  	client     bool // whether this is a client (outgoing) RPC
    59  	remoteAddr net.Addr
    60  	deadline   time.Duration // may be zero
    61  }
    62  
    63  func (f *firstLine) SetRemoteAddr(addr net.Addr) {
    64  	f.mu.Lock()
    65  	f.remoteAddr = addr
    66  	f.mu.Unlock()
    67  }
    68  
    69  func (f *firstLine) String() string {
    70  	f.mu.Lock()
    71  	defer f.mu.Unlock()
    72  
    73  	var line bytes.Buffer
    74  	io.WriteString(&line, "RPC: ")
    75  	if f.client {
    76  		io.WriteString(&line, "to")
    77  	} else {
    78  		io.WriteString(&line, "from")
    79  	}
    80  	fmt.Fprintf(&line, " %v deadline:", f.remoteAddr)
    81  	if f.deadline != 0 {
    82  		fmt.Fprint(&line, f.deadline)
    83  	} else {
    84  		io.WriteString(&line, "none")
    85  	}
    86  	return line.String()
    87  }
    88  
    89  const truncateSize = 100
    90  
    91  func truncate(x string, l int) string {
    92  	if l > len(x) {
    93  		return x
    94  	}
    95  	return x[:l]
    96  }
    97  
    98  // payload represents an RPC request or response payload.
    99  type payload struct {
   100  	sent bool        // whether this is an outgoing payload
   101  	msg  interface{} // e.g. a proto.Message
   102  	// TODO(dsymonds): add stringifying info to codec, and limit how much we hold here?
   103  }
   104  
   105  func (p payload) String() string {
   106  	if p.sent {
   107  		return truncate(fmt.Sprintf("sent: %v", p.msg), truncateSize)
   108  	}
   109  	return truncate(fmt.Sprintf("recv: %v", p.msg), truncateSize)
   110  }
   111  
   112  type fmtStringer struct {
   113  	format string
   114  	a      []interface{}
   115  }
   116  
   117  func (f *fmtStringer) String() string {
   118  	return fmt.Sprintf(f.format, f.a...)
   119  }
   120  
   121  type stringer string
   122  
   123  func (s stringer) String() string { return string(s) }