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 19package grpc 20 21import ( 22 "bytes" 23 "fmt" 24 "io" 25 "net" 26 "strings" 27 "time" 28 29 "golang.org/x/net/trace" 30) 31 32// EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package. 33// This should only be set before any RPCs are sent or received by this program. 34var EnableTracing bool 35 36// methodFamily returns the trace family for the given method. 37// It turns "/pkg.Service/GetFoo" into "pkg.Service". 38func methodFamily(m string) string { 39 m = strings.TrimPrefix(m, "/") // remove leading slash 40 if i := strings.Index(m, "/"); i >= 0 { 41 m = m[:i] // remove everything from second slash 42 } 43 if i := strings.LastIndex(m, "."); i >= 0 { 44 m = m[i+1:] // cut down to last dotted component 45 } 46 return m 47} 48 49// traceInfo contains tracing information for an RPC. 50type traceInfo struct { 51 tr trace.Trace 52 firstLine firstLine 53} 54 55// firstLine is the first line of an RPC trace. 56type firstLine struct { 57 client bool // whether this is a client (outgoing) RPC 58 remoteAddr net.Addr 59 deadline time.Duration // may be zero 60} 61 62func (f *firstLine) String() string { 63 var line bytes.Buffer 64 io.WriteString(&line, "RPC: ") 65 if f.client { 66 io.WriteString(&line, "to") 67 } else { 68 io.WriteString(&line, "from") 69 } 70 fmt.Fprintf(&line, " %v deadline:", f.remoteAddr) 71 if f.deadline != 0 { 72 fmt.Fprint(&line, f.deadline) 73 } else { 74 io.WriteString(&line, "none") 75 } 76 return line.String() 77} 78 79const truncateSize = 100 80 81func truncate(x string, l int) string { 82 if l > len(x) { 83 return x 84 } 85 return x[:l] 86} 87 88// payload represents an RPC request or response payload. 89type payload struct { 90 sent bool // whether this is an outgoing payload 91 msg interface{} // e.g. a proto.Message 92 // TODO(dsymonds): add stringifying info to codec, and limit how much we hold here? 93} 94 95func (p payload) String() string { 96 if p.sent { 97 return truncate(fmt.Sprintf("sent: %v", p.msg), truncateSize) 98 } 99 return truncate(fmt.Sprintf("recv: %v", p.msg), truncateSize) 100} 101 102type fmtStringer struct { 103 format string 104 a []interface{} 105} 106 107func (f *fmtStringer) String() string { 108 return fmt.Sprintf(f.format, f.a...) 109} 110 111type stringer string 112 113func (s stringer) String() string { return string(s) } 114