github.com/m3shine/gochain@v2.2.26+incompatible/eth/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  package eth
    18  
    19  import (
    20  	"context"
    21  
    22  	"github.com/gochain-io/gochain/metrics"
    23  	"github.com/gochain-io/gochain/p2p"
    24  )
    25  
    26  var (
    27  	propTxnInPacketsMeter     = metrics.NewRegisteredMeter("eth/prop/txns/in/packets", nil)
    28  	propTxnInTrafficMeter     = metrics.NewRegisteredMeter("eth/prop/txns/in/traffic", nil)
    29  	propTxnOutPacketsMeter    = metrics.NewRegisteredMeter("eth/prop/txns/out/packets", nil)
    30  	propTxnOutTrafficMeter    = metrics.NewRegisteredMeter("eth/prop/txns/out/traffic", nil)
    31  	propHashInPacketsMeter    = metrics.NewRegisteredMeter("eth/prop/hashes/in/packets", nil)
    32  	propHashInTrafficMeter    = metrics.NewRegisteredMeter("eth/prop/hashes/in/traffic", nil)
    33  	propHashOutPacketsMeter   = metrics.NewRegisteredMeter("eth/prop/hashes/out/packets", nil)
    34  	propHashOutTrafficMeter   = metrics.NewRegisteredMeter("eth/prop/hashes/out/traffic", nil)
    35  	propBlockInPacketsMeter   = metrics.NewRegisteredMeter("eth/prop/blocks/in/packets", nil)
    36  	propBlockInTrafficMeter   = metrics.NewRegisteredMeter("eth/prop/blocks/in/traffic", nil)
    37  	propBlockOutPacketsMeter  = metrics.NewRegisteredMeter("eth/prop/blocks/out/packets", nil)
    38  	propBlockOutTrafficMeter  = metrics.NewRegisteredMeter("eth/prop/blocks/out/traffic", nil)
    39  	reqHeaderInPacketsMeter   = metrics.NewRegisteredMeter("eth/req/headers/in/packets", nil)
    40  	reqHeaderInTrafficMeter   = metrics.NewRegisteredMeter("eth/req/headers/in/traffic", nil)
    41  	reqHeaderOutPacketsMeter  = metrics.NewRegisteredMeter("eth/req/headers/out/packets", nil)
    42  	reqHeaderOutTrafficMeter  = metrics.NewRegisteredMeter("eth/req/headers/out/traffic", nil)
    43  	reqBodyInPacketsMeter     = metrics.NewRegisteredMeter("eth/req/bodies/in/packets", nil)
    44  	reqBodyInTrafficMeter     = metrics.NewRegisteredMeter("eth/req/bodies/in/traffic", nil)
    45  	reqBodyOutPacketsMeter    = metrics.NewRegisteredMeter("eth/req/bodies/out/packets", nil)
    46  	reqBodyOutTrafficMeter    = metrics.NewRegisteredMeter("eth/req/bodies/out/traffic", nil)
    47  	reqStateInPacketsMeter    = metrics.NewRegisteredMeter("eth/req/states/in/packets", nil)
    48  	reqStateInTrafficMeter    = metrics.NewRegisteredMeter("eth/req/states/in/traffic", nil)
    49  	reqStateOutPacketsMeter   = metrics.NewRegisteredMeter("eth/req/states/out/packets", nil)
    50  	reqStateOutTrafficMeter   = metrics.NewRegisteredMeter("eth/req/states/out/traffic", nil)
    51  	reqReceiptInPacketsMeter  = metrics.NewRegisteredMeter("eth/req/receipts/in/packets", nil)
    52  	reqReceiptInTrafficMeter  = metrics.NewRegisteredMeter("eth/req/receipts/in/traffic", nil)
    53  	reqReceiptOutPacketsMeter = metrics.NewRegisteredMeter("eth/req/receipts/out/packets", nil)
    54  	reqReceiptOutTrafficMeter = metrics.NewRegisteredMeter("eth/req/receipts/out/traffic", nil)
    55  	miscInPacketsMeter        = metrics.NewRegisteredMeter("eth/misc/in/packets", nil)
    56  	miscInTrafficMeter        = metrics.NewRegisteredMeter("eth/misc/in/traffic", nil)
    57  	miscOutPacketsMeter       = metrics.NewRegisteredMeter("eth/misc/out/packets", nil)
    58  	miscOutTrafficMeter       = metrics.NewRegisteredMeter("eth/misc/out/traffic", nil)
    59  )
    60  
    61  // meteredMsgReadWriter is a wrapper around a p2p.MsgReadWriter, capable of
    62  // accumulating the above defined metrics based on the data stream contents.
    63  type meteredMsgReadWriter struct {
    64  	p2p.MsgReadWriter     // Wrapped message stream to meter
    65  	version           int // Protocol version to select correct meters
    66  }
    67  
    68  // newMeteredMsgWriter wraps a p2p MsgReadWriter with metering support. If the
    69  // metrics system is disabled, this function returns the original object.
    70  func newMeteredMsgWriter(rw p2p.MsgReadWriter) p2p.MsgReadWriter {
    71  	if !metrics.Enabled {
    72  		return rw
    73  	}
    74  	return &meteredMsgReadWriter{MsgReadWriter: rw}
    75  }
    76  
    77  // Init sets the protocol version used by the stream to know which meters to
    78  // increment in case of overlapping message ids between protocol versions.
    79  func (rw *meteredMsgReadWriter) Init(version int) {
    80  	rw.version = version
    81  }
    82  
    83  func (rw *meteredMsgReadWriter) ReadMsg() (p2p.Msg, error) {
    84  	// Read the message and short circuit in case of an error
    85  	msg, err := rw.MsgReadWriter.ReadMsg()
    86  	if err != nil {
    87  		return msg, err
    88  	}
    89  	// Account for the data traffic
    90  	packets, traffic := miscInPacketsMeter, miscInTrafficMeter
    91  	switch {
    92  	case msg.Code == BlockHeadersMsg:
    93  		packets, traffic = reqHeaderInPacketsMeter, reqHeaderInTrafficMeter
    94  	case msg.Code == BlockBodiesMsg:
    95  		packets, traffic = reqBodyInPacketsMeter, reqBodyInTrafficMeter
    96  
    97  	case rw.version >= eth63 && msg.Code == NodeDataMsg:
    98  		packets, traffic = reqStateInPacketsMeter, reqStateInTrafficMeter
    99  	case rw.version >= eth63 && msg.Code == ReceiptsMsg:
   100  		packets, traffic = reqReceiptInPacketsMeter, reqReceiptInTrafficMeter
   101  
   102  	case msg.Code == NewBlockHashesMsg:
   103  		packets, traffic = propHashInPacketsMeter, propHashInTrafficMeter
   104  	case msg.Code == NewBlockMsg:
   105  		packets, traffic = propBlockInPacketsMeter, propBlockInTrafficMeter
   106  	case msg.Code == TxMsg:
   107  		packets, traffic = propTxnInPacketsMeter, propTxnInTrafficMeter
   108  	}
   109  	packets.Mark(1)
   110  	traffic.Mark(int64(msg.Size))
   111  
   112  	return msg, err
   113  }
   114  
   115  func (rw *meteredMsgReadWriter) WriteMsg(ctx context.Context, msg p2p.Msg) error {
   116  	// Account for the data traffic
   117  	packets, traffic := miscOutPacketsMeter, miscOutTrafficMeter
   118  	switch {
   119  	case msg.Code == BlockHeadersMsg:
   120  		packets, traffic = reqHeaderOutPacketsMeter, reqHeaderOutTrafficMeter
   121  	case msg.Code == BlockBodiesMsg:
   122  		packets, traffic = reqBodyOutPacketsMeter, reqBodyOutTrafficMeter
   123  
   124  	case rw.version >= eth63 && msg.Code == NodeDataMsg:
   125  		packets, traffic = reqStateOutPacketsMeter, reqStateOutTrafficMeter
   126  	case rw.version >= eth63 && msg.Code == ReceiptsMsg:
   127  		packets, traffic = reqReceiptOutPacketsMeter, reqReceiptOutTrafficMeter
   128  
   129  	case msg.Code == NewBlockHashesMsg:
   130  		packets, traffic = propHashOutPacketsMeter, propHashOutTrafficMeter
   131  	case msg.Code == NewBlockMsg:
   132  		packets, traffic = propBlockOutPacketsMeter, propBlockOutTrafficMeter
   133  	case msg.Code == TxMsg:
   134  		packets, traffic = propTxnOutPacketsMeter, propTxnOutTrafficMeter
   135  	}
   136  	packets.Mark(1)
   137  	traffic.Mark(int64(msg.Size))
   138  
   139  	// Send the packet to the p2p layer
   140  	return rw.MsgReadWriter.WriteMsg(ctx, msg)
   141  }