summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung Yoon Whang <suwhang@microsoft.com>2019-02-19 21:40:12 -0800
committerGitHub <noreply@github.com>2019-02-19 21:40:12 -0800
commit7322038ab453067787c9d8ea2ac9047c76c434ff (patch)
treee9e11da7efb991ab241c6502a00cc29083c49ba4
parenta054254d2448314f1d24ef319b18dfd7a91747f6 (diff)
downloadcoreclr-7322038ab453067787c9d8ea2ac9047c76c434ff.tar.gz
coreclr-7322038ab453067787c9d8ea2ac9047c76c434ff.tar.bz2
coreclr-7322038ab453067787c9d8ea2ac9047c76c434ff.zip
Add ManagedRuntimeEventSource (#22515)
* Adding a dummy ManagedRuntimeEventSource * Add ManagedRuntimeEventSource * Renaming ManagedRuntimeEventSource to RuntimeEventSource * some cleanup * use Condition instead of ifdefing out the whole file * some cleanups * remove unused namespaces * Move m_RuntimeEventSource to RuntimeEventSource from EventPipeController * Adding some TODO items * address more pr comments * Use GUID to initialize RuntimeEventSource * Exclude BasicEventSourceTests from CoreFX test CI leg * Addressing rest of the PR feedback * dont dispose counters on disable command to avoid races
-rw-r--r--src/System.Private.CoreLib/System.Private.CoreLib.csproj1
-rw-r--r--src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs1
-rw-r--r--src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs114
-rw-r--r--tests/CoreFX/CoreFX.issues.json60
4 files changed, 176 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/System.Private.CoreLib.csproj
index faa24c12a5..5930aa0334 100644
--- a/src/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -131,6 +131,7 @@
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipeEventProvider.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipeMetadataGenerator.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventPipePayloadDecoder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\RuntimeEventSource.cs" Condition="'$(FeaturePerfTracing)' == 'true'"/>
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSource_CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingEventHandleTable.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\ICustomDebuggerNotification.cs" />
diff --git a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
index 21a9b925a6..c03ba4f745 100644
--- a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
+++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
@@ -90,6 +90,7 @@ namespace System.Diagnostics.Tracing
s_controllerInstance = new EventPipeController();
}
// If enable is explicitly set to 0, then don't start the controller (to avoid overhead).
+ RuntimeEventSource.Initialize();
}
}
catch { }
diff --git a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs
new file mode 100644
index 0000000000..168a6e37bc
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/RuntimeEventSource.cs
@@ -0,0 +1,114 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Threading;
+
+
+namespace System.Diagnostics.Tracing
+{
+ /// <summary>
+ /// RuntimeEventSource is an EventSource that represents events emitted by the managed runtime.
+ /// </summary>
+ [EventSource(Guid="49592C0F-5A05-516D-AA4B-A64E02026C89", Name = "System.Runtime")]
+ internal sealed class RuntimeEventSource : EventSource
+ {
+ private static RuntimeEventSource s_RuntimeEventSource;
+ private EventCounter[] _counters;
+
+ private enum Counter {
+ GCHeapSize,
+ Gen0GCCount,
+ Gen1GCCount,
+ Gen2GCCount
+ }
+
+ private Timer _timer;
+
+ private const int EnabledPollingIntervalMilliseconds = 1000; // 1 second
+
+ public static void Initialize()
+ {
+ s_RuntimeEventSource = new RuntimeEventSource();
+ }
+
+ private RuntimeEventSource(): base(new Guid(0x49592C0F, 0x5A05, 0x516D, 0xAA, 0x4B, 0xA6, 0x4E, 0x02, 0x02, 0x6C, 0x89), "System.Runtime", EventSourceSettings.EtwSelfDescribingEventFormat)
+ {
+
+ }
+
+ protected override void OnEventCommand(System.Diagnostics.Tracing.EventCommandEventArgs command)
+ {
+ if (command.Command == EventCommand.Enable)
+ {
+ if (_counters == null)
+ {
+ // NOTE: These counters will NOT be disposed on disable command because we may be introducing
+ // a race condition by doing that. We still want to create these lazily so that we aren't adding
+ // overhead by at all times even when counters aren't enabled.
+ _counters = new EventCounter[] {
+ // TODO: process info counters
+
+ // GC info counters
+ new EventCounter("Total Memory by GC", this),
+ new EventCounter("Gen 0 GC Count", this),
+ new EventCounter("Gen 1 GC Count", this),
+ new EventCounter("Gen 2 GC Count", this),
+
+ // TODO: Exception counter
+ };
+ }
+
+
+ // Initialize the timer, but don't set it to run.
+ // The timer will be set to run each time PollForTracingCommand is called.
+
+ // TODO: We should not need this timer once we are done settling upon a high-level design for
+ // what EventCounter is capable of doing. Once that decision is made, we should be able to
+ // get rid of this.
+ if (_timer == null)
+ {
+ _timer = new Timer(
+ callback: new TimerCallback(PollForCounterUpdate),
+ state: null,
+ dueTime: Timeout.Infinite,
+ period: Timeout.Infinite,
+ flowExecutionContext: false);
+ }
+ // Trigger the first poll operation on when this EventSource is enabled
+ PollForCounterUpdate(null);
+ }
+ else if (command.Command == EventCommand.Disable)
+ {
+ _timer.Change(Timeout.Infinite, Timeout.Infinite); // disable the timer from running until System.Runtime is re-enabled
+ }
+ }
+
+ public void UpdateAllCounters()
+ {
+ // GC counters
+ _counters[(int)Counter.GCHeapSize].WriteMetric(GC.GetTotalMemory(false));
+ _counters[(int)Counter.Gen0GCCount].WriteMetric(GC.CollectionCount(0));
+ _counters[(int)Counter.Gen1GCCount].WriteMetric(GC.CollectionCount(1));
+ _counters[(int)Counter.Gen2GCCount].WriteMetric(GC.CollectionCount(2));
+ }
+
+ private void PollForCounterUpdate(object state)
+ {
+ // TODO: Need to confirm with vancem about how to do error-handling here.
+ // This disables to timer from getting rescheduled to run, which may or may not be
+ // what we eventually want.
+
+ // Make sure that any transient errors don't cause the listener thread to exit.
+ try
+ {
+ UpdateAllCounters();
+
+ // Schedule the timer to run again.
+ _timer.Change(EnabledPollingIntervalMilliseconds, Timeout.Infinite);
+ }
+ catch { }
+ }
+ }
+}
diff --git a/tests/CoreFX/CoreFX.issues.json b/tests/CoreFX/CoreFX.issues.json
index ef0f725b70..d16c88b67b 100644
--- a/tests/CoreFX/CoreFX.issues.json
+++ b/tests/CoreFX/CoreFX.issues.json
@@ -158,6 +158,66 @@
{
"name": "BasicEventSourceTests.TestsUserErrors.Test_BadEventSource_MismatchedIds",
"reason": "Assert.Equal() Failure Expected: 1 Actual: 2"
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWrite.Test_Write_T_EventListener",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWrite.Test_Write_T_EventListener_UseEvents",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsUserErrors.Test_BadEventSource_MismatchedIds_WithEtwListener",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.FuzzyTests.Test_Write_Fuzzy",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWriteEventToListener.Test_WriteEvent_InvalidCalls",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWriteEventToListener.Test_WriteEvent_ZeroKwds",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWriteEventToListener.Test_EventSourceCreatedEvents_BeforeListener",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWriteEventToListener.Test_WriteEvent_ToChannel_Coverage",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWriteEventToListener.Test_WriteEvent_ArgsCornerCases",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWriteEventToListener.Test_EventSourceCreatedEvents_AfterListener",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsWriteEventToListener.Test_WriteEvent_ArgsBasicTypes",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsEventSourceLifetime.Test_EventSource_Lifetime",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsManifestNegative.Test_GenerateManifest_InvalidEventSources",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsTraits.Test_EventSource_Traits_Dynamic",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
+ },
+ {
+ "name": "BasicEventSourceTests.TestsTraits.Test_EventSource_Traits_Contract",
+ "reason": "Assert.Equal() Failure Expected: Actual: System.Runtime "
}
]
}