<FeatureICastable>true</FeatureICastable>
<FeatureManagedEtwChannels>true</FeatureManagedEtwChannels>
<FeatureManagedEtw>true</FeatureManagedEtw>
-
+ <FeaturePerfTracing>true</FeaturePerfTracing>
<ProfilingSupportedBuild>true</ProfilingSupportedBuild>
</PropertyGroup>
<FeatureStubsAsIL>true</FeatureStubsAsIL>
<FeatureCoreFxGlobalization>true</FeatureCoreFxGlobalization>
- <FeaturePerfTracing>true</FeaturePerfTracing>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetsWindows)' == 'true'">
namespace System.Diagnostics.Tracing
#endif
{
+ internal enum EventProviderType
+ {
+ None = 0,
+ ETW,
+ EventPipe
+ };
+
// New in CLR4.0
internal enum ControllerCommand
{
// it registers a callback from native code you MUST dispose it BEFORE shutdown, otherwise
// you may get native callbacks during shutdown when we have destroyed the delegate.
// EventSource has special logic to do this, no one else should be calling EventProvider.
- internal EventProvider()
+ internal EventProvider(EventProviderType providerType)
{
+ switch (providerType)
+ {
+ case EventProviderType.ETW:
#if PLATFORM_WINDOWS
- m_eventProvider = new EtwEventProvider();
-#elif FEATURE_PERFTRACING
- m_eventProvider = new EventPipeEventProvider();
+ m_eventProvider = new EtwEventProvider();
#else
- m_eventProvider = new NoOpEventProvider();
+ m_eventProvider = new NoOpEventProvider();
#endif
+ break;
+ case EventProviderType.EventPipe:
+#if FEATURE_PERFTRACING
+ m_eventProvider = new EventPipeEventProvider();
+#else
+ m_eventProvider = new NoOpEventProvider();
+#endif
+ break;
+ default:
+ m_eventProvider = new NoOpEventProvider();
+ break;
+ };
}
/// <summary>
var structBase = (byte*)providerInstance;
providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
}
-#else
+#else
#if !ES_BUILD_PCL && PLATFORM_WINDOWS // TODO command arguments don't work on PCL builds...
// This code is only used in the Nuget Package Version of EventSource. because
// the code above is using APIs baned from UWP apps.
}
}
-#elif !FEATURE_PERFTRACING
-
+#endif
internal sealed class NoOpEventProvider : IEventProvider
{
unsafe uint IEventProvider.EventRegister(
// Define an EventPipeEvent handle.
unsafe IntPtr IEventProvider.DefineEventHandle(uint eventID, string eventName, Int64 keywords, uint eventVersion, uint level, byte *pMetadata, uint metadataLength)
{
- throw new System.NotSupportedException();
+ return IntPtr.Zero;
}
}
-
-#endif
}
throw new ArgumentException(SR.EventSource_InvalidCommand, nameof(command));
}
- eventSource.SendCommand(null, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
+ eventSource.SendCommand(null, EventProviderType.ETW, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
}
#if !ES_BUILD_STANDALONE
}
Debug.Assert(m_eventData != null);
- Debug.Assert(m_provider != null);
+ Debug.Assert(m_eventPipeProvider != null);
int cnt = m_eventData.Length;
for (int i = 0; i < cnt; i++)
{
fixed (byte *pMetadata = metadata)
{
- IntPtr eventHandle = m_provider.m_eventProvider.DefineEventHandle(
+ IntPtr eventHandle = m_eventPipeProvider.m_eventProvider.DefineEventHandle(
eventID,
eventName,
keywords,
}
#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
+ if (m_eventData[eventId].EnabledForETW || m_eventData[eventId].EnabledForEventPipe)
{
if (!SelfDescribingEvents)
{
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
+ if (!m_etwProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
ThrowEventSourceException(m_eventData[eventId].Name);
+#if FEATURE_PERFTRACING
+ if (!m_eventPipeProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+#endif // FEATURE_PERFTRACING
}
else
{
if (disposing)
{
#if FEATURE_MANAGED_ETW
-#if !FEATURE_PERFTRACING
// Send the manifest one more time to ensure circular buffers have a chance to get to this information
// even in scenarios with a high volume of ETW events.
if (m_eventSourceEnabled)
{ } // If it fails, simply give up.
m_eventSourceEnabled = false;
}
+ if (m_etwProvider != null)
+ {
+ m_etwProvider.Dispose();
+ m_etwProvider = null;
+ }
#endif
- if (m_provider != null)
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider != null)
{
- m_provider.Dispose();
- m_provider = null;
+ m_eventPipeProvider.Dispose();
+ m_eventPipeProvider = null;
}
#endif
}
IntPtr data)
{
#if FEATURE_MANAGED_ETW
- if (m_provider == null)
+ if (m_etwProvider == null)
{
ThrowEventSourceException(eventName);
}
else
{
- if (!m_provider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
+ if (!m_etwProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
ThrowEventSourceException(eventName);
}
#endif // FEATURE_MANAGED_ETW
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider == null)
+ {
+ ThrowEventSourceException(eventName);
+ }
+ else
+ {
+ if (!m_eventPipeProvider.WriteEventRaw(ref eventDescriptor, eventHandle, activityID, relatedActivityID, dataCount, data))
+ ThrowEventSourceException(eventName);
+ }
+#endif // FEATURE_PERFTRACING
}
// FrameworkEventSource is on the startup path for the framework, so we have this internal overload that it can use
//Enable Implicit Activity tracker
m_activityTracker = ActivityTracker.Instance;
-#if FEATURE_MANAGED_ETW
+#if FEATURE_MANAGED_ETW || FEATURE_PERFTRACING
// Create and register our provider traits. We do this early because it is needed to log errors
// In the self-describing event case.
this.InitializeProviderMetadata();
-
+#endif
+#if FEATURE_MANAGED_ETW
// Register the provider with ETW
- var provider = new OverideEventProvider(this);
- provider.Register(this);
+ var etwProvider = new OverideEventProvider(this, EventProviderType.ETW);
+ etwProvider.Register(this);
+#endif
+#if FEATURE_PERFTRACING
+ // Register the provider with EventPipe
+ var eventPipeProvider = new OverideEventProvider(this, EventProviderType.EventPipe);
+ eventPipeProvider.Register(this);
#endif
// Add the eventSource to the global (weak) list.
// This also sets m_id, which is the index in the list.
#if FEATURE_MANAGED_ETW
// OK if we get this far without an exception, then we can at least write out error messages.
// Set m_provider, which allows this.
- m_provider = provider;
+ m_etwProvider = etwProvider;
#if PLATFORM_WINDOWS
#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
System.Runtime.InteropServices.GCHandle.Alloc(this.providerMetadata, System.Runtime.InteropServices.GCHandleType.Pinned);
IntPtr providerMetadata = metadataHandle.AddrOfPinnedObject();
- setInformationResult = m_provider.SetInformation(
+ setInformationResult = m_etwProvider.SetInformation(
UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS.SetTraits,
providerMetadata,
(uint)this.providerMetadata.Length);
}
#endif // PLATFORM_WINDOWS
#endif // FEATURE_MANAGED_ETW
+
+#if FEATURE_PERFTRACING
+ m_eventPipeProvider = eventPipeProvider;
+#endif
Debug.Assert(!m_eventSourceEnabled); // We can't be enabled until we are completely initted.
// We are logically completely initialized at this point.
m_completelyInited = true;
}
#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
+ if (m_eventData[eventId].EnabledForETW || m_eventData[eventId].EnabledForEventPipe)
{
if (!SelfDescribingEvents)
{
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, childActivityID, args))
+ if (!m_etwProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, childActivityID, args))
ThrowEventSourceException(m_eventData[eventId].Name);
+#if FEATURE_PERFTRACING
+ if (!m_eventPipeProvider.WriteEvent(ref m_eventData[eventId].Descriptor, m_eventData[eventId].EventHandle, pActivityId, childActivityID, args))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+#endif // FEATURE_PERFTRACING
}
else
{
}
}
#endif // FEATURE_MANAGED_ETW
- if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
+ if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
{
#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
// Maintain old behavior - object identity is preserved
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
private unsafe void WriteEventString(EventLevel level, long keywords, string msgString)
{
-#if FEATURE_MANAGED_ETW && !FEATURE_PERFTRACING
- if (m_provider != null)
+#if FEATURE_MANAGED_ETW
+ if (m_etwProvider != null)
{
string eventName = "EventSourceMessage";
if (SelfDescribingEvents)
data.Ptr = (ulong)msgStringPtr;
data.Size = (uint)(2 * (msgString.Length + 1));
data.Reserved = 0;
- m_provider.WriteEvent(ref descr, IntPtr.Zero, null, null, 1, (IntPtr)((void*)&data));
+ m_etwProvider.WriteEvent(ref descr, IntPtr.Zero, null, null, 1, (IntPtr)((void*)&data));
}
}
}
/// </summary>
private class OverideEventProvider : EventProvider
{
- public OverideEventProvider(EventSource eventSource)
+ public OverideEventProvider(EventSource eventSource, EventProviderType providerType)
+ : base(providerType)
{
this.m_eventSource = eventSource;
+ this.m_eventProviderType = providerType;
}
protected override void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments,
int perEventSourceSessionId, int etwSessionId)
{
// We use null to represent the ETW EventListener.
EventListener listener = null;
- m_eventSource.SendCommand(listener, perEventSourceSessionId, etwSessionId,
+ m_eventSource.SendCommand(listener, m_eventProviderType, perEventSourceSessionId, etwSessionId,
(EventCommand)command, IsEnabled(), Level, MatchAnyKeyword, arguments);
}
private EventSource m_eventSource;
+ private EventProviderType m_eventProviderType;
}
#endif
public IntPtr EventHandle; // EventPipeEvent handle.
public EventTags Tags;
public bool EnabledForAnyListener; // true if any dispatcher has this event turned on
- public bool EnabledForETW; // is this event on for the OS ETW data dispatcher?
+ public bool EnabledForETW; // is this event on for ETW?
+ public bool EnabledForEventPipe; // is this event on for EventPipe?
public bool HasRelatedActivityID; // Set if the event method's first parameter is a Guid named 'relatedActivityId'
#pragma warning disable 0649
// * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0).
//
// dispatcher == null has special meaning. It is the 'ETW' dispatcher.
- internal void SendCommand(EventListener listener, int perEventSourceSessionId, int etwSessionId,
+ internal void SendCommand(EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId,
EventCommand command, bool enable,
EventLevel level, EventKeywords matchAnyKeyword,
IDictionary<string, string> commandArguments)
{
- var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword);
+ var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, eventProviderType, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword);
lock (EventListener.EventListenersLock)
{
if (m_completelyInited)
Debug.Assert(m_completelyInited);
#if FEATURE_MANAGED_ETW
- if (m_provider == null) // If we failed to construct
+ if (m_etwProvider == null) // If we failed to construct
return;
#endif // FEATURE_MANAGED_ETW
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider == null)
+ return;
+#endif
m_outOfBandMessageCount = 0;
bool shouldReport = (commandArgs.perEventSourceSessionId > 0) && (commandArgs.perEventSourceSessionId <= SessionMask.MAX);
{
// Set it up using the 'standard' filtering bitfields (use the "global" enable, not session specific one)
for (int i = 0; i < m_eventData.Length; i++)
- EnableEventForDispatcher(commandArgs.dispatcher, i, IsEnabledByDefault(i, commandArgs.enable, commandArgs.level, commandArgs.matchAnyKeyword));
+ EnableEventForDispatcher(commandArgs.dispatcher, commandArgs.eventProviderType, i, IsEnabledByDefault(i, commandArgs.enable, commandArgs.level, commandArgs.matchAnyKeyword));
if (commandArgs.enable)
{
{
// eventSourceDispatcher == null means this is the ETW manifest
-#if !FEATURE_PERFTRACING
// Note that we unconditionally send the manifest whenever we are enabled, even if
// we were already enabled. This is because there may be multiple sessions active
// and we can't know that all the sessions have seen the manifest.
if (!SelfDescribingEvents)
SendManifest(m_rawManifest);
-#endif
}
// Turn on the enable bit before making the OnEventCommand callback This allows you to do useful
/// of 'eventId. If value is 'false' disable the event for that dispatcher. If 'eventId' is out of
/// range return false, otherwise true.
/// </summary>
- internal bool EnableEventForDispatcher(EventDispatcher dispatcher, int eventId, bool value)
+ internal bool EnableEventForDispatcher(EventDispatcher dispatcher, EventProviderType eventProviderType, int eventId, bool value)
{
if (dispatcher == null)
{
if (eventId >= m_eventData.Length)
return false;
#if FEATURE_MANAGED_ETW
- if (m_provider != null)
+ if (m_etwProvider != null && eventProviderType == EventProviderType.ETW)
m_eventData[eventId].EnabledForETW = value;
#endif
+#if FEATURE_PERFTRACING
+ if (m_eventPipeProvider != null && eventProviderType == EventProviderType.EventPipe)
+ m_eventData[eventId].EnabledForEventPipe = value;
+#endif
}
else
{
private bool AnyEventEnabled()
{
for (int i = 0; i < m_eventData.Length; i++)
- if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForAnyListener)
+ if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForEventPipe || m_eventData[i].EnabledForAnyListener)
return true;
return false;
}
while (dataLeft > 0)
{
dataDescrs[1].Size = (uint)Math.Min(dataLeft, chunkSize);
- if (m_provider != null)
+ if (m_etwProvider != null)
{
- if (!m_provider.WriteEvent(ref manifestDescr, IntPtr.Zero, null, null, 2, (IntPtr)dataDescrs))
+ if (!m_etwProvider.WriteEvent(ref manifestDescr, IntPtr.Zero, null, null, 2, (IntPtr)dataDescrs))
{
// Turns out that if users set the BufferSize to something less than 64K then WriteEvent
// can fail. If we get this failure on the first chunk try again with something smaller
// Dispatching state
internal volatile EventDispatcher m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially)
#if FEATURE_MANAGED_ETW
- private volatile OverideEventProvider m_provider; // This hooks up ETW commands to our 'OnEventCommand' callback
+ private volatile OverideEventProvider m_etwProvider; // This hooks up ETW commands to our 'OnEventCommand' callback
+#endif
+#if FEATURE_PERFTRACING
+ private volatile OverideEventProvider m_eventPipeProvider;
#endif
private bool m_completelyInited; // The EventSource constructor has returned without exception.
private Exception m_constructionException; // If there was an exception construction, this is it
throw new ArgumentNullException(nameof(eventSource));
}
- eventSource.SendCommand(this, 0, 0, EventCommand.Update, true, level, matchAnyKeyword, arguments);
+ eventSource.SendCommand(this, EventProviderType.None, 0, 0, EventCommand.Update, true, level, matchAnyKeyword, arguments);
}
/// <summary>
/// Disables all events coming from eventSource identified by 'eventSource'.
throw new ArgumentNullException(nameof(eventSource));
}
- eventSource.SendCommand(this, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null);
+ eventSource.SendCommand(this, EventProviderType.None, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null);
}
/// <summary>
{
if (Command != EventCommand.Enable && Command != EventCommand.Disable)
throw new InvalidOperationException();
- return eventSource.EnableEventForDispatcher(dispatcher, eventId, true);
+ return eventSource.EnableEventForDispatcher(dispatcher, eventProviderType, eventId, true);
}
/// <summary>
{
if (Command != EventCommand.Enable && Command != EventCommand.Disable)
throw new InvalidOperationException();
- return eventSource.EnableEventForDispatcher(dispatcher, eventId, false);
+ return eventSource.EnableEventForDispatcher(dispatcher, eventProviderType, eventId, false);
}
#region private
internal EventCommandEventArgs(EventCommand command, IDictionary<string, string> arguments, EventSource eventSource,
- EventListener listener, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
+ EventListener listener, EventProviderType eventProviderType, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
{
this.Command = command;
this.Arguments = arguments;
this.eventSource = eventSource;
this.listener = listener;
+ this.eventProviderType = eventProviderType;
this.perEventSourceSessionId = perEventSourceSessionId;
this.etwSessionId = etwSessionId;
this.enable = enable;
internal EventSource eventSource;
internal EventDispatcher dispatcher;
+ internal EventProviderType eventProviderType;
// These are the arguments of sendCommand and are only used for deferring commands until after we are fully initialized.
internal EventListener listener;
EventDescriptor descriptor = new EventDescriptor(identity, level, opcode, (long)keywords);
#if FEATURE_PERFTRACING
- IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes);
+ IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
Debug.Assert(eventHandle != IntPtr.Zero);
#else
IntPtr eventHandle = IntPtr.Zero;
}
#if FEATURE_PERFTRACING
- IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes);
+ IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
Debug.Assert(eventHandle != IntPtr.Zero);
#else
IntPtr eventHandle = IntPtr.Zero;
}
#if FEATURE_PERFTRACING
- IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_provider, m_eventHandleMap, descriptor, eventTypes);
+ IntPtr eventHandle = nameInfo.GetOrCreateEventHandle(m_eventPipeProvider, m_eventHandleMap, descriptor, eventTypes);
Debug.Assert(eventHandle != IntPtr.Zero);
#else
IntPtr eventHandle = IntPtr.Zero;
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
- PRECONDITION(s_pSession != NULL);
}
CONTRACTL_END;
// We can't procede without a configuration
return;
}
+ _ASSERTE(s_pSession != NULL);
// If the activity id isn't specified, pull it from the current thread.
if(pActivityId == NULL)
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(pSession != NULL);
// Lock must be held by EventPipe::Enable.
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
// TODO: Multiple session support will require that the session be specified.
PRECONDITION(pSession != NULL);
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(pSession != NULL);
// Lock must be held by EventPipe::Disable.
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
}
CONTRACTL
{
THROWS;
- GC_NOTRIGGER;
+ GC_TRIGGERS;
MODE_ANY;
PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
}
<ExcludeList Include="$(XunitTestBinBase)\managed\Compilation\Compilation\Compilation.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
- </ItemGroup>
-
- <!-- The following are tests that fail on Windows -->
-
- <ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(TargetsWindows)' == 'true'">
- <ExcludeList Include="$(XunitTestBinBase)\tracing\eventsourcetrace\eventsourcetrace\eventsourcetrace.cmd">
- <Issue>15494</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\tracing\tracevalidation\tracelogging\tracelogging\tracelogging.cmd">
- <Issue>15494</Issue>
+ <ExcludeList Include="$(XunitTestBinBase)\tracing\eventsource\eventpipeandetw\eventpipeandetw\eventpipeandetw.cmd">
+ <Issue>by design Windows only</Issue>
</ExcludeList>
</ItemGroup>
--- /dev/null
+using System;
+using System.IO;
+
+namespace Tracing.Tests.Common
+{
+ public class EtlFile : IDisposable
+ {
+ public string Path { get; }
+ private bool KeepOutput { get; }
+
+ private EtlFile(string fileName, bool keep)
+ {
+ Path = fileName;
+ KeepOutput = keep;
+ }
+
+ public void Dispose()
+ {
+ if (KeepOutput)
+ Console.WriteLine("\n\tOutput file: {0}", Path);
+ else
+ File.Delete(Path);
+ }
+
+ public static EtlFile Create(string[] args)
+ {
+ if (args.Length >= 1)
+ return new EtlFile(args[0], true);
+
+ return new EtlFile(System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".etl", false);
+ }
+ }
+}
</ItemGroup>
<ItemGroup>
<Compile Include="Assert.cs" />
+ <Compile Include="EtlFile.cs" />
<Compile Include="NetPerfFile.cs" />
<Compile Include="TraceControl.cs" />
<Compile Include="TraceConfiguration.cs" />
--- /dev/null
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Threading;
+using Tracing.Tests.Common;
+using System.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing.Etlx;
+using Microsoft.Diagnostics.Tracing.Parsers;
+using Microsoft.Diagnostics.Tracing.Parsers.Clr;
+using Microsoft.Diagnostics.Tracing.Session;
+
+namespace Tracing.Tests
+{
+ [EventSource(Name = "EventPipeAndEtwEventSource")]
+ class EventPipeAndEtwEventSource : EventSource
+ {
+ public class Keywords
+ {
+ public const EventKeywords EventPipeKeyword = (EventKeywords)0x1;
+ public const EventKeywords EtwKeyword = (EventKeywords)0x2;
+ }
+
+ public static EventPipeAndEtwEventSource Log = new EventPipeAndEtwEventSource();
+
+ private EventPipeAndEtwEventSource() : base(true) { }
+
+ [Event(1, Keywords = Keywords.EventPipeKeyword)]
+ public void Event1()
+ {
+ WriteEvent(1);
+ }
+
+ [Event(2, Keywords = Keywords.EtwKeyword)]
+ public void Event2()
+ {
+ WriteEvent(2);
+ }
+
+ [Event(3, Keywords = Keywords.EventPipeKeyword | Keywords.EtwKeyword)]
+ public void Event3()
+ {
+ WriteEvent(3);
+ }
+ }
+
+ class EventResults
+ {
+ public int Event1Count { get; private set; }
+ public int Event2Count { get; private set; }
+ public int Event3Count { get; private set; }
+
+ public void AddEvent(TraceEvent data)
+ {
+ if (data.ProviderName == EventPipeAndEtwEventSource.Log.Name)
+ {
+ if (data.EventName == "ManifestData")
+ {
+ return;
+ }
+
+ if (data.EventName == "Event1")
+ {
+ Event1Count++;
+ }
+ else if (data.EventName == "Event2")
+ {
+ Event2Count++;
+ }
+ else if (data.EventName == "Event3")
+ {
+ Event3Count++;
+ }
+ else
+ {
+ Console.WriteLine($"\tEncountered unexpected event with name '{data.EventName}'.");
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public void Print(string header)
+ {
+ Console.WriteLine("\n\t" + header);
+ Console.WriteLine($"\t\tEvent1Count: {Event1Count}");
+ Console.WriteLine($"\t\tEvent2Count: {Event2Count}");
+ Console.WriteLine($"\t\tEvent3Count: {Event3Count}\n\n");
+ }
+ }
+
+ class EventPipeAndEtw
+ {
+ private static TraceConfiguration EventPipeGetConfig(EventSource eventSource, EventKeywords keywords, string outputFile="default.netperf")
+ {
+ // Setup the configuration values.
+ uint circularBufferMB = 1024; // 1 GB
+ uint level = 5;
+
+ // Create a new instance of EventPipeConfiguration.
+ TraceConfiguration config = new TraceConfiguration(outputFile, circularBufferMB);
+
+ // Enable the provider.
+ config.EnableProvider(eventSource.Name, (ulong)keywords, level);
+
+ return config;
+ }
+
+ private static TraceEventSession EnableETW(EventSource eventSource, EventKeywords keywords, string outputFile="default.etl")
+ {
+ outputFile = Path.GetFullPath(outputFile);
+ TraceEventSession session = new TraceEventSession("EventSourceEventPipeSession", outputFile);
+ session.EnableProvider(eventSource.Name, TraceEventLevel.Verbose, (ulong)keywords, null);
+ Thread.Sleep(200); // Calls are async.
+ return session;
+ }
+
+ private static void DisableETW(TraceEventSession traceEventSession)
+ {
+ traceEventSession.Flush();
+ Thread.Sleep(1010); // Calls are async.
+ traceEventSession.Dispose();
+ }
+
+ private static void WriteAllEvents(EventPipeAndEtwEventSource eventSource)
+ {
+ Console.WriteLine("\tStart: Write events.");
+ eventSource.Event1();
+ eventSource.Event2();
+ eventSource.Event3();
+ Console.WriteLine("\tEnd: Writing events.\n");
+ }
+
+ private static void RoundOne(string[] args)
+ {
+ using (var netPerfFile = NetPerfFile.Create(args))
+ {
+ using (var etlFile = EtlFile.Create(args))
+ {
+ Console.WriteLine("\tStart: Enable EventPipe.");
+ TraceControl.Enable(EventPipeGetConfig(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EventPipeKeyword, netPerfFile.Path));
+ Console.WriteLine("\tEnd: Enable EventPipe.\n");
+
+ Console.WriteLine("\tStart: Enable ETW.");
+ TraceEventSession etwSession = EnableETW(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EtwKeyword, etlFile.Path);
+ Console.WriteLine("\tEnd: Enable ETW.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable ETW.");
+ DisableETW(etwSession);
+ Console.WriteLine("\tEnd: Disable ETW.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable EventPipe.");
+ TraceControl.Disable();
+ Console.WriteLine("\tEnd: Disable EventPipe.\n");
+
+ Console.WriteLine("\tStart: Processing events from EventPipe file.");
+
+ EventResults eventPipeResults = new EventResults();
+ EventResults etwResults = new EventResults();
+
+ using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ eventPipeResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate EventPipe results.
+ eventPipeResults.Print("EventPipe Results:");
+ Assert.Equal("EventPipeEvent1Count", eventPipeResults.Event1Count, 2);
+ Assert.Equal("EventPipeEvent2Count", eventPipeResults.Event2Count, 0);
+ Assert.Equal("EventPipeEvent3Count", eventPipeResults.Event3Count, 2);
+
+ Console.WriteLine("\tEnd: Processing events from EventPipe file.\n");
+
+ Console.WriteLine("\tStart: Processing events from ETW file.");
+
+ using (var trace = new ETWTraceEventSource(etlFile.Path))
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ etwResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate ETW results.
+ etwResults.Print("ETW Results:");
+ Assert.Equal("EventPipeEvent1Count", etwResults.Event1Count, 0);
+ Assert.Equal("EventPipeEvent2Count", etwResults.Event2Count, 1);
+ Assert.Equal("EventPipeEvent3Count", etwResults.Event3Count, 1);
+
+ Console.WriteLine("\tEnd: Processing events from ETW file.");
+ }
+ }
+ }
+
+ private static void RoundTwo(string[] args)
+ {
+ using (var netPerfFile = NetPerfFile.Create(args))
+ {
+ using (var etlFile = EtlFile.Create(args))
+ {
+ Console.WriteLine("\tStart: Enable EventPipe.");
+ TraceControl.Enable(EventPipeGetConfig(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EventPipeKeyword, netPerfFile.Path));
+ Console.WriteLine("\tEnd: Enable EventPipe.\n");
+
+ Console.WriteLine("\tStart: Enable ETW.");
+ TraceEventSession etwSession = EnableETW(EventPipeAndEtwEventSource.Log, EventPipeAndEtwEventSource.Keywords.EtwKeyword, etlFile.Path);
+ Console.WriteLine("\tEnd: Enable ETW.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable EventPipe.");
+ TraceControl.Disable();
+ Console.WriteLine("\tEnd: Disable EventPipe.\n");
+
+ WriteAllEvents(EventPipeAndEtwEventSource.Log);
+
+ Console.WriteLine("\tStart: Disable ETW.");
+ DisableETW(etwSession);
+ Console.WriteLine("\tEnd: Disable ETW.\n");
+
+ Console.WriteLine("\tStart: Processing events from EventPipe file.");
+
+ EventResults eventPipeResults = new EventResults();
+ EventResults etwResults = new EventResults();
+
+ using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ eventPipeResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate EventPipe results.
+ eventPipeResults.Print("EventPipe Results:");
+ Assert.Equal("EventPipeEvent1Count", eventPipeResults.Event1Count, 1);
+ Assert.Equal("EventPipeEvent2Count", eventPipeResults.Event2Count, 0);
+ Assert.Equal("EventPipeEvent3Count", eventPipeResults.Event3Count, 1);
+
+ Console.WriteLine("\tEnd: Processing events from EventPipe file.\n");
+
+ Console.WriteLine("\tStart: Processing events from ETW file.");
+
+ using (var trace = new ETWTraceEventSource(etlFile.Path))
+ {
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ etwResults.AddEvent(data);
+ };
+
+ trace.Process();
+ }
+
+ // Validate ETW results.
+ etwResults.Print("ETW Results:");
+ Assert.Equal("EventPipeEvent1Count", etwResults.Event1Count, 0);
+ Assert.Equal("EventPipeEvent2Count", etwResults.Event2Count, 2);
+ Assert.Equal("EventPipeEvent3Count", etwResults.Event3Count, 2);
+
+ Console.WriteLine("\tEnd: Processing events from ETW file.");
+ }
+ }
+ }
+
+ static int Main(string[] args)
+ {
+ // This test can only run with elevation.
+ if (TraceEventSession.IsElevated() != true)
+ {
+ Console.WriteLine("Test skipped because the shell is not elevated.");
+ return 100;
+ }
+
+ RoundOne(args);
+ RoundTwo(args);
+
+
+ return 100;
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{8E3244CB-407F-4142-BAAB-E7A55901A5FA}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"></PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"></PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="EventPipeAndEtw.cs" />
+ <ProjectReference Include="../../common/common.csproj" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
\ No newline at end of file
--- /dev/null
+using System;
+using System.IO;
+using System.Collections.Generic;
+using Tracing.Tests.Common;
+using System.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing;
+using Microsoft.Diagnostics.Tracing.Etlx;
+using Microsoft.Diagnostics.Tracing.Parsers;
+using Microsoft.Diagnostics.Tracing.Parsers.Clr;
+
+namespace Tracing.Tests
+{
+ [EventSource(Name = "SimpleEventSource")]
+ class SimpleEventSource : EventSource
+ {
+ public SimpleEventSource() : base(true) { }
+
+ [Event(1)]
+ internal void MathResult(int x, int y, int z, string formula) { this.WriteEvent(1, x, y, z, formula); }
+ }
+
+ class EventSourceTrace
+ {
+ private static int messageIterations = 10000;
+
+ public static TraceConfiguration GetConfig(EventSource eventSource, string outputFile="default.netperf")
+ {
+ // Setup the configuration values.
+ uint circularBufferMB = 1024; // 1 GB
+ uint level = 5;//(uint)EventLevel.Informational;
+ TimeSpan profSampleDelay = TimeSpan.FromMilliseconds(1);
+
+ // Create a new instance of EventPipeConfiguration.
+ TraceConfiguration config = new TraceConfiguration(outputFile, circularBufferMB);
+ // Setup the provider values.
+ // Public provider.
+ string providerName = eventSource.Name;
+ UInt64 keywords = 0xffffffffffffffff;
+
+ // Enable the provider.
+ config.EnableProvider(providerName, keywords, level);
+
+ // Set the sampling rate.
+ config.SetSamplingRate(profSampleDelay);
+
+ return config;
+ }
+
+ static int Main(string[] args)
+ {
+ bool pass = true;
+
+ using (SimpleEventSource eventSource = new SimpleEventSource())
+ {
+ using (var netPerfFile = NetPerfFile.Create(args))
+ {
+ Console.WriteLine("\tStart: Enable tracing.");
+ TraceControl.Enable(GetConfig(eventSource, netPerfFile.Path));
+ Console.WriteLine("\tEnd: Enable tracing.\n");
+
+ Console.WriteLine("\tStart: Messaging.");
+ // Send messages
+ // Use random numbers and addition as a simple, human readble checksum
+ Random generator = new Random();
+ for (int i = 0; i < messageIterations; i++)
+ {
+ int x = generator.Next(1, 1000);
+ int y = generator.Next(1, 1000);
+ string formula = String.Format("{0} + {1} = {2}", x, y, x + y);
+
+ eventSource.MathResult(x, y, x + y, formula);
+ }
+ Console.WriteLine("\tEnd: Messaging.\n");
+
+ Console.WriteLine("\tStart: Disable tracing.");
+ TraceControl.Disable();
+ Console.WriteLine("\tEnd: Disable tracing.\n");
+
+ Console.WriteLine("\tStart: Processing events from file.");
+ int msgCount = 0;
+ using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
+ {
+ var names = new HashSet<string>();
+
+ trace.Dynamic.All += delegate (TraceEvent data)
+ {
+ if (!names.Contains(data.ProviderName))
+ {
+ Console.WriteLine("\t{0}", data.ProviderName);
+ names.Add(data.ProviderName);
+ }
+
+ if (data.ProviderName == "SimpleEventSource")
+ {
+ msgCount += 1;
+ }
+ };
+
+ trace.Process();
+ }
+ Console.WriteLine("\tEnd: Processing events from file.\n");
+
+ Console.WriteLine("\tProcessed {0} events from EventSource", msgCount);
+
+ pass &= msgCount == messageIterations;
+ }
+ }
+
+ return pass ? 100 : 0;
+ }
+ }
+}
</ItemGroup>
<ItemGroup>
<Compile Include="EventSourceTrace.cs" />
- <ProjectReference Include="../common/common.csproj" />
+ <ProjectReference Include="../../common/common.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
\ No newline at end of file
+++ /dev/null
-using System;
-using System.IO;
-using System.Collections.Generic;
-using Tracing.Tests.Common;
-using System.Diagnostics.Tracing;
-using Microsoft.Diagnostics.Tracing;
-using Microsoft.Diagnostics.Tracing.Etlx;
-using Microsoft.Diagnostics.Tracing.Parsers;
-using Microsoft.Diagnostics.Tracing.Parsers.Clr;
-
-namespace Tracing.Tests
-{
- [EventSource(Name = "SimpleEventSource")]
- class SimpleEventSource : EventSource
- {
- public SimpleEventSource() : base(true) { }
-
- [Event(1)]
- internal void MathResult(int x, int y, int z, string formula) { this.WriteEvent(1, x, y, z, formula); }
- }
-
- class EventSourceTrace
- {
- private static int messageIterations = 10000;
-
- public static TraceConfiguration GetConfig(EventSource eventSource, string outputFile="default.netperf")
- {
- // Setup the configuration values.
- uint circularBufferMB = 1024; // 1 GB
- uint level = 5;//(uint)EventLevel.Informational;
- TimeSpan profSampleDelay = TimeSpan.FromMilliseconds(1);
-
- // Create a new instance of EventPipeConfiguration.
- TraceConfiguration config = new TraceConfiguration(outputFile, circularBufferMB);
- // Setup the provider values.
- // Public provider.
- string providerName = eventSource.Name;
- UInt64 keywords = 0xffffffffffffffff;
-
- // Enable the provider.
- config.EnableProvider(providerName, keywords, level);
-
- // Set the sampling rate.
- config.SetSamplingRate(profSampleDelay);
-
- return config;
- }
-
- static int Main(string[] args)
- {
- bool pass = true;
-
- SimpleEventSource eventSource = new SimpleEventSource();
-
- using (var netPerfFile = NetPerfFile.Create(args))
- {
- Console.WriteLine("\tStart: Enable tracing.");
- TraceControl.Enable(GetConfig(eventSource, netPerfFile.Path));
- Console.WriteLine("\tEnd: Enable tracing.\n");
-
- Console.WriteLine("\tStart: Messaging.");
- // Send messages
- // Use random numbers and addition as a simple, human readble checksum
- Random generator = new Random();
- for(int i=0; i<messageIterations; i++)
- {
- int x = generator.Next(1,1000);
- int y = generator.Next(1,1000);
- string formula = String.Format("{0} + {1} = {2}", x, y, x+y);
-
- eventSource.MathResult(x, y, x+y, formula);
- }
- Console.WriteLine("\tEnd: Messaging.\n");
-
- Console.WriteLine("\tStart: Disable tracing.");
- TraceControl.Disable();
- Console.WriteLine("\tEnd: Disable tracing.\n");
-
- Console.WriteLine("\tStart: Processing events from file.");
- int msgCount = 0;
- using (var trace = new TraceLog(TraceLog.CreateFromEventPipeDataFile(netPerfFile.Path)).Events.GetSource())
- {
- var names = new HashSet<string>();
-
- trace.Dynamic.All += delegate(TraceEvent data)
- {
- if (!names.Contains(data.ProviderName))
- {
- Console.WriteLine("\t{0}", data.ProviderName);
- names.Add(data.ProviderName);
- }
-
- if (data.ProviderName == "SimpleEventSource")
- {
- msgCount += 1;
- }
- };
-
- trace.Process();
- }
- Console.WriteLine("\tEnd: Processing events from file.\n");
-
- Console.WriteLine("\tProcessed {0} events from EventSource", msgCount);
-
- pass &= msgCount == messageIterations;
- }
-
- return pass ? 100 : 0;
- }
- }
-}
managed/Compilation/Compilation/Compilation.sh
Regressions/coreclr/0584/Test584/Test584.sh
Interop/SizeConst/SizeConstTest/SizeConstTest.sh
+tracing/eventsource/eventpipeandetw/eventpipeandetw/eventpipeandetw.sh