1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 using System.Collections.Generic;
5 using System.Runtime.CompilerServices;
6 using System.Runtime.InteropServices;
10 namespace System.Diagnostics.Tracing
12 [StructLayout(LayoutKind.Sequential)]
13 internal struct EventPipeProviderConfiguration
15 [MarshalAs(UnmanagedType.LPWStr)]
16 private string m_providerName;
17 private ulong m_keywords;
18 private uint m_loggingLevel;
20 internal EventPipeProviderConfiguration(
25 if(string.IsNullOrEmpty(providerName))
27 throw new ArgumentNullException(nameof(providerName));
29 if(loggingLevel > 5) // 5 == Verbose, the highest value in EventPipeLoggingLevel.
31 throw new ArgumentOutOfRangeException(nameof(loggingLevel));
33 m_providerName = providerName;
34 m_keywords = keywords;
35 m_loggingLevel = loggingLevel;
38 internal string ProviderName
40 get { return m_providerName; }
43 internal ulong Keywords
45 get { return m_keywords; }
48 internal uint LoggingLevel
50 get { return m_loggingLevel; }
54 internal sealed class EventPipeConfiguration
56 private string m_outputFile;
57 private uint m_circularBufferSizeInMB;
58 private List<EventPipeProviderConfiguration> m_providers;
59 private TimeSpan m_minTimeBetweenSamples = TimeSpan.FromMilliseconds(1);
61 internal EventPipeConfiguration(
63 uint circularBufferSizeInMB)
65 if(string.IsNullOrEmpty(outputFile))
67 throw new ArgumentNullException(nameof(outputFile));
69 if(circularBufferSizeInMB == 0)
71 throw new ArgumentOutOfRangeException(nameof(circularBufferSizeInMB));
73 m_outputFile = outputFile;
74 m_circularBufferSizeInMB = circularBufferSizeInMB;
75 m_providers = new List<EventPipeProviderConfiguration>();
78 internal string OutputFile
80 get { return m_outputFile; }
83 internal uint CircularBufferSizeInMB
85 get { return m_circularBufferSizeInMB; }
88 internal EventPipeProviderConfiguration[] Providers
90 get { return m_providers.ToArray(); }
93 internal long ProfilerSamplingRateInNanoseconds
95 // 100 nanoseconds == 1 tick.
96 get { return m_minTimeBetweenSamples.Ticks * 100; }
99 internal void EnableProvider(string providerName, ulong keywords, uint loggingLevel)
101 m_providers.Add(new EventPipeProviderConfiguration(
107 internal void SetProfilerSamplingRate(TimeSpan minTimeBetweenSamples)
109 if(minTimeBetweenSamples.Ticks <= 0)
111 throw new ArgumentOutOfRangeException(nameof(minTimeBetweenSamples));
114 m_minTimeBetweenSamples = minTimeBetweenSamples;
118 internal static class EventPipe
120 internal static void Enable(EventPipeConfiguration configuration)
122 if(configuration == null)
124 throw new ArgumentNullException(nameof(configuration));
127 if(configuration.Providers == null)
129 throw new ArgumentNullException(nameof(configuration.Providers));
132 EventPipeProviderConfiguration[] providers = configuration.Providers;
134 EventPipeInternal.Enable(
135 configuration.OutputFile,
136 configuration.CircularBufferSizeInMB,
137 configuration.ProfilerSamplingRateInNanoseconds,
142 internal static void Disable()
144 EventPipeInternal.Disable();
148 internal static class EventPipeInternal
151 // These PInvokes are used by the configuration APIs to interact with EventPipe.
153 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
154 internal static extern void Enable(string outputFile, uint circularBufferSizeInMB, long profilerSamplingRateInNanoseconds, EventPipeProviderConfiguration[] providers, int numProviders);
156 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
157 internal static extern void Disable();
160 // These PInvokes are used by EventSource to interact with the EventPipe.
162 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
163 internal static extern IntPtr CreateProvider(string providerName, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback callbackFunc);
165 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
166 internal static extern unsafe IntPtr DefineEvent(IntPtr provHandle, uint eventID, long keywords, uint eventVersion, uint level, void *pMetadata, uint metadataLength);
168 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
169 internal static extern void DeleteProvider(IntPtr provHandle);
171 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
172 internal static extern int EventActivityIdControl(uint controlCode, ref Guid activityId);
174 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
175 internal static extern unsafe void WriteEvent(IntPtr eventHandle, uint eventID, void* pData, uint length, Guid* activityId, Guid* relatedActivityId);
177 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
178 internal static extern unsafe void WriteEventData(IntPtr eventHandle, uint eventID, EventProvider.EventData* pEventData, uint dataCount, Guid* activityId, Guid* relatedActivityId);