google.golang.org/grpc@v1.62.1/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 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) }