From 8501906509321efecaf0878cdb0b94abcdde9e09 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 17 Jul 2024 16:19:11 -0700 Subject: [PATCH] Use int for meter and instrument hashes --- .../System/Diagnostics/Metrics/Instrument.cs | 2 - .../src/System/Diagnostics/Metrics/Meter.cs | 2 - .../Diagnostics/Metrics/MetricsEventSource.cs | 34 ++++++------- .../tests/MetricEventSourceTests.cs | 48 +++++++++---------- 4 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs index ef6a84b0c9688..8ece16419aff7 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Instrument.cs @@ -14,7 +14,6 @@ public abstract class Instrument internal static KeyValuePair[] EmptyTags => Array.Empty>(); private string? _formattedTags; - private string? _formattedHash; // The SyncObject is used to synchronize the following operations: // - Instrument.Publish() @@ -147,7 +146,6 @@ protected void Publish() public virtual bool IsObservable => false; internal string FormattedTags => _formattedTags ??= Helpers.FormatTags(Tags); - internal string FormattedHash => _formattedHash ??= Helpers.FormatObjectHash(this); // NotifyForUnpublishedInstrument is called from Meter.Dispose() internal void NotifyForUnpublishedInstrument() diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs index de591f2ee8397..1cbbad0b75d47 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/Meter.cs @@ -20,7 +20,6 @@ public class Meter : IDisposable private string? _formattedTags; private string? _formattedScopeHash; - private string? _formattedHash; internal bool Disposed { get; private set; } @@ -28,7 +27,6 @@ public class Meter : IDisposable internal string FormattedTags => _formattedTags ??= Helpers.FormatTags(Tags); internal string FormattedScopeHash => _formattedScopeHash ??= Helpers.FormatObjectHash(Scope); - internal string FormattedHash => _formattedHash ??= Helpers.FormatObjectHash(this); private static bool InitializeIsSupported() => AppContext.TryGetSwitch("System.Diagnostics.Metrics.Meter.IsSupported", out bool isSupported) ? isSupported : true; diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs index 1a88598e512e3..2aaf7df30e456 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs @@ -121,7 +121,7 @@ public void CollectionStop(string sessionId, DateTime intervalStartTime, DateTim Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif public void CounterRateValuePublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string? unit, string tags, string rate, string value, - string instrumentTags, string instrumentHash, string meterTags, string meterHash, string scopeHash) + string instrumentTags, int instrumentHash, string meterTags, int meterHash, string scopeHash) { WriteEvent(4, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, rate, value, instrumentTags, instrumentHash, meterTags, meterHash, scopeHash); } @@ -132,7 +132,7 @@ public void CounterRateValuePublished(string sessionId, string meterName, string Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif public void GaugeValuePublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string? unit, string tags, string lastValue, - string instrumentTags, string instrumentHash, string meterTags, string meterHash, string scopeHash) + string instrumentTags, int instrumentHash, string meterTags, int meterHash, string scopeHash) { WriteEvent(5, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, lastValue, instrumentTags, instrumentHash, meterTags, meterHash, scopeHash); } @@ -143,7 +143,7 @@ public void GaugeValuePublished(string sessionId, string meterName, string? mete Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif public void HistogramValuePublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string? unit, string tags, string quantiles, int count, double sum, - string instrumentTags, string instrumentHash, string meterTags, string meterHash, string scopeHash) + string instrumentTags, int instrumentHash, string meterTags, int meterHash, string scopeHash) { WriteEvent(6, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, quantiles, count, sum, instrumentTags, instrumentHash, meterTags, meterHash, scopeHash); } @@ -167,8 +167,8 @@ public void BeginInstrumentReporting( string instrumentTags, string meterTags, string meterScopeHash, - string instrumentHash, - string meterHash) + int instrumentHash, + int meterHash) { WriteEvent(7, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "", instrumentTags, meterTags, meterScopeHash, instrumentHash, meterHash); @@ -192,8 +192,8 @@ public void EndInstrumentReporting( string instrumentTags, string meterTags, string meterScopeHash, - string instrumentHash, - string meterHash) + int instrumentHash, + int meterHash) { WriteEvent(8, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "", instrumentTags, meterTags, meterScopeHash, instrumentHash, meterHash); @@ -227,8 +227,8 @@ public void InstrumentPublished( string instrumentTags, string meterTags, string meterScopeHash, - string instrumentHash, - string meterHash) + int instrumentHash, + int meterHash) { WriteEvent(11, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "", instrumentTags, meterTags, meterScopeHash, instrumentHash, meterHash); @@ -264,7 +264,7 @@ public void MultipleSessionsNotSupportedError(string runningSessionId) Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")] #endif public void UpDownCounterRateValuePublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string? unit, string tags, string rate, string value, - string instrumentTags, string instrumentHash, string meterTags, string meterHash, string scopeHash) + string instrumentTags, int instrumentHash, string meterTags, int meterHash, string scopeHash) { WriteEvent(16, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, rate, value, instrumentTags, instrumentHash, meterTags, meterHash, scopeHash); } @@ -448,11 +448,11 @@ public void OnEventCommand(EventCommandEventArgs command) (startIntervalTime, endIntervalTime) => Parent.CollectionStart(sessionId, startIntervalTime, endIntervalTime), (startIntervalTime, endIntervalTime) => Parent.CollectionStop(sessionId, startIntervalTime, endIntervalTime), i => Parent.BeginInstrumentReporting(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description, - i.FormattedTags, i.Meter.FormattedTags, i.Meter.FormattedScopeHash, i.FormattedHash, i.Meter.FormattedHash), + i.FormattedTags, i.Meter.FormattedTags, i.Meter.FormattedScopeHash, RuntimeHelpers.GetHashCode(i), RuntimeHelpers.GetHashCode(i.Meter)), i => Parent.EndInstrumentReporting(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description, - i.FormattedTags, i.Meter.FormattedTags, i.Meter.FormattedScopeHash, i.FormattedHash, i.Meter.FormattedHash), + i.FormattedTags, i.Meter.FormattedTags, i.Meter.FormattedScopeHash, RuntimeHelpers.GetHashCode(i), RuntimeHelpers.GetHashCode(i.Meter)), i => Parent.InstrumentPublished(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description, - i.FormattedTags, i.Meter.FormattedTags, i.Meter.FormattedScopeHash, i.FormattedHash, i.Meter.FormattedHash), + i.FormattedTags, i.Meter.FormattedTags, i.Meter.FormattedScopeHash, RuntimeHelpers.GetHashCode(i), RuntimeHelpers.GetHashCode(i.Meter)), () => Parent.InitialInstrumentEnumerationComplete(sessionId), e => Parent.Error(sessionId, e.ToString()), () => Parent.TimeSeriesLimitReached(sessionId), @@ -675,25 +675,25 @@ private static void TransmitMetricValue(Instrument instrument, LabeledAggregatio { Log.CounterRateValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, Helpers.FormatTags(stats.Labels), rateStats.Delta.HasValue ? rateStats.Delta.Value.ToString(CultureInfo.InvariantCulture) : "", rateStats.Value.ToString(CultureInfo.InvariantCulture), - instrument.FormattedTags, instrument.FormattedHash, instrument.Meter.FormattedTags, instrument.Meter.FormattedHash, instrument.Meter.FormattedScopeHash); + instrument.FormattedTags, RuntimeHelpers.GetHashCode(instrument), instrument.Meter.FormattedTags, RuntimeHelpers.GetHashCode(instrument.Meter), instrument.Meter.FormattedScopeHash); } else { Log.UpDownCounterRateValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, Helpers.FormatTags(stats.Labels), rateStats.Delta.HasValue ? rateStats.Delta.Value.ToString(CultureInfo.InvariantCulture) : "", rateStats.Value.ToString(CultureInfo.InvariantCulture), - instrument.FormattedTags, instrument.FormattedHash, instrument.Meter.FormattedTags, instrument.Meter.FormattedHash, instrument.Meter.FormattedScopeHash); + instrument.FormattedTags, RuntimeHelpers.GetHashCode(instrument), instrument.Meter.FormattedTags, RuntimeHelpers.GetHashCode(instrument.Meter), instrument.Meter.FormattedScopeHash); } } else if (stats.AggregationStatistics is LastValueStatistics lastValueStats) { Log.GaugeValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, Helpers.FormatTags(stats.Labels), lastValueStats.LastValue.HasValue ? lastValueStats.LastValue.Value.ToString(CultureInfo.InvariantCulture) : "", - instrument.FormattedTags, instrument.FormattedHash, instrument.Meter.FormattedTags, instrument.Meter.FormattedHash, instrument.Meter.FormattedScopeHash); + instrument.FormattedTags, RuntimeHelpers.GetHashCode(instrument), instrument.Meter.FormattedTags, RuntimeHelpers.GetHashCode(instrument.Meter), instrument.Meter.FormattedScopeHash); } else if (stats.AggregationStatistics is HistogramStatistics histogramStats) { Log.HistogramValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, Helpers.FormatTags(stats.Labels), FormatQuantiles(histogramStats.Quantiles), - histogramStats.Count, histogramStats.Sum, instrument.FormattedTags, instrument.FormattedHash, instrument.Meter.FormattedTags, instrument.Meter.FormattedHash, instrument.Meter.FormattedScopeHash); + histogramStats.Count, histogramStats.Sum, instrument.FormattedTags, RuntimeHelpers.GetHashCode(instrument), instrument.Meter.FormattedTags, RuntimeHelpers.GetHashCode(instrument.Meter), instrument.Meter.FormattedScopeHash); } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs index f0285b8f28b15..5c11b2053c112 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs @@ -1645,14 +1645,14 @@ public void TestDifferentMetersAndInstruments(MeterInstrumentContainer data) Rate = e.Payload[6].ToString(), Value = e.Payload[7].ToString(), InstrumentFormattedTags = e.Payload[8].ToString(), - InstrumentFormattedHash = e.Payload[9].ToString(), + InstrumentHash = (int)(e.Payload[9]), MeterFormattedTags = e.Payload[10].ToString(), - MeterFormattedHash = e.Payload[11].ToString(), + MeterHash = (int)(e.Payload[11]), MeterScopeHash = e.Payload[12].ToString() }).ToArray(); - var counter1Events = counterEvents.Where(e => e.InstrumentFormattedHash == Helpers.FormatObjectHash(data.Counter1)).ToArray(); - var counter2Events = counterEvents.Where(e => e.InstrumentFormattedHash == Helpers.FormatObjectHash(data.Counter2)).ToArray(); + var counter1Events = counterEvents.Where(e => e.InstrumentHash == RuntimeHelpers.GetHashCode(data.Counter1)).ToArray(); + var counter2Events = counterEvents.Where(e => e.InstrumentHash == RuntimeHelpers.GetHashCode(data.Counter2)).ToArray(); var instrument1Event = counter1Events[0]; var instrument2Event = counter2Events[0]; @@ -1660,17 +1660,17 @@ public void TestDifferentMetersAndInstruments(MeterInstrumentContainer data) Assert.Equal(counter1Events.Length, counter2Events.Length); Assert.Equal(1, counter1Events.Length); Assert.Equal(1, counter2Events.Length); - Assert.Equal(counter1Events[0].InstrumentFormattedHash, Helpers.FormatObjectHash(data.Counter1)); + Assert.Equal(counter1Events[0].InstrumentHash, RuntimeHelpers.GetHashCode(data.Counter1)); if (data.SameInstrumentInstances || (data.SameMeterInstances && data.SameInstrumentNames && data.SameInstrumentTags)) { - Assert.Equal(counter1Events[0].InstrumentFormattedHash, counter2Events[0].InstrumentFormattedHash); - Assert.Equal(counter1Events[0].InstrumentFormattedHash, Helpers.FormatObjectHash(data.Counter2)); + Assert.Equal(counter1Events[0].InstrumentHash, counter2Events[0].InstrumentHash); + Assert.Equal(counter1Events[0].InstrumentHash, RuntimeHelpers.GetHashCode(data.Counter2)); Assert.Equal("2", instrument1Event.Value); } else { - Assert.Equal(counter2Events[0].InstrumentFormattedHash, Helpers.FormatObjectHash(data.Counter2)); + Assert.Equal(counter2Events[0].InstrumentHash, RuntimeHelpers.GetHashCode(data.Counter2)); Assert.Equal("1", instrument1Event.Value); Assert.Equal("1", instrument2Event.Value); } @@ -1680,7 +1680,7 @@ public void TestDifferentMetersAndInstruments(MeterInstrumentContainer data) Assert.Equal(data.SameMeterVersion, instrument1Event.MeterVersion == instrument2Event.MeterVersion); Assert.Equal(data.SameMeterTags, instrument1Event.MeterFormattedTags == instrument2Event.MeterFormattedTags); Assert.Equal(data.SameScopeInstances, instrument1Event.MeterScopeHash == instrument2Event.MeterScopeHash); - Assert.Equal(data.SameMeterInstances, instrument1Event.MeterFormattedHash == instrument2Event.MeterFormattedHash); + Assert.Equal(data.SameMeterInstances, instrument1Event.MeterHash == instrument2Event.MeterHash); Assert.Equal(data.SameInstrumentNames, instrument1Event.InstrumentName == instrument2Event.InstrumentName); } @@ -1832,17 +1832,17 @@ private static void AssertGenericCounterEventsPresent(string eventName, EventWri Rate = e.Payload[6].ToString(), Value = e.Payload[7].ToString(), InstrumentFormattedTags = e.Payload[8].ToString(), - InstrumentFormattedHash = e.Payload[9].ToString(), + InstrumentHash = (int)(e.Payload[9]), MeterFormattedTags = e.Payload[10].ToString(), - MeterFormattedHash = e.Payload[11].ToString(), + MeterHash = (int)(e.Payload[11]), MeterScopeHash = e.Payload[12].ToString() }).ToArray(); - var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags && e.InstrumentFormattedHash == Helpers.FormatObjectHash(instrument)).ToArray(); + var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags && e.InstrumentHash == RuntimeHelpers.GetHashCode(instrument)).ToArray(); Assert.True(filteredEvents.Length >= expected.Length); string formattedInstrumentTags = Helpers.FormatTags(instrument.Tags); string formattedMeterTags = Helpers.FormatTags(instrument.Meter.Tags); - string formattedMeterHash = Helpers.FormatObjectHash(instrument.Meter); + int meterHash = RuntimeHelpers.GetHashCode(instrument.Meter); string formattedMeterScopeHash = Helpers.FormatObjectHash(instrument.Meter.Scope); for (int i = 0; i < expected.Length; i++) @@ -1853,7 +1853,7 @@ private static void AssertGenericCounterEventsPresent(string eventName, EventWri Assert.Equal(formattedInstrumentTags, filteredEvents[i].InstrumentFormattedTags); Assert.Equal(formattedMeterTags, filteredEvents[i].MeterFormattedTags); - Assert.Equal(formattedMeterHash, filteredEvents[i].MeterFormattedHash); + Assert.Equal(meterHash, filteredEvents[i].MeterHash); Assert.Equal(formattedMeterScopeHash, filteredEvents[i].MeterScopeHash); } } @@ -1885,17 +1885,17 @@ private static void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, str Tags = e.Payload[5].ToString(), Value = e.Payload[6].ToString(), InstrumentFormattedTags = e.Payload[7].ToString(), - InstrumentFormattedHash = e.Payload[8].ToString(), + InstrumentHash = (int)(e.Payload[8]), MeterFormattedTags = e.Payload[9].ToString(), - MeterFormattedHash = e.Payload[10].ToString(), + MeterHash = (int)(e.Payload[10]), MeterScopeHash = e.Payload[11].ToString(), }).ToArray(); - var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags && e.InstrumentFormattedHash == Helpers.FormatObjectHash(instrument)).ToArray(); + var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags && e.InstrumentHash == RuntimeHelpers.GetHashCode(instrument)).ToArray(); Assert.True(filteredEvents.Length >= expectedValues.Length); string formattedInstrumentTags = Helpers.FormatTags(instrument.Tags); string formattedMeterTags = Helpers.FormatTags(instrument.Meter.Tags); - string formattedMeterHash = Helpers.FormatObjectHash(instrument.Meter); + int meterHash = RuntimeHelpers.GetHashCode(instrument.Meter); string formattedMeterScopeHash = Helpers.FormatObjectHash(instrument.Meter.Scope); for (int i = 0; i < expectedValues.Length; i++) @@ -1905,7 +1905,7 @@ private static void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, str Assert.Equal(formattedInstrumentTags, filteredEvents[i].InstrumentFormattedTags); Assert.Equal(formattedMeterTags, filteredEvents[i].MeterFormattedTags); - Assert.Equal(formattedMeterHash, filteredEvents[i].MeterFormattedHash); + Assert.Equal(meterHash, filteredEvents[i].MeterHash); Assert.Equal(formattedMeterScopeHash, filteredEvents[i].MeterScopeHash); } } @@ -1925,17 +1925,17 @@ private static void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, Count = e.Payload[7].ToString(), Sum = e.Payload[8].ToString(), InstrumentFormattedTags = e.Payload[9].ToString(), - InstrumentFormattedHash = e.Payload[10].ToString(), + InstrumentHash = (int)(e.Payload[10]), MeterFormattedTags = e.Payload[11].ToString(), - MeterFormattedHash = e.Payload[12].ToString(), + MeterHash = (int)(e.Payload[12]), MeterScopeHash = e.Payload[13].ToString() }).ToArray(); - var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags && e.InstrumentFormattedHash == Helpers.FormatObjectHash(instrument)).ToArray(); + var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags && e.InstrumentHash == RuntimeHelpers.GetHashCode(instrument)).ToArray(); Assert.True(filteredEvents.Length >= expected.Length); string formattedInstrumentTags = Helpers.FormatTags(instrument.Tags); string formattedMeterTags = Helpers.FormatTags(instrument.Meter.Tags); - string formattedMeterHash = Helpers.FormatObjectHash(instrument.Meter); + int meterHash = RuntimeHelpers.GetHashCode(instrument.Meter); string formattedMeterScopeHash = Helpers.FormatObjectHash(instrument.Meter.Scope); for (int i = 0; i < expected.Length; i++) @@ -1947,7 +1947,7 @@ private static void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, Assert.Equal(formattedInstrumentTags, filteredEvents[i].InstrumentFormattedTags); Assert.Equal(formattedMeterTags, filteredEvents[i].MeterFormattedTags); - Assert.Equal(formattedMeterHash, filteredEvents[i].MeterFormattedHash); + Assert.Equal(meterHash, filteredEvents[i].MeterHash); Assert.Equal(formattedMeterScopeHash, filteredEvents[i].MeterScopeHash); } }