diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
index 49b7834a9de36..378251006567f 100644
--- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
+++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj
@@ -6,6 +6,8 @@
$(NoWarn);SA1205
false
true
+ true
+ 1
Provides Classes that allow you to decouple code logging rich (unserializable) diagnostics/telemetry (e.g. framework) from code that consumes it (e.g. tools)
Commonly Used Types:
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 41979421991f4..4b5da60a44156 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
@@ -737,7 +737,11 @@ private static string FormatQuantiles(QuantileValue[] quantiles)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < quantiles.Length; i++)
{
- sb.Append(quantiles[i].Quantile).Append('=').Append(quantiles[i].Value);
+#if NETCOREAPP
+ sb.Append(CultureInfo.InvariantCulture, $"{quantiles[i].Quantile}={quantiles[i].Value}");
+#else
+ sb.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}", quantiles[i].Quantile, quantiles[i].Value);
+#endif
if (i != quantiles.Length - 1)
{
sb.Append(';');
diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs
index 1902c2a6c4bdc..a6d2c4a6f2664 100644
--- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs
+++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Globalization;
@@ -9,7 +8,7 @@
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
-using System.Threading.Tasks;
+using Microsoft.DotNet.RemoteExecutor;
using Xunit;
using Xunit.Abstractions;
@@ -658,45 +657,59 @@ public void MultipleListeners_PublishingInstruments()
AssertInitialEnumerationCompleteEventPresent(events2);
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+ public static bool IsNotBrowserAndRemoteExecuteSupported => PlatformDetection.IsNotBrowser && RemoteExecutor.IsSupported;
+
+ [ConditionalFact(typeof(MetricEventSourceTests), nameof(IsNotBrowserAndRemoteExecuteSupported))]
[OuterLoop("Slow and has lots of console spew")]
public void EventSourcePublishesTimeSeriesWithEmptyMetadata()
{
- using Meter meter = new Meter("TestMeter1", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
- Counter c = meter.CreateCounter("counter1");
- int counterState = 3;
- ObservableCounter oc = meter.CreateObservableCounter("observableCounter1", () => { counterState += 7; return counterState; });
- int gaugeState = 0;
- ObservableGauge og = meter.CreateObservableGauge("observableGauge1", () => { gaugeState += 9; return gaugeState; });
- Histogram h = meter.CreateHistogram("histogram1");
- UpDownCounter udc = meter.CreateUpDownCounter("upDownCounter1");
- int upDownCounterState = 0;
- ObservableUpDownCounter oudc = meter.CreateObservableUpDownCounter("observableUpDownCounter1", () => { upDownCounterState -= 11; return upDownCounterState; });
-
- EventWrittenEventArgs[] events;
- using (MetricsEventListener listener = new MetricsEventListener(_output, MetricsEventListener.TimeSeriesValues, IntervalSecs, "TestMeter1"))
+ RemoteExecutor.Invoke(static () =>
{
- listener.WaitForCollectionStop(s_waitForEventTimeout, 1);
- c.Add(5);
- h.Record(19);
- udc.Add(-33);
- listener.WaitForCollectionStop(s_waitForEventTimeout, 2);
- c.Add(12);
- h.Record(26);
- udc.Add(-40);
- listener.WaitForCollectionStop(s_waitForEventTimeout, 3);
- events = listener.Events.ToArray();
- }
+ CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("fi-FI");
- AssertBeginInstrumentReportingEventsPresent(events, c, oc, og, h, udc, oudc);
- AssertInitialEnumerationCompleteEventPresent(events);
- AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17"));
- AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17"));
- AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18");
- AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26"));
- AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("-33", "-33"), ("-40", "-73"));
- AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "-11"), ("-11", "-22"));
- AssertCollectStartStopEventsPresent(events, IntervalSecs, 3);
+ using Meter meter = new Meter("TestMeter1", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
+ Counter c = meter.CreateCounter("counter1");
+ int counterState = 3;
+ ObservableCounter oc = meter.CreateObservableCounter("observableCounter1", () => { counterState += 7; return counterState; });
+ int gaugeState = 0;
+ ObservableGauge og = meter.CreateObservableGauge("observableGauge1", () => { gaugeState += 9; return gaugeState; });
+ Histogram h = meter.CreateHistogram("histogram1");
+ UpDownCounter udc = meter.CreateUpDownCounter("upDownCounter1");
+ int upDownCounterState = 0;
+ ObservableUpDownCounter oudc = meter.CreateObservableUpDownCounter("observableUpDownCounter1", () => { upDownCounterState -= 11; return upDownCounterState; });
+
+ EventWrittenEventArgs[] events;
+ using (MetricsEventListener listener = new MetricsEventListener(NullTestOutputHelper.Instance, MetricsEventListener.TimeSeriesValues, IntervalSecs, "TestMeter1"))
+ {
+ listener.WaitForCollectionStop(s_waitForEventTimeout, 1);
+ c.Add(5);
+ h.Record(19);
+ udc.Add(-33);
+ listener.WaitForCollectionStop(s_waitForEventTimeout, 2);
+ c.Add(12);
+ h.Record(26);
+ udc.Add(-40);
+ listener.WaitForCollectionStop(s_waitForEventTimeout, 3);
+ events = listener.Events.ToArray();
+ }
+
+ AssertBeginInstrumentReportingEventsPresent(events, c, oc, og, h, udc, oudc);
+ AssertInitialEnumerationCompleteEventPresent(events);
+ AssertCounterEventsPresent(events, meter.Name, c.Name, "", "", ("5", "5"), ("12", "17"));
+ AssertCounterEventsPresent(events, meter.Name, oc.Name, "", "", ("", "10"), ("7", "17"));
+ AssertGaugeEventsPresent(events, meter.Name, og.Name, "", "", "9", "18");
+ AssertHistogramEventsPresent(events, meter.Name, h.Name, "", "", ("0.5=19;0.95=19;0.99=19", "1", "19"), ("0.5=26;0.95=26;0.99=26", "1", "26"));
+ AssertUpDownCounterEventsPresent(events, meter.Name, udc.Name, "", "", ("-33", "-33"), ("-40", "-73"));
+ AssertUpDownCounterEventsPresent(events, meter.Name, oudc.Name, "", "", ("", "-11"), ("-11", "-22"));
+ AssertCollectStartStopEventsPresent(events, IntervalSecs, 3);
+ }).Dispose();
+ }
+
+ private sealed class NullTestOutputHelper : ITestOutputHelper
+ {
+ public static NullTestOutputHelper Instance { get; } = new();
+ public void WriteLine(string message) { }
+ public void WriteLine(string format, params object[] args) { }
}
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
@@ -1470,7 +1483,7 @@ private static string FormatTags(IEnumerable>? tag
return sb.ToString();
}
- private void AssertBeginInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments)
+ private static void AssertBeginInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments)
{
var beginReportEvents = events.Where(e => e.EventName == "BeginInstrumentReporting").Select(e =>
new
@@ -1502,7 +1515,7 @@ private void AssertBeginInstrumentReportingEventsPresent(EventWrittenEventArgs[]
Assert.Equal(expectedInstruments.Length, beginReportEvents.Length);
}
- private void AssertEndInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments)
+ private static void AssertEndInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments)
{
var beginReportEvents = events.Where(e => e.EventName == "EndInstrumentReporting").Select(e =>
new
@@ -1534,27 +1547,27 @@ private void AssertEndInstrumentReportingEventsPresent(EventWrittenEventArgs[] e
Assert.Equal(expectedInstruments.Length, beginReportEvents.Length);
}
- private void AssertInitialEnumerationCompleteEventPresent(EventWrittenEventArgs[] events, int eventsCount = 1)
+ private static void AssertInitialEnumerationCompleteEventPresent(EventWrittenEventArgs[] events, int eventsCount = 1)
{
Assert.Equal(eventsCount, events.Where(e => e.EventName == "InitialInstrumentEnumerationComplete").Count());
}
- private void AssertTimeSeriesLimitPresent(EventWrittenEventArgs[] events)
+ private static void AssertTimeSeriesLimitPresent(EventWrittenEventArgs[] events)
{
Assert.Equal(1, events.Where(e => e.EventName == "TimeSeriesLimitReached").Count());
}
- private void AssertTimeSeriesLimitNotPresent(EventWrittenEventArgs[] events)
+ private static void AssertTimeSeriesLimitNotPresent(EventWrittenEventArgs[] events)
{
Assert.Equal(0, events.Where(e => e.EventName == "TimeSeriesLimitReached").Count());
}
- private void AssertHistogramLimitPresent(EventWrittenEventArgs[] events)
+ private static void AssertHistogramLimitPresent(EventWrittenEventArgs[] events)
{
Assert.Equal(1, events.Where(e => e.EventName == "HistogramLimitReached").Count());
}
- private void AssertInstrumentPublishingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments)
+ private static void AssertInstrumentPublishingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments)
{
var publishEvents = events.Where(e => e.EventName == "InstrumentPublished").Select(e =>
new
@@ -1586,19 +1599,19 @@ private void AssertInstrumentPublishingEventsPresent(EventWrittenEventArgs[] eve
Assert.Equal(expectedInstruments.Length, publishEvents.Length);
}
- private void AssertCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
+ private static void AssertCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
string expectedUnit, params (string, string)[] expected)
{
AssertGenericCounterEventsPresent("CounterRateValuePublished", events, meterName, instrumentName, tags, expectedUnit, expected);
}
- private void AssertUpDownCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
+ private static void AssertUpDownCounterEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
string expectedUnit, params (string, string)[] expected)
{
AssertGenericCounterEventsPresent("UpDownCounterRateValuePublished", events, meterName, instrumentName, tags, expectedUnit, expected);
}
- private void AssertGenericCounterEventsPresent(string eventName, EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
+ private static void AssertGenericCounterEventsPresent(string eventName, EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
string expectedUnit, params (string, string)[] expected)
{
var counterEvents = events.Where(e => e.EventName == eventName).Select(e =>
@@ -1622,7 +1635,7 @@ private void AssertInstrumentPublishingEventsPresent(EventWrittenEventArgs[] eve
}
}
- private void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags)
+ private static void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags)
{
var counterEvents = events.Where(e => e.EventName == "CounterRateValuePublished").Select(e =>
new
@@ -1636,7 +1649,7 @@ private void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, strin
Assert.Equal(0, filteredEvents.Length);
}
- private void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
+ private static void AssertGaugeEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
string expectedUnit, params string[] expectedValues)
{
var counterEvents = events.Where(e => e.EventName == "GaugeValuePublished").Select(e =>
@@ -1658,7 +1671,7 @@ private void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, strin
}
}
- private void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
+ private static void AssertHistogramEventsPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags,
string expectedUnit, params (string, string, string)[] expected)
{
var counterEvents = events.Where(e => e.EventName == "HistogramValuePublished").Select(e =>
@@ -1684,7 +1697,7 @@ private void AssertCounterEventsNotPresent(EventWrittenEventArgs[] events, strin
}
}
- private void AssertHistogramEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags)
+ private static void AssertHistogramEventsNotPresent(EventWrittenEventArgs[] events, string meterName, string instrumentName, string tags)
{
var counterEvents = events.Where(e => e.EventName == "HistogramValuePublished").Select(e =>
new
@@ -1697,7 +1710,7 @@ private void AssertHistogramEventsNotPresent(EventWrittenEventArgs[] events, str
var filteredEvents = counterEvents.Where(e => e.MeterName == meterName && e.InstrumentName == instrumentName && e.Tags == tags).ToArray();
Assert.Equal(0, filteredEvents.Length);
}
- private void AssertCollectStartStopEventsPresent(EventWrittenEventArgs[] events, double expectedIntervalSecs, int expectedPairs)
+ private static void AssertCollectStartStopEventsPresent(EventWrittenEventArgs[] events, double expectedIntervalSecs, int expectedPairs)
{
int startEventsSeen = 0;
int stopEventsSeen = 0;
@@ -1726,7 +1739,7 @@ private void AssertCollectStartStopEventsPresent(EventWrittenEventArgs[] events,
Assert.Equal(expectedPairs, stopEventsSeen);
}
- private void AssertObservableCallbackErrorPresent(EventWrittenEventArgs[] events)
+ private static void AssertObservableCallbackErrorPresent(EventWrittenEventArgs[] events)
{
var errorEvents = events.Where(e => e.EventName == "ObservableInstrumentCallbackError").Select(e =>
new
@@ -1737,7 +1750,7 @@ private void AssertObservableCallbackErrorPresent(EventWrittenEventArgs[] events
Assert.Contains("Example user exception", errorEvents[0].ErrorText);
}
- private void AssertMultipleSessionsConfiguredIncorrectlyErrorEventsPresent(EventWrittenEventArgs[] events,
+ private static void AssertMultipleSessionsConfiguredIncorrectlyErrorEventsPresent(EventWrittenEventArgs[] events,
string expectedMaxHistograms, string actualMaxHistograms, string expectedMaxTimeSeries, string actualMaxTimeSeries,
string expectedRefreshInterval, string actualRefreshInterval)
{