metrics.go 6.7 KB

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