cubefs
123 строки · 2.9 Кб
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 grpc20
21import (22"bytes"23"fmt"24"io"25"net"26"strings"27"sync"28"time"29
30"golang.org/x/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.
35var EnableTracing bool36
37// methodFamily returns the trace family for the given method.
38// It turns "/pkg.Service/GetFoo" into "pkg.Service".
39func methodFamily(m string) string {40m = strings.TrimPrefix(m, "/") // remove leading slash41if i := strings.Index(m, "/"); i >= 0 {42m = m[:i] // remove everything from second slash43}44return m45}
46
47// traceInfo contains tracing information for an RPC.
48type traceInfo struct {49tr trace.Trace50firstLine 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.
56type firstLine struct {57mu sync.Mutex58client bool // whether this is a client (outgoing) RPC59remoteAddr net.Addr60deadline time.Duration // may be zero61}
62
63func (f *firstLine) SetRemoteAddr(addr net.Addr) {64f.mu.Lock()65f.remoteAddr = addr66f.mu.Unlock()67}
68
69func (f *firstLine) String() string {70f.mu.Lock()71defer f.mu.Unlock()72
73var line bytes.Buffer74io.WriteString(&line, "RPC: ")75if f.client {76io.WriteString(&line, "to")77} else {78io.WriteString(&line, "from")79}80fmt.Fprintf(&line, " %v deadline:", f.remoteAddr)81if f.deadline != 0 {82fmt.Fprint(&line, f.deadline)83} else {84io.WriteString(&line, "none")85}86return line.String()87}
88
89const truncateSize = 10090
91func truncate(x string, l int) string {92if l > len(x) {93return x94}95return x[:l]96}
97
98// payload represents an RPC request or response payload.
99type payload struct {100sent bool // whether this is an outgoing payload101msg interface{} // e.g. a proto.Message102// TODO(dsymonds): add stringifying info to codec, and limit how much we hold here?103}
104
105func (p payload) String() string {106if p.sent {107return truncate(fmt.Sprintf("sent: %v", p.msg), truncateSize)108}109return truncate(fmt.Sprintf("recv: %v", p.msg), truncateSize)110}
111
112type fmtStringer struct {113format string114a []interface{}115}
116
117func (f *fmtStringer) String() string {118return fmt.Sprintf(f.format, f.a...)119}
120
121type stringer string122
123func (s stringer) String() string { return string(s) }124