diff --git a/src/Nethermind/Nethermind.Core/Metric/IMetricLabels.cs b/src/Nethermind/Nethermind.Core/Metric/IMetricLabels.cs new file mode 100644 index 00000000000..187e178c35a --- /dev/null +++ b/src/Nethermind/Nethermind.Core/Metric/IMetricLabels.cs @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +namespace Nethermind.Core.Metric; + +/// +/// Used by MetricController to provide labels. Useful in high performance scenario where you don't want to set a string +/// on the metric dictionary as key and/or you don't want to use tuple. +/// +public interface IMetricLabels +{ + string[] Labels { get; } +} diff --git a/src/Nethermind/Nethermind.Monitoring.Test/MetricsTests.cs b/src/Nethermind/Nethermind.Monitoring.Test/MetricsTests.cs index 86859aa654c..bf64368e9f2 100644 --- a/src/Nethermind/Nethermind.Monitoring.Test/MetricsTests.cs +++ b/src/Nethermind/Nethermind.Monitoring.Test/MetricsTests.cs @@ -11,6 +11,7 @@ using FluentAssertions; using Nethermind.Core; using Nethermind.Core.Attributes; +using Nethermind.Core.Metric; using Nethermind.Logging; using Nethermind.Monitoring.Config; using Nethermind.Monitoring.Metrics; @@ -34,6 +35,9 @@ public static class TestMetrics [KeyIsLabel("somelabel")] public static ConcurrentDictionary WithLabelledDictionary { get; set; } = new(); + [KeyIsLabel("label1", "label2", "label3")] + public static ConcurrentDictionary WithCustomLabelType { get; set; } = new(); + public static IDictionary OldDictionaryMetrics { get; set; } = new ConcurrentDictionary(); } @@ -43,6 +47,11 @@ public enum SomeEnum Option2, } + public struct CustomLabelType(int num1, int num2, int num3) : IMetricLabels + { + public string[] Labels => [num1.ToString(), num2.ToString(), num3.ToString()]; + } + [Test] public void Test_update_correct_gauge() { @@ -57,6 +66,7 @@ public void Test_update_correct_gauge() TestMetrics.OneTwoThreeSpecial = 1234; TestMetrics.WithLabelledDictionary[SomeEnum.Option1] = 2; TestMetrics.WithLabelledDictionary[SomeEnum.Option2] = 3; + TestMetrics.WithCustomLabelType[new CustomLabelType(1, 11, 111)] = 1111; TestMetrics.OldDictionaryMetrics["metrics0"] = 4; TestMetrics.OldDictionaryMetrics["metrics1"] = 5; metricsController.UpdateMetrics(null); @@ -65,6 +75,7 @@ public void Test_update_correct_gauge() var keyDefault = $"{nameof(TestMetrics)}.{nameof(TestMetrics.OneTwoThree)}"; var keySpecial = $"{nameof(TestMetrics)}.{nameof(TestMetrics.OneTwoThreeSpecial)}"; var keyDictionary = $"{nameof(TestMetrics)}.{nameof(TestMetrics.WithLabelledDictionary)}"; + var keyDictionary2 = $"{nameof(TestMetrics)}.{nameof(TestMetrics.WithCustomLabelType)}"; var keyOldDictionary0 = $"{nameof(TestMetrics.OldDictionaryMetrics)}.metrics0"; var keyOldDictionary1 = $"{nameof(TestMetrics.OldDictionaryMetrics)}.metrics1"; @@ -81,6 +92,7 @@ public void Test_update_correct_gauge() Assert.That(gauges[keySpecial].Value, Is.EqualTo(1234)); Assert.That(gauges[keyDictionary].WithLabels(SomeEnum.Option1.ToString()).Value, Is.EqualTo(2)); Assert.That(gauges[keyDictionary].WithLabels(SomeEnum.Option2.ToString()).Value, Is.EqualTo(3)); + Assert.That(gauges[keyDictionary2].WithLabels("1", "11", "111").Value, Is.EqualTo(1111)); Assert.That(gauges[keyOldDictionary0].Value, Is.EqualTo(4)); Assert.That(gauges[keyOldDictionary1].Value, Is.EqualTo(5)); } diff --git a/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs b/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs index fc9c450673d..5e2e21c7f2d 100644 --- a/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs +++ b/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs @@ -15,6 +15,7 @@ using Nethermind.Core; using Nethermind.Core.Attributes; using Nethermind.Core.Collections; +using Nethermind.Core.Metric; using Nethermind.Monitoring.Config; using Prometheus; @@ -252,19 +253,25 @@ private void UpdateMetrics(Type type) foreach (object key in dict.Keys) { double value = Convert.ToDouble(dict[key]); - if (key is ITuple keyAsTuple) + switch (key) { - string[] labels = new string[keyAsTuple.Length]; - for (int i = 0; i < keyAsTuple.Length; i++) - { - labels[i] = keyAsTuple[i].ToString(); - } - - ReplaceValueIfChanged(value, gaugeName, labels); - } - else - { - ReplaceValueIfChanged(value, gaugeName, key.ToString()); + case IMetricLabels label: + ReplaceValueIfChanged(value, gaugeName, label.Labels); + break; + case ITuple keyAsTuple: + { + string[] labels = new string[keyAsTuple.Length]; + for (int i = 0; i < keyAsTuple.Length; i++) + { + labels[i] = keyAsTuple[i].ToString(); + } + + ReplaceValueIfChanged(value, gaugeName, labels); + break; + } + default: + ReplaceValueIfChanged(value, gaugeName, key.ToString()); + break; } } } diff --git a/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs b/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs index f87ea2f89c6..0a4c63b9d6b 100644 --- a/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/P2P/SessionTests.cs @@ -13,6 +13,7 @@ using Nethermind.Network.P2P.ProtocolHandlers; using Nethermind.Network.Rlpx; using Nethermind.Stats.Model; +using NonBlocking; using NSubstitute; using NSubstitute.ReceivedExtensions; using NUnit.Framework; diff --git a/src/Nethermind/Nethermind.Network/Metrics.cs b/src/Nethermind/Nethermind.Network/Metrics.cs index 6313ebd34fc..d3a0ab87b64 100644 --- a/src/Nethermind/Nethermind.Network/Metrics.cs +++ b/src/Nethermind/Nethermind.Network/Metrics.cs @@ -1,10 +1,25 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Concurrent; +using System.Collections.Frozen; +using System.Collections.Generic; using System.ComponentModel; +using System.Linq; +using System.Reflection; using System.Runtime.Serialization; using Nethermind.Core.Attributes; +using Nethermind.Network.P2P; +using Nethermind.Network.P2P.Subprotocols.Eth.V62; +using Nethermind.Network.P2P.Subprotocols.Eth.V63; +using Nethermind.Network.P2P.Subprotocols.Eth.V65; +using Nethermind.Network.P2P.Subprotocols.Eth.V66; +using Nethermind.Network.P2P.Subprotocols.Eth.V68; +using Nethermind.Network.P2P.Subprotocols.Les; +using Nethermind.Network.P2P.Subprotocols.NodeData; +using Nethermind.Network.P2P.Subprotocols.Snap; +using Nethermind.Network.P2P.Subprotocols.Wit; using Nethermind.Stats.Model; namespace Nethermind.Network @@ -37,27 +52,27 @@ public static class Metrics public static long HandshakeTimeouts { get; set; } [CounterMetric] - [Description("Number of devp2p hello messages received")] + [Description("_Deprecated._ Number of devp2p hello messages received")] public static long HellosReceived { get; set; } [CounterMetric] - [Description("Number of devp2p hello messages sent")] + [Description("_Deprecated._ Number of devp2p hello messages sent")] public static long HellosSent { get; set; } [CounterMetric] - [Description("Number of eth status messages received")] + [Description("_Deprecated._ Number of eth status messages received")] public static long StatusesReceived { get; set; } [CounterMetric] - [Description("Number of eth status messages sent")] + [Description("_Deprecated._ Number of eth status messages sent")] public static long StatusesSent { get; set; } [CounterMetric] - [Description("Number of les status messages received")] + [Description("_Deprecated._ Number of les status messages received")] public static long LesStatusesReceived { get; set; } [CounterMetric] - [Description("Number of les status messages sent")] + [Description("_Deprecated._ Number of les status messages sent")] public static long LesStatusesSent { get; set; } [CounterMetric] @@ -165,183 +180,183 @@ public static class Metrics public static long LocalTcpSubsystemErrorDisconnects { get; set; } [CounterMetric] - [Description("Number of eth.62 NewBlockHashes messages received")] + [Description("_Deprecated._ Number of eth.62 NewBlockHashes messages received")] public static long Eth62NewBlockHashesReceived { get; set; } [CounterMetric] - [Description("Number of eth.62 Transactions messages received")] + [Description("_Deprecated._ Number of eth.62 Transactions messages received")] public static long Eth62TransactionsReceived { get; set; } [CounterMetric] - [Description("Number of eth.62 GetBlockHeaders messages received")] + [Description("_Deprecated._ Number of eth.62 GetBlockHeaders messages received")] public static long Eth62GetBlockHeadersReceived { get; set; } [CounterMetric] - [Description("Number of eth.62 BlockHeaders messages received")] + [Description("_Deprecated._ Number of eth.62 BlockHeaders messages received")] public static long Eth62BlockHeadersReceived { get; set; } [CounterMetric] - [Description("Number of eth.62 GetBlockBodies messages received")] + [Description("_Deprecated._ Number of eth.62 GetBlockBodies messages received")] public static long Eth62GetBlockBodiesReceived { get; set; } [CounterMetric] - [Description("Number of eth.62 BlockBodies messages received")] + [Description("_Deprecated._ Number of eth.62 BlockBodies messages received")] public static long Eth62BlockBodiesReceived { get; set; } [CounterMetric] - [Description("Number of eth.62 NewBlock messages received")] + [Description("_Deprecated._ Number of eth.62 NewBlock messages received")] public static long Eth62NewBlockReceived { get; set; } [CounterMetric] - [Description("Number of eth.63 GetReceipts messages received")] + [Description("_Deprecated._ Number of eth.63 GetReceipts messages received")] public static long Eth63GetReceiptsReceived { get; set; } [CounterMetric] - [Description("Number of eth.63 Receipts messages received")] + [Description("_Deprecated._ Number of eth.63 Receipts messages received")] public static long Eth63ReceiptsReceived { get; set; } [CounterMetric] - [Description("Number of eth.63 GetNodeData messages received")] + [Description("_Deprecated._ Number of eth.63 GetNodeData messages received")] public static long Eth63GetNodeDataReceived { get; set; } [CounterMetric] - [Description("Number of eth.63 NodeData messages received")] + [Description("_Deprecated._ Number of eth.63 NodeData messages received")] public static long Eth63NodeDataReceived { get; set; } [CounterMetric] - [Description("Number of eth.65 NewPooledTransactionHashes messages received")] + [Description("_Deprecated._ Number of eth.65 NewPooledTransactionHashes messages received")] public static long Eth65NewPooledTransactionHashesReceived { get; set; } [CounterMetric] - [Description("Number of eth.65 NewPooledTransactionHashes messages sent")] + [Description("_Deprecated._ Number of eth.65 NewPooledTransactionHashes messages sent")] public static long Eth65NewPooledTransactionHashesSent { get; set; } [CounterMetric] - [Description("Number of eth.68 NewPooledTransactionHashes messages received")] + [Description("_Deprecated._ Number of eth.68 NewPooledTransactionHashes messages received")] public static long Eth68NewPooledTransactionHashesReceived { get; set; } [CounterMetric] - [Description("Number of eth.68 NewPooledTransactionHashes messages sent")] + [Description("_Deprecated._ Number of eth.68 NewPooledTransactionHashes messages sent")] public static long Eth68NewPooledTransactionHashesSent { get; set; } [CounterMetric] - [Description("Number of eth.65 GetPooledTransactions messages received")] + [Description("_Deprecated._ Number of eth.65 GetPooledTransactions messages received")] public static long Eth65GetPooledTransactionsReceived { get; set; } [CounterMetric] - [Description("Number of eth.65 GetPooledTransactions messages sent")] + [Description("_Deprecated._ Number of eth.65 GetPooledTransactions messages sent")] public static long Eth65GetPooledTransactionsRequested { get; set; } [CounterMetric] - [Description("Number of eth.65 PooledTransactions messages received")] + [Description("_Deprecated._ Number of eth.65 PooledTransactions messages received")] public static long Eth65PooledTransactionsReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 GetBlockHeaders messages received")] + [Description("_Deprecated._ Number of eth.66 GetBlockHeaders messages received")] public static long Eth66GetBlockHeadersReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 BlockHeaders messages received")] + [Description("_Deprecated._ Number of eth.66 BlockHeaders messages received")] public static long Eth66BlockHeadersReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 GetBlockBodies messages received")] + [Description("_Deprecated._ Number of eth.66 GetBlockBodies messages received")] public static long Eth66GetBlockBodiesReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 BlockBodies messages received")] + [Description("_Deprecated._ Number of eth.66 BlockBodies messages received")] public static long Eth66BlockBodiesReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 GetNodeData messages received")] + [Description("_Deprecated._ Number of eth.66 GetNodeData messages received")] public static long Eth66GetNodeDataReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 NodeData messages received")] + [Description("_Deprecated._ Number of eth.66 NodeData messages received")] public static long Eth66NodeDataReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 GetReceipts messages received")] + [Description("_Deprecated._ Number of eth.66 GetReceipts messages received")] public static long Eth66GetReceiptsReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 Receipts messages received")] + [Description("_Deprecated._ Number of eth.66 Receipts messages received")] public static long Eth66ReceiptsReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 GetPooledTransactions messages received")] + [Description("_Deprecated._ Number of eth.66 GetPooledTransactions messages received")] public static long Eth66GetPooledTransactionsReceived { get; set; } [CounterMetric] - [Description("Number of eth.66 GetPooledTransactions messages sent")] + [Description("_Deprecated._ Number of eth.66 GetPooledTransactions messages sent")] public static long Eth66GetPooledTransactionsRequested { get; set; } [CounterMetric] - [Description("Number of eth.66 PooledTransactions messages received")] + [Description("_Deprecated._ Number of eth.66 PooledTransactions messages received")] public static long Eth66PooledTransactionsReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetAccountRange messages received")] + [Description("_Deprecated._ Number of SNAP GetAccountRange messages received")] public static long SnapGetAccountRangeReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetAccountRange messages sent")] + [Description("_Deprecated._ Number of SNAP GetAccountRange messages sent")] public static long SnapGetAccountRangeSent { get; set; } [CounterMetric] - [Description("Number of SNAP AccountRange messages received")] + [Description("_Deprecated._ Number of SNAP AccountRange messages received")] public static long SnapAccountRangeReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetStorageRanges messages received")] + [Description("_Deprecated._ Number of SNAP GetStorageRanges messages received")] public static long SnapGetStorageRangesReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetStorageRanges messages sent")] + [Description("_Deprecated._ Number of SNAP GetStorageRanges messages sent")] public static long SnapGetStorageRangesSent { get; set; } [CounterMetric] - [Description("Number of SNAP StorageRanges messages received")] + [Description("_Deprecated._ Number of SNAP StorageRanges messages received")] public static long SnapStorageRangesReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetByteCodes messages received")] + [Description("_Deprecated._ Number of SNAP GetByteCodes messages received")] public static long SnapGetByteCodesReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetByteCodes messages sent")] + [Description("_Deprecated._ Number of SNAP GetByteCodes messages sent")] public static long SnapGetByteCodesSent { get; set; } [CounterMetric] - [Description("Number of SNAP ByteCodes messages received")] + [Description("_Deprecated._ Number of SNAP ByteCodes messages received")] public static long SnapByteCodesReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetTrieNodes messages received")] + [Description("_Deprecated._ Number of SNAP GetTrieNodes messages received")] public static long SnapGetTrieNodesReceived { get; set; } [CounterMetric] - [Description("Number of SNAP GetTrieNodes messages sent")] + [Description("_Deprecated._ Number of SNAP GetTrieNodes messages sent")] public static long SnapGetTrieNodesSent { get; set; } [CounterMetric] - [Description("Number of SNAP TrieNodes messages received")] + [Description("_Deprecated._ Number of SNAP TrieNodes messages received")] public static long SnapTrieNodesReceived { get; set; } [CounterMetric] - [Description("Number of GetNodeData messages received via NodeData protocol")] + [Description("_Deprecated._ Number of GetNodeData messages received via NodeData protocol")] public static long GetNodeDataReceived { get; set; } [CounterMetric] - [Description("Number of NodeData messages received via NodeData protocol")] + [Description("_Deprecated._ Number of NodeData messages received via NodeData protocol")] public static long NodeDataReceived { get; set; } [CounterMetric] - [Description("Number of bytes sent through P2P (TCP).")] + [Description("_Deprecated._ Number of bytes sent through P2P (TCP).")] public static long P2PBytesSent; [CounterMetric] - [Description("Number of bytes received through P2P (TCP).")] + [Description("_Deprecated._ Number of bytes received through P2P (TCP).")] public static long P2PBytesReceived; [CounterMetric] @@ -364,5 +379,29 @@ public static class Metrics [Description("The maximum number of peers this node allows to connect.")] [DataMember(Name = "ethereum_peer_limit")] public static long PeerLimit { get; set; } + + [CounterMetric] + [DataMember(Name = "nethermind_outgoing_p2p_messages")] + [Description("Number of outgoing p2p packets.")] + [KeyIsLabel("protocol", "message")] + public static NonBlocking.ConcurrentDictionary OutgoingP2PMessages { get; } = new(); + + [CounterMetric] + [DataMember(Name = "nethermind_outgoing_p2p_message_bytes")] + [Description("Bytes of outgoing p2p packets.")] + [KeyIsLabel("protocol", "message")] + public static NonBlocking.ConcurrentDictionary OutgoingP2PMessageBytes { get; } = new(); + + [CounterMetric] + [DataMember(Name = "nethermind_incoming_p2p_messages")] + [Description("Number of incoming p2p packets.")] + [KeyIsLabel("protocol", "message")] + public static NonBlocking.ConcurrentDictionary IncomingP2PMessages { get; } = new(); + + [CounterMetric] + [DataMember(Name = "nethermind_incoming_p2p_message_bytes")] + [Description("Bytes of incoming p2p packets.")] + [KeyIsLabel("protocol", "message")] + public static NonBlocking.ConcurrentDictionary IncomingP2PMessageBytes { get; } = new(); } } diff --git a/src/Nethermind/Nethermind.Network/P2P/P2PMessageKey.cs b/src/Nethermind/Nethermind.Network/P2P/P2PMessageKey.cs new file mode 100644 index 00000000000..8f4e62c8c57 --- /dev/null +++ b/src/Nethermind/Nethermind.Network/P2P/P2PMessageKey.cs @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Nethermind.Core.Metric; +using Nethermind.Network.P2P.Subprotocols.Eth.V62; +using Nethermind.Network.P2P.Subprotocols.Eth.V63; +using Nethermind.Network.P2P.Subprotocols.Eth.V65; +using Nethermind.Network.P2P.Subprotocols.Eth.V66; +using Nethermind.Network.P2P.Subprotocols.Eth.V68; +using Nethermind.Network.P2P.Subprotocols.Les; +using Nethermind.Network.P2P.Subprotocols.NodeData; +using Nethermind.Network.P2P.Subprotocols.Snap; +using Nethermind.Network.P2P.Subprotocols.Wit; + +namespace Nethermind.Network.P2P; + +public readonly record struct VersionedProtocol(string Protocol, byte Version); + +public record struct P2PMessageKey(VersionedProtocol Protocol, int PacketType) : IMetricLabels +{ + private static readonly FrozenDictionary<(string, int), string> MessageNames = + FromMessageCodeClass(Contract.P2P.Protocol.P2P, typeof(P2PMessageCode)) + + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Eth, typeof(Eth62MessageCode))) + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Eth, typeof(Eth63MessageCode))) + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Eth, typeof(Eth65MessageCode))) + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Eth, typeof(Eth66MessageCode))) + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Eth, typeof(Eth68MessageCode))) + + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.NodeData, typeof(NodeDataMessageCode))) + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Wit, typeof(WitMessageCode))) + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Les, typeof(LesMessageCode))) + + .Concat(FromMessageCodeClass(Contract.P2P.Protocol.Snap, typeof(SnapMessageCode))) + + .ToFrozenDictionary(); + + private static IEnumerable> FromMessageCodeClass(string protocol, Type classType) => + classType.GetFields( + BindingFlags.Public | BindingFlags.Static) + .Where(field => field.FieldType.IsAssignableTo(typeof(int))) + .Select(field => KeyValuePair.Create((protocol, (int)field.GetValue(null)), field.Name)); + + private string[]? _labels = null; + public string[] Labels => _labels ??= CalculateLabel(); + + private string[] CalculateLabel() + { + return [$"{Protocol.Protocol}{Protocol.Version}", GetMessageType()]; + } + + private string GetMessageType() + { + if (!MessageNames.TryGetValue((Protocol.Protocol, PacketType), out string messageName)) + { +#if DEBUG + throw new NotImplementedException($"Message name for protocol {Protocol.Protocol} message id {PacketType} not set."); +#else + return PacketType.ToString(); // Just use the integer directly then +#endif + } + return messageName; + } + + public override string ToString() + { + return string.Join(',', Labels); + } +} diff --git a/src/Nethermind/Nethermind.Network/P2P/Session.cs b/src/Nethermind/Nethermind.Network/P2P/Session.cs index b6e5781b8ec..e29e2df39e8 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Session.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Session.cs @@ -178,6 +178,8 @@ public void ReceiveMessage(ZeroPacket zeroPacket) (string? protocol, int messageId) = _resolver.ResolveProtocol(zeroPacket.PacketType); zeroPacket.Protocol = protocol; + RecordIncomingMessageMetric(zeroPacket.Protocol, messageId, zeroPacket.Content.ReadableBytes); + if (_logger.IsTrace) _logger.Trace($"{this} received a message of length {zeroPacket.Content.ReadableBytes} " + $"({dynamicMessageCode} => {protocol}.{messageId})"); @@ -224,7 +226,11 @@ public int DeliverMessage(T message) where T : P2PMessage message.AdaptivePacketType = _resolver.ResolveAdaptiveId(message.Protocol, message.PacketType); int size = _packetSender.Enqueue(message); + + RecordOutgoingMessageMetric(message, size); + Interlocked.Add(ref Metrics.P2PBytesSent, size); + return size; } @@ -249,6 +255,8 @@ public void ReceiveMessage(Packet packet) (string protocol, int messageId) = _resolver.ResolveProtocol(packet.PacketType); packet.Protocol = protocol; + RecordIncomingMessageMetric(protocol, messageId, packet.Data.Length); + if (_logger.IsTrace) _logger.Trace($"{this} received a message of length {packet.Data.Length} " + $"({dynamicMessageCode} => {protocol}.{messageId})"); @@ -652,5 +660,42 @@ public void StartTrackingSession() { _isTracked = true; } + + private void RecordOutgoingMessageMetric(T message, int size) where T : P2PMessage + { + byte version = _protocols.TryGetValue(message.Protocol, out IProtocolHandler? handler) + ? handler!.ProtocolVersion + : (byte)0; + + P2PMessageKey metricKey = new P2PMessageKey(new VersionedProtocol(message.Protocol, version), message.PacketType); + Metrics.OutgoingP2PMessages.AddOrUpdate(metricKey, 0, IncrementMetric); + Metrics.OutgoingP2PMessageBytes.AddOrUpdate(metricKey, ZeroMetric, AddMetric, size); + } + + private void RecordIncomingMessageMetric(string protocol, int packetType, int size) + { + if (protocol == null) return; + byte version = _protocols.TryGetValue(protocol, out IProtocolHandler? handler) + ? handler!.ProtocolVersion + : (byte)0; + P2PMessageKey metricKey = new P2PMessageKey(new VersionedProtocol(protocol, version), packetType); + Metrics.IncomingP2PMessages.AddOrUpdate(metricKey, 0, IncrementMetric); + Metrics.IncomingP2PMessageBytes.AddOrUpdate(metricKey, ZeroMetric, AddMetric, size); + } + + private static long IncrementMetric(P2PMessageKey _, long value) + { + return value + 1; + } + + private static long ZeroMetric(P2PMessageKey _, int i) + { + return 0; + } + + private static long AddMetric(P2PMessageKey _, long value, int toAdd) + { + return value + toAdd; + } } } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62MessageCode.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62MessageCode.cs index f25b38c984d..af3e174de19 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62MessageCode.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62MessageCode.cs @@ -13,21 +13,5 @@ public static class Eth62MessageCode public const int GetBlockBodies = 0x05; public const int BlockBodies = 0x06; public const int NewBlock = 0x07; - - public static string GetDescription(int code) - { - return code switch - { - Status => nameof(Status), - NewBlockHashes => nameof(NewBlockHashes), - Transactions => nameof(Transactions), - GetBlockHeaders => nameof(GetBlockHeaders), - BlockHeaders => nameof(BlockHeaders), - GetBlockBodies => nameof(GetBlockBodies), - BlockBodies => nameof(BlockBodies), - NewBlock => nameof(NewBlock), - _ => $"Unknown({code.ToString()})" - }; - } } } diff --git a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs index 11e75e066ff..d800738904b 100644 --- a/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs +++ b/src/Nethermind/Nethermind.Network/P2P/Subprotocols/Eth/V62/Eth62ProtocolHandler.cs @@ -139,8 +139,6 @@ bool CanAcceptBlockGossip() throw new SubprotocolException($"No {nameof(StatusMessage)} received prior to communication with {Node:c}."); } - if (Logger.IsTrace) Logger.Trace($"{Counter:D5} {Eth62MessageCode.GetDescription(packetType)} from {Node:c}"); - switch (packetType) { case Eth62MessageCode.Status: