github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/eth/metrics.go (about) 1 // Copyright 2015 The Spectrum Authors 2 // This file is part of the Spectrum library. 3 // 4 // The Spectrum 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 Spectrum 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 Spectrum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package eth 18 19 import ( 20 "github.com/SmartMeshFoundation/Spectrum/metrics" 21 "github.com/SmartMeshFoundation/Spectrum/p2p" 22 ) 23 24 var ( 25 propTxnInPacketsMeter = metrics.NewMeter("eth/prop/txns/in/packets") 26 propTxnInTrafficMeter = metrics.NewMeter("eth/prop/txns/in/traffic") 27 propTxnOutPacketsMeter = metrics.NewMeter("eth/prop/txns/out/packets") 28 propTxnOutTrafficMeter = metrics.NewMeter("eth/prop/txns/out/traffic") 29 propHashInPacketsMeter = metrics.NewMeter("eth/prop/hashes/in/packets") 30 propHashInTrafficMeter = metrics.NewMeter("eth/prop/hashes/in/traffic") 31 propHashOutPacketsMeter = metrics.NewMeter("eth/prop/hashes/out/packets") 32 propHashOutTrafficMeter = metrics.NewMeter("eth/prop/hashes/out/traffic") 33 propBlockInPacketsMeter = metrics.NewMeter("eth/prop/blocks/in/packets") 34 propBlockInTrafficMeter = metrics.NewMeter("eth/prop/blocks/in/traffic") 35 propBlockOutPacketsMeter = metrics.NewMeter("eth/prop/blocks/out/packets") 36 propBlockOutTrafficMeter = metrics.NewMeter("eth/prop/blocks/out/traffic") 37 reqHeaderInPacketsMeter = metrics.NewMeter("eth/req/headers/in/packets") 38 reqHeaderInTrafficMeter = metrics.NewMeter("eth/req/headers/in/traffic") 39 reqHeaderOutPacketsMeter = metrics.NewMeter("eth/req/headers/out/packets") 40 reqHeaderOutTrafficMeter = metrics.NewMeter("eth/req/headers/out/traffic") 41 reqBodyInPacketsMeter = metrics.NewMeter("eth/req/bodies/in/packets") 42 reqBodyInTrafficMeter = metrics.NewMeter("eth/req/bodies/in/traffic") 43 reqBodyOutPacketsMeter = metrics.NewMeter("eth/req/bodies/out/packets") 44 reqBodyOutTrafficMeter = metrics.NewMeter("eth/req/bodies/out/traffic") 45 reqStateInPacketsMeter = metrics.NewMeter("eth/req/states/in/packets") 46 reqStateInTrafficMeter = metrics.NewMeter("eth/req/states/in/traffic") 47 reqStateOutPacketsMeter = metrics.NewMeter("eth/req/states/out/packets") 48 reqStateOutTrafficMeter = metrics.NewMeter("eth/req/states/out/traffic") 49 reqReceiptInPacketsMeter = metrics.NewMeter("eth/req/receipts/in/packets") 50 reqReceiptInTrafficMeter = metrics.NewMeter("eth/req/receipts/in/traffic") 51 reqReceiptOutPacketsMeter = metrics.NewMeter("eth/req/receipts/out/packets") 52 reqReceiptOutTrafficMeter = metrics.NewMeter("eth/req/receipts/out/traffic") 53 miscInPacketsMeter = metrics.NewMeter("eth/misc/in/packets") 54 miscInTrafficMeter = metrics.NewMeter("eth/misc/in/traffic") 55 miscOutPacketsMeter = metrics.NewMeter("eth/misc/out/packets") 56 miscOutTrafficMeter = metrics.NewMeter("eth/misc/out/traffic") 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 }