github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/eth/metrics.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package eth 13 14 import ( 15 "github.com/Sberex/go-sberex/metrics" 16 "github.com/Sberex/go-sberex/p2p" 17 ) 18 19 var ( 20 propTxnInPacketsMeter = metrics.NewRegisteredMeter("eth/prop/txns/in/packets", nil) 21 propTxnInTrafficMeter = metrics.NewRegisteredMeter("eth/prop/txns/in/traffic", nil) 22 propTxnOutPacketsMeter = metrics.NewRegisteredMeter("eth/prop/txns/out/packets", nil) 23 propTxnOutTrafficMeter = metrics.NewRegisteredMeter("eth/prop/txns/out/traffic", nil) 24 propHashInPacketsMeter = metrics.NewRegisteredMeter("eth/prop/hashes/in/packets", nil) 25 propHashInTrafficMeter = metrics.NewRegisteredMeter("eth/prop/hashes/in/traffic", nil) 26 propHashOutPacketsMeter = metrics.NewRegisteredMeter("eth/prop/hashes/out/packets", nil) 27 propHashOutTrafficMeter = metrics.NewRegisteredMeter("eth/prop/hashes/out/traffic", nil) 28 propBlockInPacketsMeter = metrics.NewRegisteredMeter("eth/prop/blocks/in/packets", nil) 29 propBlockInTrafficMeter = metrics.NewRegisteredMeter("eth/prop/blocks/in/traffic", nil) 30 propBlockOutPacketsMeter = metrics.NewRegisteredMeter("eth/prop/blocks/out/packets", nil) 31 propBlockOutTrafficMeter = metrics.NewRegisteredMeter("eth/prop/blocks/out/traffic", nil) 32 reqHeaderInPacketsMeter = metrics.NewRegisteredMeter("eth/req/headers/in/packets", nil) 33 reqHeaderInTrafficMeter = metrics.NewRegisteredMeter("eth/req/headers/in/traffic", nil) 34 reqHeaderOutPacketsMeter = metrics.NewRegisteredMeter("eth/req/headers/out/packets", nil) 35 reqHeaderOutTrafficMeter = metrics.NewRegisteredMeter("eth/req/headers/out/traffic", nil) 36 reqBodyInPacketsMeter = metrics.NewRegisteredMeter("eth/req/bodies/in/packets", nil) 37 reqBodyInTrafficMeter = metrics.NewRegisteredMeter("eth/req/bodies/in/traffic", nil) 38 reqBodyOutPacketsMeter = metrics.NewRegisteredMeter("eth/req/bodies/out/packets", nil) 39 reqBodyOutTrafficMeter = metrics.NewRegisteredMeter("eth/req/bodies/out/traffic", nil) 40 reqStateInPacketsMeter = metrics.NewRegisteredMeter("eth/req/states/in/packets", nil) 41 reqStateInTrafficMeter = metrics.NewRegisteredMeter("eth/req/states/in/traffic", nil) 42 reqStateOutPacketsMeter = metrics.NewRegisteredMeter("eth/req/states/out/packets", nil) 43 reqStateOutTrafficMeter = metrics.NewRegisteredMeter("eth/req/states/out/traffic", nil) 44 reqReceiptInPacketsMeter = metrics.NewRegisteredMeter("eth/req/receipts/in/packets", nil) 45 reqReceiptInTrafficMeter = metrics.NewRegisteredMeter("eth/req/receipts/in/traffic", nil) 46 reqReceiptOutPacketsMeter = metrics.NewRegisteredMeter("eth/req/receipts/out/packets", nil) 47 reqReceiptOutTrafficMeter = metrics.NewRegisteredMeter("eth/req/receipts/out/traffic", nil) 48 miscInPacketsMeter = metrics.NewRegisteredMeter("eth/misc/in/packets", nil) 49 miscInTrafficMeter = metrics.NewRegisteredMeter("eth/misc/in/traffic", nil) 50 miscOutPacketsMeter = metrics.NewRegisteredMeter("eth/misc/out/packets", nil) 51 miscOutTrafficMeter = metrics.NewRegisteredMeter("eth/misc/out/traffic", nil) 52 ) 53 54 // meteredMsgReadWriter is a wrapper around a p2p.MsgReadWriter, capable of 55 // accumulating the above defined metrics based on the data stream contents. 56 type meteredMsgReadWriter struct { 57 p2p.MsgReadWriter // Wrapped message stream to meter 58 version int // Protocol version to select correct meters 59 } 60 61 // newMeteredMsgWriter wraps a p2p MsgReadWriter with metering support. If the 62 // metrics system is disabled, this function returns the original object. 63 func newMeteredMsgWriter(rw p2p.MsgReadWriter) p2p.MsgReadWriter { 64 if !metrics.Enabled { 65 return rw 66 } 67 return &meteredMsgReadWriter{MsgReadWriter: rw} 68 } 69 70 // Init sets the protocol version used by the stream to know which meters to 71 // increment in case of overlapping message ids between protocol versions. 72 func (rw *meteredMsgReadWriter) Init(version int) { 73 rw.version = version 74 } 75 76 func (rw *meteredMsgReadWriter) ReadMsg() (p2p.Msg, error) { 77 // Read the message and short circuit in case of an error 78 msg, err := rw.MsgReadWriter.ReadMsg() 79 if err != nil { 80 return msg, err 81 } 82 // Account for the data traffic 83 packets, traffic := miscInPacketsMeter, miscInTrafficMeter 84 switch { 85 case msg.Code == BlockHeadersMsg: 86 packets, traffic = reqHeaderInPacketsMeter, reqHeaderInTrafficMeter 87 case msg.Code == BlockBodiesMsg: 88 packets, traffic = reqBodyInPacketsMeter, reqBodyInTrafficMeter 89 90 case rw.version >= eth63 && msg.Code == NodeDataMsg: 91 packets, traffic = reqStateInPacketsMeter, reqStateInTrafficMeter 92 case rw.version >= eth63 && msg.Code == ReceiptsMsg: 93 packets, traffic = reqReceiptInPacketsMeter, reqReceiptInTrafficMeter 94 95 case msg.Code == NewBlockHashesMsg: 96 packets, traffic = propHashInPacketsMeter, propHashInTrafficMeter 97 case msg.Code == NewBlockMsg: 98 packets, traffic = propBlockInPacketsMeter, propBlockInTrafficMeter 99 case msg.Code == TxMsg: 100 packets, traffic = propTxnInPacketsMeter, propTxnInTrafficMeter 101 } 102 packets.Mark(1) 103 traffic.Mark(int64(msg.Size)) 104 105 return msg, err 106 } 107 108 func (rw *meteredMsgReadWriter) WriteMsg(msg p2p.Msg) error { 109 // Account for the data traffic 110 packets, traffic := miscOutPacketsMeter, miscOutTrafficMeter 111 switch { 112 case msg.Code == BlockHeadersMsg: 113 packets, traffic = reqHeaderOutPacketsMeter, reqHeaderOutTrafficMeter 114 case msg.Code == BlockBodiesMsg: 115 packets, traffic = reqBodyOutPacketsMeter, reqBodyOutTrafficMeter 116 117 case rw.version >= eth63 && msg.Code == NodeDataMsg: 118 packets, traffic = reqStateOutPacketsMeter, reqStateOutTrafficMeter 119 case rw.version >= eth63 && msg.Code == ReceiptsMsg: 120 packets, traffic = reqReceiptOutPacketsMeter, reqReceiptOutTrafficMeter 121 122 case msg.Code == NewBlockHashesMsg: 123 packets, traffic = propHashOutPacketsMeter, propHashOutTrafficMeter 124 case msg.Code == NewBlockMsg: 125 packets, traffic = propBlockOutPacketsMeter, propBlockOutTrafficMeter 126 case msg.Code == TxMsg: 127 packets, traffic = propTxnOutPacketsMeter, propTxnOutTrafficMeter 128 } 129 packets.Mark(1) 130 traffic.Mark(int64(msg.Size)) 131 132 // Send the packet to the p2p layer 133 return rw.MsgReadWriter.WriteMsg(msg) 134 }