metrics.go 7.4 KB

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