...

Source file src/google.golang.org/grpc/trace.go

Documentation: google.golang.org/grpc

     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  
    31  // EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package.
    32  // This should only be set before any RPCs are sent or received by this program.
    33  var EnableTracing bool
    34  
    35  // methodFamily returns the trace family for the given method.
    36  // It turns "/pkg.Service/GetFoo" into "pkg.Service".
    37  func methodFamily(m string) string {
    38  	m = strings.TrimPrefix(m, "/") // remove leading slash
    39  	if i := strings.Index(m, "/"); i >= 0 {
    40  		m = m[:i] // remove everything from second slash
    41  	}
    42  	return m
    43  }
    44  
    45  // traceEventLog mirrors golang.org/x/net/trace.EventLog.
    46  //
    47  // It exists in order to avoid importing x/net/trace on grpcnotrace builds.
    48  type traceEventLog interface {
    49  	Printf(format string, a ...any)
    50  	Errorf(format string, a ...any)
    51  	Finish()
    52  }
    53  
    54  // traceLog mirrors golang.org/x/net/trace.Trace.
    55  //
    56  // It exists in order to avoid importing x/net/trace on grpcnotrace builds.
    57  type traceLog interface {
    58  	LazyLog(x fmt.Stringer, sensitive bool)
    59  	LazyPrintf(format string, a ...any)
    60  	SetError()
    61  	SetRecycler(f func(any))
    62  	SetTraceInfo(traceID, spanID uint64)
    63  	SetMaxEvents(m int)
    64  	Finish()
    65  }
    66  
    67  // traceInfo contains tracing information for an RPC.
    68  type traceInfo struct {
    69  	tr        traceLog
    70  	firstLine firstLine
    71  }
    72  
    73  // firstLine is the first line of an RPC trace.
    74  // It may be mutated after construction; remoteAddr specifically may change
    75  // during client-side use.
    76  type firstLine struct {
    77  	mu         sync.Mutex
    78  	client     bool // whether this is a client (outgoing) RPC
    79  	remoteAddr net.Addr
    80  	deadline   time.Duration // may be zero
    81  }
    82  
    83  func (f *firstLine) SetRemoteAddr(addr net.Addr) {
    84  	f.mu.Lock()
    85  	f.remoteAddr = addr
    86  	f.mu.Unlock()
    87  }
    88  
    89  func (f *firstLine) String() string {
    90  	f.mu.Lock()
    91  	defer f.mu.Unlock()
    92  
    93  	var line bytes.Buffer
    94  	io.WriteString(&line, "RPC: ")
    95  	if f.client {
    96  		io.WriteString(&line, "to")
    97  	} else {
    98  		io.WriteString(&line, "from")
    99  	}
   100  	fmt.Fprintf(&line, " %v deadline:", f.remoteAddr)
   101  	if f.deadline != 0 {
   102  		fmt.Fprint(&line, f.deadline)
   103  	} else {
   104  		io.WriteString(&line, "none")
   105  	}
   106  	return line.String()
   107  }
   108  
   109  const truncateSize = 100
   110  
   111  func truncate(x string, l int) string {
   112  	if l > len(x) {
   113  		return x
   114  	}
   115  	return x[:l]
   116  }
   117  
   118  // payload represents an RPC request or response payload.
   119  type payload struct {
   120  	sent bool // whether this is an outgoing payload
   121  	msg  any  // e.g. a proto.Message
   122  	// TODO(dsymonds): add stringifying info to codec, and limit how much we hold here?
   123  }
   124  
   125  func (p payload) String() string {
   126  	if p.sent {
   127  		return truncate(fmt.Sprintf("sent: %v", p.msg), truncateSize)
   128  	}
   129  	return truncate(fmt.Sprintf("recv: %v", p.msg), truncateSize)
   130  }
   131  
   132  type fmtStringer struct {
   133  	format string
   134  	a      []any
   135  }
   136  
   137  func (f *fmtStringer) String() string {
   138  	return fmt.Sprintf(f.format, f.a...)
   139  }
   140  
   141  type stringer string
   142  
   143  func (s stringer) String() string { return string(s) }
   144  

View as plain text