stats.go raw

   1  /*
   2   *
   3   * Copyright 2016 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 stats is for collecting and reporting various network and RPC stats.
  20  // This package is for monitoring purpose only. All fields are read-only.
  21  // All APIs are experimental.
  22  package stats // import "google.golang.org/grpc/stats"
  23  
  24  import (
  25  	"context"
  26  	"net"
  27  	"time"
  28  
  29  	"google.golang.org/grpc/metadata"
  30  )
  31  
  32  // RPCStats contains stats information about RPCs.
  33  type RPCStats interface {
  34  	isRPCStats()
  35  	// IsClient returns true if this RPCStats is from client side.
  36  	IsClient() bool
  37  }
  38  
  39  // Begin contains stats for the start of an RPC attempt.
  40  //
  41  //   - Server-side: Triggered after `InHeader`, as headers are processed
  42  //     before the RPC lifecycle begins.
  43  //   - Client-side: The first stats event recorded.
  44  //
  45  // FailFast is only valid if this Begin is from client side.
  46  type Begin struct {
  47  	// Client is true if this Begin is from client side.
  48  	Client bool
  49  	// BeginTime is the time when the RPC attempt begins.
  50  	BeginTime time.Time
  51  	// FailFast indicates if this RPC is failfast.
  52  	FailFast bool
  53  	// IsClientStream indicates whether the RPC is a client streaming RPC.
  54  	IsClientStream bool
  55  	// IsServerStream indicates whether the RPC is a server streaming RPC.
  56  	IsServerStream bool
  57  	// IsTransparentRetryAttempt indicates whether this attempt was initiated
  58  	// due to transparently retrying a previous attempt.
  59  	IsTransparentRetryAttempt bool
  60  }
  61  
  62  // IsClient indicates if the stats information is from client side.
  63  func (s *Begin) IsClient() bool { return s.Client }
  64  
  65  func (s *Begin) isRPCStats() {}
  66  
  67  // DelayedPickComplete indicates that the RPC is unblocked following a delay in
  68  // selecting a connection for the call.
  69  type DelayedPickComplete struct{}
  70  
  71  // IsClient indicates DelayedPickComplete is available on the client.
  72  func (*DelayedPickComplete) IsClient() bool { return true }
  73  
  74  func (*DelayedPickComplete) isRPCStats() {}
  75  
  76  // PickerUpdated indicates that the RPC is unblocked following a delay in
  77  // selecting a connection for the call.
  78  //
  79  // Deprecated: will be removed in a future release; use DelayedPickComplete
  80  // instead.
  81  type PickerUpdated = DelayedPickComplete
  82  
  83  // InPayload contains stats about an incoming payload.
  84  type InPayload struct {
  85  	// Client is true if this InPayload is from client side.
  86  	Client bool
  87  	// Payload is the payload with original type.  This may be modified after
  88  	// the call to HandleRPC which provides the InPayload returns and must be
  89  	// copied if needed later.
  90  	Payload any
  91  
  92  	// Length is the size of the uncompressed payload data. Does not include any
  93  	// framing (gRPC or HTTP/2).
  94  	Length int
  95  	// CompressedLength is the size of the compressed payload data. Does not
  96  	// include any framing (gRPC or HTTP/2). Same as Length if compression not
  97  	// enabled.
  98  	CompressedLength int
  99  	// WireLength is the size of the compressed payload data plus gRPC framing.
 100  	// Does not include HTTP/2 framing.
 101  	WireLength int
 102  
 103  	// RecvTime is the time when the payload is received.
 104  	RecvTime time.Time
 105  }
 106  
 107  // IsClient indicates if the stats information is from client side.
 108  func (s *InPayload) IsClient() bool { return s.Client }
 109  
 110  func (s *InPayload) isRPCStats() {}
 111  
 112  // InHeader contains stats about header reception.
 113  //
 114  // - Server-side: The first stats event after the RPC request is received.
 115  type InHeader struct {
 116  	// Client is true if this InHeader is from client side.
 117  	Client bool
 118  	// WireLength is the wire length of header.
 119  	WireLength int
 120  	// Compression is the compression algorithm used for the RPC.
 121  	Compression string
 122  	// Header contains the header metadata received.
 123  	Header metadata.MD
 124  
 125  	// The following fields are valid only if Client is false.
 126  	// FullMethod is the full RPC method string, i.e., /package.service/method.
 127  	FullMethod string
 128  	// RemoteAddr is the remote address of the corresponding connection.
 129  	RemoteAddr net.Addr
 130  	// LocalAddr is the local address of the corresponding connection.
 131  	LocalAddr net.Addr
 132  }
 133  
 134  // IsClient indicates if the stats information is from client side.
 135  func (s *InHeader) IsClient() bool { return s.Client }
 136  
 137  func (s *InHeader) isRPCStats() {}
 138  
 139  // InTrailer contains stats about trailer reception.
 140  type InTrailer struct {
 141  	// Client is true if this InTrailer is from client side.
 142  	Client bool
 143  	// WireLength is the wire length of trailer.
 144  	WireLength int
 145  	// Trailer contains the trailer metadata received from the server. This
 146  	// field is only valid if this InTrailer is from the client side.
 147  	Trailer metadata.MD
 148  }
 149  
 150  // IsClient indicates if the stats information is from client side.
 151  func (s *InTrailer) IsClient() bool { return s.Client }
 152  
 153  func (s *InTrailer) isRPCStats() {}
 154  
 155  // OutPayload contains stats about an outgoing payload.
 156  type OutPayload struct {
 157  	// Client is true if this OutPayload is from client side.
 158  	Client bool
 159  	// Payload is the payload with original type.  This may be modified after
 160  	// the call to HandleRPC which provides the OutPayload returns and must be
 161  	// copied if needed later.
 162  	Payload any
 163  	// Length is the size of the uncompressed payload data. Does not include any
 164  	// framing (gRPC or HTTP/2).
 165  	Length int
 166  	// CompressedLength is the size of the compressed payload data. Does not
 167  	// include any framing (gRPC or HTTP/2). Same as Length if compression not
 168  	// enabled.
 169  	CompressedLength int
 170  	// WireLength is the size of the compressed payload data plus gRPC framing.
 171  	// Does not include HTTP/2 framing.
 172  	WireLength int
 173  	// SentTime is the time when the payload is sent.
 174  	SentTime time.Time
 175  }
 176  
 177  // IsClient indicates if this stats information is from client side.
 178  func (s *OutPayload) IsClient() bool { return s.Client }
 179  
 180  func (s *OutPayload) isRPCStats() {}
 181  
 182  // OutHeader contains stats about header transmission.
 183  //
 184  //   - Client-side: Only occurs after 'Begin', as headers are always the first
 185  //     thing sent on a stream.
 186  type OutHeader struct {
 187  	// Client is true if this OutHeader is from client side.
 188  	Client bool
 189  	// Compression is the compression algorithm used for the RPC.
 190  	Compression string
 191  	// Header contains the header metadata sent.
 192  	Header metadata.MD
 193  
 194  	// The following fields are valid only if Client is true.
 195  	// FullMethod is the full RPC method string, i.e., /package.service/method.
 196  	FullMethod string
 197  	// RemoteAddr is the remote address of the corresponding connection.
 198  	RemoteAddr net.Addr
 199  	// LocalAddr is the local address of the corresponding connection.
 200  	LocalAddr net.Addr
 201  }
 202  
 203  // IsClient indicates if this stats information is from client side.
 204  func (s *OutHeader) IsClient() bool { return s.Client }
 205  
 206  func (s *OutHeader) isRPCStats() {}
 207  
 208  // OutTrailer contains stats about trailer transmission.
 209  type OutTrailer struct {
 210  	// Client is true if this OutTrailer is from client side.
 211  	Client bool
 212  	// WireLength is the wire length of trailer.
 213  	//
 214  	// Deprecated: This field is never set. The length is not known when this
 215  	// message is emitted because the trailer fields are compressed with hpack
 216  	// after that.
 217  	WireLength int
 218  	// Trailer contains the trailer metadata sent to the client. This
 219  	// field is only valid if this OutTrailer is from the server side.
 220  	Trailer metadata.MD
 221  }
 222  
 223  // IsClient indicates if this stats information is from client side.
 224  func (s *OutTrailer) IsClient() bool { return s.Client }
 225  
 226  func (s *OutTrailer) isRPCStats() {}
 227  
 228  // End contains stats about RPC completion.
 229  type End struct {
 230  	// Client is true if this End is from client side.
 231  	Client bool
 232  	// BeginTime is the time when the RPC began.
 233  	BeginTime time.Time
 234  	// EndTime is the time when the RPC ends.
 235  	EndTime time.Time
 236  	// Trailer contains the trailer metadata received from the server. This
 237  	// field is only valid if this End is from the client side.
 238  	// Deprecated: use Trailer in InTrailer instead.
 239  	Trailer metadata.MD
 240  	// Error is the error the RPC ended with. It is an error generated from
 241  	// status.Status and can be converted back to status.Status using
 242  	// status.FromError if non-nil.
 243  	Error error
 244  }
 245  
 246  // IsClient indicates if this is from client side.
 247  func (s *End) IsClient() bool { return s.Client }
 248  
 249  func (s *End) isRPCStats() {}
 250  
 251  // ConnStats contains stats information about connections.
 252  type ConnStats interface {
 253  	isConnStats()
 254  	// IsClient returns true if this ConnStats is from client side.
 255  	IsClient() bool
 256  }
 257  
 258  // ConnBegin contains stats about connection establishment.
 259  type ConnBegin struct {
 260  	// Client is true if this ConnBegin is from client side.
 261  	Client bool
 262  }
 263  
 264  // IsClient indicates if this is from client side.
 265  func (s *ConnBegin) IsClient() bool { return s.Client }
 266  
 267  func (s *ConnBegin) isConnStats() {}
 268  
 269  // ConnEnd contains stats about connection termination.
 270  type ConnEnd struct {
 271  	// Client is true if this ConnEnd is from client side.
 272  	Client bool
 273  }
 274  
 275  // IsClient indicates if this is from client side.
 276  func (s *ConnEnd) IsClient() bool { return s.Client }
 277  
 278  func (s *ConnEnd) isConnStats() {}
 279  
 280  // SetTags attaches stats tagging data to the context, which will be sent in
 281  // the outgoing RPC with the header grpc-tags-bin.  Subsequent calls to
 282  // SetTags will overwrite the values from earlier calls.
 283  //
 284  // Deprecated: set the `grpc-tags-bin` header in the metadata instead.
 285  func SetTags(ctx context.Context, b []byte) context.Context {
 286  	return metadata.AppendToOutgoingContext(ctx, "grpc-tags-bin", string(b))
 287  }
 288  
 289  // Tags returns the tags from the context for the inbound RPC.
 290  //
 291  // Deprecated: obtain the `grpc-tags-bin` header from metadata instead.
 292  func Tags(ctx context.Context) []byte {
 293  	traceValues := metadata.ValueFromIncomingContext(ctx, "grpc-tags-bin")
 294  	if len(traceValues) == 0 {
 295  		return nil
 296  	}
 297  	return []byte(traceValues[len(traceValues)-1])
 298  }
 299  
 300  // SetTrace attaches stats tagging data to the context, which will be sent in
 301  // the outgoing RPC with the header grpc-trace-bin.  Subsequent calls to
 302  // SetTrace will overwrite the values from earlier calls.
 303  //
 304  // Deprecated: set the `grpc-trace-bin` header in the metadata instead.
 305  func SetTrace(ctx context.Context, b []byte) context.Context {
 306  	return metadata.AppendToOutgoingContext(ctx, "grpc-trace-bin", string(b))
 307  }
 308  
 309  // Trace returns the trace from the context for the inbound RPC.
 310  //
 311  // Deprecated: obtain the `grpc-trace-bin` header from metadata instead.
 312  func Trace(ctx context.Context) []byte {
 313  	traceValues := metadata.ValueFromIncomingContext(ctx, "grpc-trace-bin")
 314  	if len(traceValues) == 0 {
 315  		return nil
 316  	}
 317  	return []byte(traceValues[len(traceValues)-1])
 318  }
 319