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