github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/p2p/metrics.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Contains the meters and timers used by the networking layer.
    18  
    19  package p2p
    20  
    21  import (
    22  	"errors"
    23  	"net"
    24  
    25  	"github.com/ethereum/go-ethereum/metrics"
    26  )
    27  
    28  const (
    29  	// HandleHistName is the prefix of the per-packet serving time histograms.
    30  	HandleHistName = "p2p/handle"
    31  
    32  	// ingressMeterName is the prefix of the per-packet inbound metrics.
    33  	ingressMeterName = "p2p/ingress"
    34  
    35  	// egressMeterName is the prefix of the per-packet outbound metrics.
    36  	egressMeterName = "p2p/egress"
    37  )
    38  
    39  var (
    40  	activePeerGauge         metrics.Gauge = metrics.NilGauge{}
    41  	activeInboundPeerGauge  metrics.Gauge = metrics.NilGauge{}
    42  	activeOutboundPeerGauge metrics.Gauge = metrics.NilGauge{}
    43  
    44  	ingressTrafficMeter = metrics.NewRegisteredMeter("p2p/ingress", nil)
    45  	egressTrafficMeter  = metrics.NewRegisteredMeter("p2p/egress", nil)
    46  
    47  	// general ingress/egress connection meters
    48  	serveMeter          metrics.Meter = metrics.NilMeter{}
    49  	serveSuccessMeter   metrics.Meter = metrics.NilMeter{}
    50  	dialMeter           metrics.Meter = metrics.NilMeter{}
    51  	dialSuccessMeter    metrics.Meter = metrics.NilMeter{}
    52  	dialConnectionError metrics.Meter = metrics.NilMeter{}
    53  
    54  	// handshake error meters
    55  	dialTooManyPeers        = metrics.NewRegisteredMeter("p2p/dials/error/saturated", nil)
    56  	dialAlreadyConnected    = metrics.NewRegisteredMeter("p2p/dials/error/known", nil)
    57  	dialSelf                = metrics.NewRegisteredMeter("p2p/dials/error/self", nil)
    58  	dialUselessPeer         = metrics.NewRegisteredMeter("p2p/dials/error/useless", nil)
    59  	dialUnexpectedIdentity  = metrics.NewRegisteredMeter("p2p/dials/error/id/unexpected", nil)
    60  	dialEncHandshakeError   = metrics.NewRegisteredMeter("p2p/dials/error/rlpx/enc", nil)
    61  	dialProtoHandshakeError = metrics.NewRegisteredMeter("p2p/dials/error/rlpx/proto", nil)
    62  )
    63  
    64  func init() {
    65  	if !metrics.Enabled {
    66  		return
    67  	}
    68  
    69  	activePeerGauge = metrics.NewRegisteredGauge("p2p/peers", nil)
    70  	activeInboundPeerGauge = metrics.NewRegisteredGauge("p2p/peers/inbound", nil)
    71  	activeOutboundPeerGauge = metrics.NewRegisteredGauge("p2p/peers/outbound", nil)
    72  	serveMeter = metrics.NewRegisteredMeter("p2p/serves", nil)
    73  	serveSuccessMeter = metrics.NewRegisteredMeter("p2p/serves/success", nil)
    74  	dialMeter = metrics.NewRegisteredMeter("p2p/dials", nil)
    75  	dialSuccessMeter = metrics.NewRegisteredMeter("p2p/dials/success", nil)
    76  	dialConnectionError = metrics.NewRegisteredMeter("p2p/dials/error/connection", nil)
    77  }
    78  
    79  // markDialError matches errors that occur while setting up a dial connection
    80  // to the corresponding meter.
    81  func markDialError(err error) {
    82  	if !metrics.Enabled {
    83  		return
    84  	}
    85  	if err2 := errors.Unwrap(err); err2 != nil {
    86  		err = err2
    87  	}
    88  	switch err {
    89  	case DiscTooManyPeers:
    90  		dialTooManyPeers.Mark(1)
    91  	case DiscAlreadyConnected:
    92  		dialAlreadyConnected.Mark(1)
    93  	case DiscSelf:
    94  		dialSelf.Mark(1)
    95  	case DiscUselessPeer:
    96  		dialUselessPeer.Mark(1)
    97  	case DiscUnexpectedIdentity:
    98  		dialUnexpectedIdentity.Mark(1)
    99  	case errEncHandshakeError:
   100  		dialEncHandshakeError.Mark(1)
   101  	case errProtoHandshakeError:
   102  		dialProtoHandshakeError.Mark(1)
   103  	}
   104  }
   105  
   106  // meteredConn is a wrapper around a net.Conn that meters both the
   107  // inbound and outbound network traffic.
   108  type meteredConn struct {
   109  	net.Conn
   110  }
   111  
   112  // newMeteredConn creates a new metered connection, bumps the ingress or egress
   113  // connection meter and also increases the metered peer count. If the metrics
   114  // system is disabled, function returns the original connection.
   115  func newMeteredConn(conn net.Conn) net.Conn {
   116  	if !metrics.Enabled {
   117  		return conn
   118  	}
   119  	return &meteredConn{Conn: conn}
   120  }
   121  
   122  // Read delegates a network read to the underlying connection, bumping the common
   123  // and the peer ingress traffic meters along the way.
   124  func (c *meteredConn) Read(b []byte) (n int, err error) {
   125  	n, err = c.Conn.Read(b)
   126  	ingressTrafficMeter.Mark(int64(n))
   127  	return n, err
   128  }
   129  
   130  // Write delegates a network write to the underlying connection, bumping the common
   131  // and the peer egress traffic meters along the way.
   132  func (c *meteredConn) Write(b []byte) (n int, err error) {
   133  	n, err = c.Conn.Write(b)
   134  	egressTrafficMeter.Mark(int64(n))
   135  	return n, err
   136  }