Exemple #1
0
 internal static string LookupSeverity(TraceEventLevel level, TraceEventOpcode opcode)
 {
     string severity;
     if (opcode == TraceEventOpcode.Info)
     {
         switch (level)
         {
             case TraceEventLevel.Critical:
                 severity = "Critical";
                 break;
             case TraceEventLevel.Error:
                 severity = "Error";
                 break;
             case TraceEventLevel.Warning:
                 severity = "Warning";
                 break;
             case TraceEventLevel.Informational:
                 severity = "Information";
                 break;
             case TraceEventLevel.Verbose:
                 severity = "Verbose";
                 break;
             default:
                 severity = level.ToString();
                 break;
         }
     }
     else
     {
         switch (opcode)
         {
             case TraceEventOpcode.Start:
                 severity = "Start";
                 break;
             case TraceEventOpcode.Stop:
                 severity = "Stop";
                 break;
             case TraceEventOpcode.Suspend:
                 severity = "Suspend";
                 break;
             case TraceEventOpcode.Resume:
                 severity = "Resume";
                 break;
             default:
                 severity = opcode.ToString();
                 break;
         }
     }
     return severity;
 }
        internal static string LookupSeverity(TraceEventLevel level, TraceEventOpcode opcode)
        {
            switch (opcode)
            {
                case TraceEventOpcode.Start:
                    return "Start";

                case TraceEventOpcode.Stop:
                    return "Stop";

                case TraceEventOpcode.Resume:
                    return "Resume";

                case TraceEventOpcode.Suspend:
                    return "Suspend";

                case TraceEventOpcode.Info:
                    switch (level)
                    {
                        case TraceEventLevel.Critical:
                            return "Critical";

                        case TraceEventLevel.Error:
                            return "Error";

                        case TraceEventLevel.Warning:
                            return "Warning";

                        case TraceEventLevel.Informational:
                            return "Information";

                        case TraceEventLevel.Verbose:
                            return "Verbose";
                    }
                    return level.ToString();
            }
            return opcode.ToString();
        }
 internal static TraceEventType GetTraceEventType(TraceEventLevel level)
 {
     return EtwLevelToTraceEventType[(int)level];
 }
Exemple #4
0
 /// <summary>
 /// Add an additional USER MODE provider prepresented by 'providerGuid' (a list of
 /// providers is available by using 'logman query providers').
 /// </summary>
 /// <param name="providerGuid">
 /// The GUID that represents the event provider to turn on. Use 'logman query providers' or
 /// for a list of possible providers. Note that additional user mode (but not kernel mode)
 /// providers can be added to the session by using EnableProvider.</param>
 /// <param name="providerLevel">The verbosity to turn on</param>
 /// <param name="matchAnyKeywords">A bitvector representing the areas to turn on. Only the
 /// low 32 bits are used by classic providers and passed as the 'flags' value.  Zero
 /// is a special value which is a provider defined default, which is usuall 'everything'</param>
 /// <param name="matchAllKeywords">A bitvector representing keywords of an event that must
 /// be on for a particular event for the event to be logged.  A value of zero means
 /// that no keyword must be on, which effectively ignores this value.  </param>
 /// <param name="options">Additional options for the provider (e.g. taking a stack trace)</param>
 /// <param name="values">This is set of key-value strings that are passed to the provider
 /// for provider-specific interpretation. Can be null if no additional args are needed.  
 /// If the special key-value pair 'Command'='SendManifest' is provided, then the 'SendManifest'
 /// command will be sent (which causes EventSources to redump their manifest to the ETW log.  </param>
 /// <returns>true if the session already existed and needed to be restarted.</returns>
 public bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel = TraceEventLevel.Verbose, ulong matchAnyKeywords = ulong.MaxValue, ulong matchAllKeywords = 0, TraceEventOptions options = 0, IEnumerable<KeyValuePair<string, string>> values = null)
 {
     byte[] valueData = null;
     int valueDataSize = 0;
     int valueDataType = 0;
     if (values != null)
     {
         valueDataType = 0; // ControllerCommand.Update  // TODO use enumeration
         valueData = new byte[1024];
         foreach (KeyValuePair<string, string> keyValue in values)
         {
             if (keyValue.Key == "Command")
             {
                 if (keyValue.Value == "SendManifest")
                     valueDataType = -1; // ControllerCommand.SendManifest
                 else
                 {
                     int val;
                     if (int.TryParse(keyValue.Value, out val))
                         valueDataType = val;
                 }
             }
             valueDataSize += Encoding.UTF8.GetBytes(keyValue.Key, 0, keyValue.Key.Length, valueData, valueDataSize);
             if (valueDataSize >= 1023)
                 throw new Exception("Too much provider data");  // TODO better message. 
             valueData[valueDataSize++] = 0;
             valueDataSize += Encoding.UTF8.GetBytes(keyValue.Value, 0, keyValue.Value.Length, valueData, valueDataSize);
             if (valueDataSize >= 1023)
                 throw new Exception("Too much provider data");  // TODO better message. 
             valueData[valueDataSize++] = 0;
         }
     }
     return EnableProvider(providerGuid, providerLevel, matchAnyKeywords, matchAllKeywords, options, valueDataType, valueData, valueDataSize);
 }
 public bool ShouldTraceToTraceSource(TraceEventLevel level)
 {
     return ((this.HaveListeners && (this.TraceSource != null)) && (((TraceEventType) 0) != (TraceLevelHelper.GetTraceEventType(level) & ((TraceEventType) ((int) this.Level)))));
 }
 private static System.Diagnostics.Eventing.EventDescriptor GetEventDescriptor(int eventId, TraceChannel channel, TraceEventLevel traceEventLevel)
 {
     long keywords = 0L;
     if (channel == TraceChannel.Admin)
     {
         keywords |= -9223372036854775808L;
     }
     else if (channel == TraceChannel.Operational)
     {
         keywords |= 0x4000000000000000L;
     }
     else if (channel == TraceChannel.Analytic)
     {
         keywords |= 0x2000000000000000L;
     }
     else if (channel == TraceChannel.Debug)
     {
         keywords |= 0x100000000000000L;
     }
     else if (channel == TraceChannel.Perf)
     {
         keywords |= 0x800000000000000L;
     }
     return new System.Diagnostics.Eventing.EventDescriptor(eventId, 0, (byte) channel, (byte) traceEventLevel, 0, 0, keywords);
 }
Exemple #7
0
 public bool ShouldTraceToTraceSource(TraceEventLevel level)
 {
     return((this.HaveListeners && (this.TraceSource != null)) && (((TraceEventType)0) != (TraceLevelHelper.GetTraceEventType(level) & ((TraceEventType)((int)this.Level)))));
 }
 public void Event(int eventId, TraceEventLevel traceEventLevel, TraceChannel channel, string description)
 {
     if (this.TracingEnabled)
     {
         EventDescriptor eventDescriptor = EtwDiagnosticTrace.GetEventDescriptor(eventId, channel, traceEventLevel);
         this.Event(ref eventDescriptor, description);
     }
 }
 public virtual bool ShouldTrace(TraceEventLevel level)
 {
     return ShouldTraceToTraceSource(level);
 }
Exemple #10
0
		private static EventDescriptor GetEventDescriptor(int eventId, TraceChannel channel, TraceEventLevel traceEventLevel)
		{
			long num = (long)0;
			if (channel != TraceChannel.Admin)
			{
				if (channel != TraceChannel.Operational)
				{
					if (channel != TraceChannel.Analytic)
					{
						if (channel != TraceChannel.Debug)
						{
							if (channel == TraceChannel.Perf)
							{
								num = num | 0x800000000000000L;
							}
						}
						else
						{
							num = num | 0x100000000000000L;
						}
					}
					else
					{
						num = num | 0x2000000000000000L;
					}
				}
				else
				{
					num = num | 0x4000000000000000L;
				}
			}
			else
			{
				num = num | -9223372036854775808L;
			}
			return new EventDescriptor(eventId, 0, (byte)channel, (byte)traceEventLevel, 0, 0, num);
		}
        public static bool RealTimeTraceEventSession
        (
            string providerName
            , string sessionName
            , string tracingFileName = null
            , string[] traceEvents   = null
            , Action
            <
                long
                , TraceEventDispatcher
                , TraceEventSession
                , TraceEvent
            > onOneEventTracedOnceProcessAction = null
            , TraceEventProviderOptions traceEventProviderOptions = null
            , TraceEventSessionOptions traceEventSessionOptions   = TraceEventSessionOptions.Create
            , TraceEventSourceType traceEventSourceType           = TraceEventSourceType.MergeAll
            , TraceEventLevel traceEventLevel = TraceEventLevel.Always
            , ulong matchKeywords             = ulong.MaxValue
            , bool needCountHits = false
        )
        {
            var r = false;

            if (!(TraceEventSession.IsElevated() ?? false))
            {
                Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
                return(r);
            }
            var needTracingFile = !string.IsNullOrEmpty(tracingFileName);

            if
            (
                traceEvents != null
                &&
                traceEvents.Length > 0
                &&
                onOneEventTracedOnceProcessAction != null
            )
            {
                using
                (
                    var session =
                        (
                            needTracingFile
                                    ?
                            new TraceEventSession
                            (
                                sessionName
                                , tracingFileName
                                , traceEventSessionOptions
                            )
                {
                    StopOnDispose = true
                }
                                    :
                            new TraceEventSession
                            (
                                sessionName
                                , traceEventSessionOptions
                            )
                {
                    StopOnDispose = true
                }
                        )
                )
                {
                    using
                    (
                        var source =
                            (
                                needTracingFile
                                            ?
                                new ETWTraceEventSource(tracingFileName)
                                            :
                                session.Source
                            )
                    )
                    {
                        long sequence = 0;
                        RegisterCallbacks
                        (
                            providerName
                            , traceEvents
                            , source
                            , session
                            , (x, y, z) =>
                        {
                            long id = 0;
                            if (needCountHits)
                            {
                                id = Interlocked.Increment(ref sequence);
                            }
                            onOneEventTracedOnceProcessAction
                            (
                                id
                                , x
                                , y
                                , z
                            );
                        }
                        );
                        var restarted = session
                                        .EnableProvider
                                        (
                            providerName
                            , traceEventLevel
                            , matchKeywords
                            , traceEventProviderOptions
                                        );
                        source
                        .Process();
                        r = true;
                    }
                }
            }
            return(r);
        }
        public static bool TraceETWTraceEventSource
        (
            string providerName
            , string tracedFileName
            , string[] traceEvents = null
            , Action
            <
                long
                , TraceEventDispatcher
                , TraceEventSession
                , TraceEvent
            > onOneEventTracedOnceProcessAction = null
            , TraceEventProviderOptions traceEventProviderOptions = null
            , TraceEventSourceType traceEventSourceType           = TraceEventSourceType.MergeAll
            , TraceEventLevel traceEventLevel = TraceEventLevel.Always
            , ulong matchKeywords             = ulong.MaxValue
            , bool needCountHits = false
        )
        {
            var r = false;

            if (!(TraceEventSession.IsElevated() ?? false))
            {
                Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
                return(r);
            }
            if
            (
                traceEvents != null
                &&
                traceEvents.Length > 0
                &&
                onOneEventTracedOnceProcessAction != null
            )
            {
                using (var source = new ETWTraceEventSource(tracedFileName, traceEventSourceType))
                {
                    //闭包
                    long sequence = 0;
                    RegisterCallbacks
                    (
                        providerName
                        , traceEvents
                        , source
                        , null
                        , (x, y, z) =>
                    {
                        long id = 0;
                        if (needCountHits)
                        {
                            id = Interlocked.Increment(ref sequence);
                        }
                        onOneEventTracedOnceProcessAction
                        (
                            id
                            , x
                            , y
                            , z
                        );
                    }
                    );
                    source.Process();   // call the callbacks for each event
                }
            }
            return(true);
        }
Exemple #13
0
		internal static string LookupSeverity(TraceEventLevel level, TraceEventOpcode opcode)
		{
			string str;
			TraceEventOpcode traceEventOpcode = opcode;
			switch (traceEventOpcode)
			{
				case TraceEventOpcode.Start:
				{
					str = "Start";
					break;
				}
				case TraceEventOpcode.Stop:
				{
					str = "Stop";
					break;
				}
				default:
				{
					switch (traceEventOpcode)
					{
						case TraceEventOpcode.Resume:
						{
							str = "Resume";
							return str;
						}
						case TraceEventOpcode.Suspend:
						{
							str = "Suspend";
							return str;
						}
						default:
						{
							TraceEventLevel traceEventLevel = level;
							switch (traceEventLevel)
							{
								case TraceEventLevel.Critical:
								{
									str = "Critical";
									return str;
								}
								case TraceEventLevel.Error:
								{
									str = "Error";
									return str;
								}
								case TraceEventLevel.Warning:
								{
									str = "Warning";
									return str;
								}
								case TraceEventLevel.Informational:
								{
									str = "Information";
									return str;
								}
								case TraceEventLevel.Verbose:
								{
									str = "Verbose";
									return str;
								}
							}
							break;
						}
					}
					str = level.ToString();
					break;
				}
				break;
			}
			return str;
		}
 public MockEtwEventSource(string providerName, TraceEventLevel traceLevel, ulong matchAnyKeywords, IPlugInContext context) : base(providerName, traceLevel, matchAnyKeywords, context)
 {
 }
 public bool TraceETWTraceEventSource
             (
                 string providerName
                 , string tracedFileName
                 , string[] traceEvents = null
                 , Action
                         <
                             long
                             , TraceEventDispatcher
                             , TraceEventSession
                             , TraceEvent
                         > onOneEventTracedOnceProcessAction = null
                 , TraceEventProviderOptions traceEventProviderOptions = null
                 , TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
                 , TraceEventLevel traceEventLevel = TraceEventLevel.Always
                 , ulong matchKeywords = ulong.MaxValue
                 , bool needCountHits = false
             )
 {
     var r = false;
     if
         (
             traceEvents != null
             &&
             traceEvents.Length > 0
             &&
             onOneEventTracedOnceProcessAction != null
         )
     {
         r = TraceEventsHelper
                     .TraceETWTraceEventSource
                         (
                             providerName
                             , tracedFileName
                             , traceEvents
                             , onOneEventTracedOnceProcessAction
                             , traceEventProviderOptions
                             , traceEventSourceType
                             , traceEventLevel
                             , matchKeywords
                             , needCountHits
                         );
     }
     return r;
 }
 public static Task<bool> RealTimeTraceEventSessionAsync
                     (
                         string providerName
                         , string sessionName
                         , string tracingFileName = null
                         , string[] traceEvents = null
                         , Action
                                 <
                                     long
                                     , TraceEventDispatcher
                                     , TraceEventSession
                                     , TraceEvent
                                 > onOneEventTracedOnceProcessAction = null
                         , TraceEventProviderOptions traceEventProviderOptions = null
                         , TraceEventSessionOptions traceEventSessionOptions = TraceEventSessionOptions.Create
                         , TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
                         , TraceEventLevel traceEventLevel = TraceEventLevel.Always
                         , ulong matchKeywords = ulong.MaxValue
                         , bool needCountHits = false
                     )
 {
     return
         Task
             .Factory
             .StartNew<bool>
                 (
                     () =>
                     {
                         return
                             RealTimeTraceEventSession
                                 (
                                     providerName
                                     , sessionName
                                     , tracingFileName
                                     , traceEvents
                                     , onOneEventTracedOnceProcessAction
                                     , traceEventProviderOptions
                                     , traceEventSessionOptions
                                     , traceEventSourceType
                                     , traceEventLevel
                                     , matchKeywords
                                     , needCountHits
                                 );
                     }
                     ,
                         TaskCreationOptions.LongRunning
                         |
                         TaskCreationOptions.DenyChildAttach
                 );
 }
Exemple #17
0
		public override bool ShouldTrace(TraceEventLevel level)
		{
			if (base.ShouldTrace(level))
			{
				return true;
			}
			else
			{
				return this.ShouldTraceToEtw(level);
			}
		}
 public override bool ShouldTrace(TraceEventLevel level)
 {
     return base.ShouldTrace(level) || ShouldTraceToEtw(level);
 }
Exemple #19
0
		public bool ShouldTraceToEtw(TraceEventLevel level)
		{
			if (this.EtwProvider == null)
			{
				return false;
			}
			else
			{
				return this.EtwProvider.IsEnabled((byte)level, (long)0);
			}
		}
 public bool ShouldTraceToTraceSource(TraceEventLevel level)
 {
     return(this.ShouldTrace(TraceLevelHelper.GetTraceEventType(level)));
 }
 public TraceLogEventArgs(string providerName, TraceEventLevel level, string message)
 {
     this.ProviderName = providerName ?? throw new ArgumentNullException(nameof(providerName));
     this.Level        = level;
     this.Message      = message ?? throw new ArgumentNullException(nameof(message));
 }
Exemple #22
0
 public bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel = TraceEventLevel.Verbose, ulong matchAnyKeywords = ulong.MaxValue, TraceEventProviderOptions options = null)
 {
     return(this.session.EnableProvider(providerGuid, providerLevel, matchAnyKeywords, options));
 }
Exemple #23
0
 internal static TraceEventType GetTraceEventType(TraceEventLevel level)
 {
     return(EtwLevelToTraceEventType[(int)level]);
 }
 public bool ShouldTrace(TraceEventLevel level)
 {
     if (!this.ShouldTraceToTraceSource(level))
     {
         return this.ShouldTraceToEtw(level);
     }
     return true;
 }
Exemple #25
0
 public bool EnableProvider(TraceEventLevel level = TraceEventLevel.Verbose, ulong matchAnyKeywords = ulong.MaxValue, TraceEventProviderOptions options = null)
 {
     return(session.EnableProvider(WinINetProviderId, TraceEventLevel.Verbose, matchAnyKeywords, options));
 }
 public bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel)
 {
     return EnableProvider(providerGuid, providerLevel, 0, 0, null);
 }
 public bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel, ulong matchAnyKeywords)
 {
     return EnableProvider(providerGuid, providerLevel, matchAnyKeywords, 0, null);
 }
Exemple #28
0
        /// <summary>
        /// Do intialization common to the contructors.  
        /// </summary>
        private bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel, ulong matchAnyKeywords, ulong matchAllKeywords, TraceEventOptions options, int providerDataType, byte[] providerData, int providerDataSize)
        {
            if (m_SessionName == KernelTraceEventParser.KernelSessionName)
                throw new NotSupportedException("Can only enable kernel events on a kernel session.");

            bool ret = InsureStarted();
            TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR* dataDescrPtr = null;
            fixed (byte* providerDataPtr = providerData)
            {
                string regKeyName = @"Software\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + providerGuid + "}";
                byte[] registryData = null;
                // If this is an update operation, remember the data in registry so that even providers
                // that have not yet started will get the data.   We don't do this for any other kind of command (providerDataType)
                // since we don't know that they are desired 'on startup'.  
                if (providerData != null && providerDataType == 0)
                {
                    TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR dataDescr = new TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR();
                    dataDescr.Ptr = null;
                    dataDescr.Size = providerDataSize;
                    dataDescr.Type = providerDataType;
                    dataDescrPtr = &dataDescr;

                    if (providerData == null)
                        providerData = new byte[0];
                    else
                        dataDescr.Ptr = providerDataPtr;

                    // Set the registry key so providers get the information even if they are not active now
                    registryData = new byte[providerDataSize + 4];
                    // providerDataType is always zero, but older versions assume it is here, so we put the redundant value here for compatibility. 
                    registryData[0] = (byte)(providerDataType);
                    registryData[1] = (byte)(providerDataType >> 8);
                    registryData[2] = (byte)(providerDataType >> 16);
                    registryData[3] = (byte)(providerDataType >> 24);
                    Array.Copy(providerData, 0, registryData, 4, providerDataSize);
                }
                SetOrDelete(regKeyName, "ControllerData", registryData);
                int hr;

                try
                {
                    try
                    {
                        // Try the Win7 API
                        TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS parameters = new TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS();
                        parameters.Version = TraceEventNativeMethods.ENABLE_TRACE_PARAMETERS_VERSION;
                        if ((options & TraceEventOptions.Stacks) != 0)
                            parameters.EnableProperty = TraceEventNativeMethods.EVENT_ENABLE_PROPERTY_STACK_TRACE;
                        parameters.EnableFilterDesc = dataDescrPtr;

                        hr = TraceEventNativeMethods.EnableTraceEx2(m_SessionHandle, ref providerGuid,
                            TraceEventNativeMethods.EVENT_CONTROL_CODE_ENABLE_PROVIDER, (byte)providerLevel,
                            matchAnyKeywords, matchAllKeywords, 0, ref parameters);
                    }
                    catch (EntryPointNotFoundException)
                    {
                        // OK that did not work, try the VISTA API
                        hr = TraceEventNativeMethods.EnableTraceEx(ref providerGuid, null, m_SessionHandle, 1,
                            (byte)providerLevel, matchAnyKeywords, matchAllKeywords, 0, dataDescrPtr);
                    }
                }
                catch (EntryPointNotFoundException)
                {
                    // Try with the old pre-vista API
                    hr = TraceEventNativeMethods.EnableTrace(1, (int)matchAnyKeywords, (int)providerLevel, ref providerGuid, m_SessionHandle);
                }
                Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr));
            }
            m_IsActive = true;
            return ret;
        }
 /// <summary>
 /// Add an additional USER MODE provider prepresented by 'providerGuid' (a list of
 /// providers is available by using 'logman query providers').
 /// </summary>
 /// <param name="providerGuid">
 /// The GUID that represents the event provider to turn on. Use 'logman query providers' or
 /// for a list of possible providers. Note that additional user mode (but not kernel mode)
 /// providers can be added to the session by using EnableProvider.</param>
 /// <param name="providerLevel">The verbosity to turn on</param>
 /// <param name="matchAnyKeywords">A bitvector representing the areas to turn on. Only the
 /// low 32 bits are used by classic providers and passed as the 'flags' value.  Zero
 /// is a special value which is a provider defined default, which is usuall 'everything'</param>
 /// <param name="matchAllKeywords">A bitvector representing keywords of an event that must
 /// be on for a particular event for the event to be logged.  A value of zero means
 /// that no keyword must be on, which effectively ignores this value.  </param>
 /// <param name="values">This is set of key-value strings that are passed to the provider
 /// for provider-specific interpretation. Can be null if no additional args are needed.</param>
 /// <returns>true if the session already existed and needed to be restarted.</returns>
 public bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel, ulong matchAnyKeywords, ulong matchAllKeywords, IEnumerable<KeyValuePair<string, string>> values)
 {
     byte[] valueData = null;
     int valueDataSize = 0;
     int valueDataType = 0;
     if (values != null)
     {
         valueDataType = 0; // ControllerCommands.Start   // TODO use enumeration
         valueData = new byte[1024];
         foreach (KeyValuePair<string, string> keyValue in values)
         {
             valueDataSize += Encoding.UTF8.GetBytes(keyValue.Key, 0, keyValue.Key.Length, valueData, valueDataSize);
             if (valueDataSize >= 1023)
                 throw new Exception("Too much provider data");  // TODO better message.
             valueData[valueDataSize++] = 0;
             valueDataSize += Encoding.UTF8.GetBytes(keyValue.Value, 0, keyValue.Value.Length, valueData, valueDataSize);
             if (valueDataSize >= 1023)
                 throw new Exception("Too much provider data");  // TODO better message.
             valueData[valueDataSize++] = 0;
         }
     }
     return EnableProvider(providerGuid, providerLevel, matchAnyKeywords, matchAllKeywords, valueDataType, valueData, valueDataSize);
 }
 public Task<bool> TraceETWTraceEventSourceAsync
             (
                 string providerName
                 , string tracedFileName
                 , string[] traceEvents = null
                 , Action
                         <
                             long
                             , TraceEventDispatcher
                             , TraceEventSession
                             , TraceEvent
                         > onOneEventTracedOnceProcessAction = null
                 , TraceEventProviderOptions traceEventProviderOptions = null
                 , TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
                 , TraceEventLevel traceEventLevel = TraceEventLevel.Always
                 , ulong matchKeywords = ulong.MaxValue
                 , bool needCountHits = false
             )
 {
     return
         Task
             .Factory
             .StartNew<bool>
                 (
                     () =>
                     {
                         return
                             TraceETWTraceEventSource
                             (
                                 providerName
                                 , tracedFileName
                                 , traceEvents
                                 , onOneEventTracedOnceProcessAction
                                 , traceEventProviderOptions
                                 , traceEventSourceType
                                 , traceEventLevel
                                 , matchKeywords
                                 , needCountHits
                             );
                     }
                 );
 }
        private unsafe bool EnableProvider(Guid providerGuid, TraceEventLevel providerLevel, ulong matchAnyKeywords, ulong matchAllKeywords, int providerDataType, byte[] providerData, int providerDataSize)
        {
            bool ret = InsureSession();
            TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR* dataDescrPtr = null;
            fixed (byte* providerDataPtr = providerData)
            {
                string regKeyName = @"Software\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + providerGuid + "}";
                byte[] registryData = null;
                if (providerData != null || providerDataType != 0)
                {
                    TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR dataDescr = new TraceEventNativeMethods.EVENT_FILTER_DESCRIPTOR();
                    dataDescr.Ptr = null;
                    dataDescr.Size = providerDataSize;
                    dataDescr.Type = providerDataType;
                    dataDescrPtr = &dataDescr;

                    if (providerData == null)
                        providerData = new byte[0];
                    else
                        dataDescr.Ptr = providerDataPtr;

                    // Set the registry key so providers get the information even if they are not active now
                    registryData = new byte[providerDataSize + 4];
                    registryData[0] = (byte)(providerDataType);
                    registryData[1] = (byte)(providerDataType >> 8);
                    registryData[2] = (byte)(providerDataType >> 16);
                    registryData[3] = (byte)(providerDataType >> 24);
                    Array.Copy(providerData, 0, registryData, 4, providerDataSize);
                }
                SetOrDelete(regKeyName, "ControllerData", registryData);
                int hr;
                try
                {
                    hr = TraceEventNativeMethods.EnableTraceEx(ref providerGuid, null, sessionHandle,
                    1, (byte)providerLevel, matchAnyKeywords, matchAllKeywords, 0, dataDescrPtr);
                }
                catch (EntryPointNotFoundException)
                {
                    // Try with the old pre-vista API
                    hr = TraceEventNativeMethods.EnableTrace(1, (int)matchAnyKeywords, (int)providerLevel, ref providerGuid, sessionHandle);
                }
                Marshal.ThrowExceptionForHR(TraceEventNativeMethods.GetHRFromWin32(hr));
                }
            isActive = true;
            return ret;
        }
 public static bool TraceETWTraceEventSource
                     (
                         string providerName
                         , string tracedFileName
                         , string[] traceEvents = null
                         , Action
                                 <
                                     long
                                     , TraceEventDispatcher
                                     , TraceEventSession
                                     , TraceEvent
                                 > onOneEventTracedOnceProcessAction = null
                         , TraceEventProviderOptions traceEventProviderOptions = null
                         , TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
                         , TraceEventLevel traceEventLevel = TraceEventLevel.Always
                         , ulong matchKeywords = ulong.MaxValue
                         , bool needCountHits = false
                     )
 {
     var r = false;
     if (!(TraceEventSession.IsElevated() ?? false))
     {
         Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
         return r;
     }
     if
         (
             traceEvents != null
             &&
             traceEvents.Length > 0
             &&
             onOneEventTracedOnceProcessAction != null
         )
     {
         using (var source = new ETWTraceEventSource(tracedFileName, traceEventSourceType))
         {
             //闭包
             long sequence = 0;
             RegisterCallbacks
                 (
                     providerName
                     , traceEvents
                     , source
                     , null
                     , (x, y, z) =>
                     {
                         long id = 0;
                         if (needCountHits)
                         {
                             id = Interlocked.Increment(ref sequence);
                         }
                         onOneEventTracedOnceProcessAction
                                         (
                                             id
                                             , x
                                             , y
                                             , z
                                         );
                     }
                 );
             source.Process();   // call the callbacks for each event
         }
     }
     return true;
 }
 public override bool ShouldTrace(TraceEventLevel level)
 {
     return(base.ShouldTrace(level) || ShouldTraceToEtw(level));
 }
        public static bool RealTimeTraceEventSession
            (
                string providerName
                , string sessionName
                , string tracingFileName = null
                , string[] traceEvents = null
                , Action
                        <
                            long
                            , TraceEventDispatcher
                            , TraceEventSession
                            , TraceEvent
                        > onOneEventTracedOnceProcessAction = null
                , TraceEventProviderOptions traceEventProviderOptions = null
                , TraceEventSessionOptions traceEventSessionOptions = TraceEventSessionOptions.Create
                , TraceEventSourceType traceEventSourceType = TraceEventSourceType.MergeAll
                , TraceEventLevel traceEventLevel = TraceEventLevel.Always
                , ulong matchKeywords = ulong.MaxValue
                , bool needCountHits = false
            )
        {
            var r = false;
            if (!(TraceEventSession.IsElevated() ?? false))
            {
                Out.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
                return r;
            }
            var needTracingFile = !string.IsNullOrEmpty(tracingFileName);
            if
                (
                    traceEvents != null
                    &&
                    traceEvents.Length > 0
                    &&
                    onOneEventTracedOnceProcessAction != null
                )
            {
                using
                    (
                        var session =
                                (
                                    needTracingFile
                                    ?
                                    new TraceEventSession
                                                (
                                                    sessionName
                                                    , tracingFileName
                                                    , traceEventSessionOptions
                                                )
                                    {
                                        StopOnDispose = true
                                    }
                                    :
                                    new TraceEventSession
                                                (
                                                    sessionName
                                                    , traceEventSessionOptions
                                                )
                                    {
                                        StopOnDispose = true
                                    }
                                )
                    )
                {
                    using
                        (
                            var source =
                                        (
                                            needTracingFile
                                            ?
                                            new ETWTraceEventSource(tracingFileName)
                                            :
                                            session.Source
                                        )
                            )
                    {
                        long sequence = 0;
                        RegisterCallbacks
                            (
                                providerName
                                , traceEvents
                                , source
                                , session
                                , (x, y, z) =>
                                {
                                    long id = 0;
                                    if (needCountHits)
                                    {
                                        id = Interlocked.Increment(ref sequence);
                                    }
                                    onOneEventTracedOnceProcessAction
                                                    (
                                                        id
                                                        , x
                                                        , y
                                                        , z
                                                    );
                                }
                            );
                        var restarted = session
                                            .EnableProvider
                                                (
                                                    providerName
                                                    , traceEventLevel
                                                    , matchKeywords
                                                    , traceEventProviderOptions
                                                );
                        source
                            .Process();
                        r = true;
                    }
                }

            }
            return r;
        }
Exemple #35
0
        private void SetupCommandLine(CommandLineParser parser)
        {
            // #CommandLineDefinitions
            parser.ParameterSetsWhereQualifiersMustBeFirst = new string[] { "run", "UserCommand" };
            parser.NoDashOnParameterSets = true;

            parser.DefineOptionalQualifier("LogFile", ref LogFile, "Send messages to this file instead launching the GUI.  Intended for batch scripts and other automation.");

            // These apply to start, collect and run
            parser.DefineOptionalQualifier("BufferSize", ref BufferSizeMB, "The size the buffers (in MB) the OS should use to store events waiting to be written to disk."); // TODO remove eventually.
            parser.DefineOptionalQualifier("Circular", ref CircularMB, "Do Circular logging with a file size in MB.  Zero means non-circular.");                             // TODO remove eventually.
            parser.DefineOptionalQualifier("BufferSizeMB", ref BufferSizeMB, "The size the buffers (in MB) the OS should use to store events waiting to be written to disk.");
            parser.DefineOptionalQualifier("CircularMB", ref CircularMB, "Do Circular logging with a file size in MB.  Zero means non-circular.");
            parser.DefineOptionalQualifier("InMemoryCircularBuffer", ref InMemoryCircularBuffer, "Keeps the circular buffer in memory until the session is stopped.");
            parser.DefineOptionalQualifier("StackCompression", ref StackCompression, "Use stack compression (only on Win 8+) to make collected file smaller.");
            parser.DefineOptionalQualifier("MaxCollectSec", ref MaxCollectSec,
                                           "Turn off collection (and kill the program if perfView started it) after this many seconds. Zero means no timeout.");
            parser.DefineOptionalQualifier("StopOnPerfCounter", ref StopOnPerfCounter,
                                           "This is of the form CATEGORY:COUNTERNAME:INSTANCE OP NUM  where CATEGORY:COUNTERNAME:INSTANCE, identify " +
                                           "a performance counter (same as PerfMon), OP is either < or >, and NUM is a number.  " +
                                           "When that condition is true then collection will stop.  You can specify this qualifier more than once (logical OR).  See 'Stop Trigger' in the users guide for more.");
            parser.DefineOptionalQualifier("StopOnEventLogMessage", ref StopOnEventLogMessage,
                                           "Stop when an event log message that matches the given (ignore case) regular expression is written to the Windows 'Application' event log.  " +
                                           "You can specify a particular event log with the syntax eventLogName@RegExp.   Can be specified more than once (logical OR).");

            parser.DefineOptionalQualifier("StopOnEtwEvent", ref StopOnEtwEvent,
                                           "This is of the form PROVIDER/EVENTNAME;key1=value1;key2=value2... " +
                                           "This option is quite powerful, See the users guide for more details.");

            int StopOnRequestOverMsec   = 0;
            int StopOnGCSuspendOverMSec = 0;

            // These are basically special cases of the /StopOnEtwEvent
            parser.DefineOptionalQualifier("StopOnRequestOverMsec", ref StopOnRequestOverMsec,
                                           "Trigger a stop of a collect command if there is any IIS request that is longer than the given number of MSec.");
            parser.DefineOptionalQualifier("StopOnGCOverMsec", ref StopOnGCOverMsec,
                                           "Trigger a stop of a collect command if there is a .NET Garbage Collection (GC) is longer than the given number of MSec.");
            parser.DefineOptionalQualifier("StopOnGCSuspendOverMSec", ref StopOnGCSuspendOverMSec,
                                           "Trigger a stop of a collect command if there is a .NET Garbage Collection (GC) where suspending for the GC took over the given number of MSec.");
            parser.DefineOptionalQualifier("StopOnBGCFinalPauseOverMsec", ref StopOnBGCFinalPauseOverMsec,
                                           "Trigger a stop of a collect command if there is a background .NET Garbage Collection (GC) whose final pause is longer than the given number of MSec. To work correctly, " +
                                           "this requires that heap survival and movement tracking is not enabled.");
            parser.DefineOptionalQualifier("StopOnAppFabricOverMsec", ref StopOnAppFabricOverMsec,
                                           "Trigger a stop of a collect command if there is a AppFabric request is longer than the given number of MSec.");

            parser.DefineOptionalQualifier("StopOnException", ref StopOnException,
                                           "Where the text is a regular expression that will be used to match the full name and message of the .NET Exception thrown." +
                                           "The empty string represents any exception.");
            parser.DefineOptionalQualifier("StopOnGen2GC", ref StopOnGen2GC,
                                           "This will stop on any non-background Gen2 GC from the given process (can be a process ID or a process Name (exe file name without path or extension) or * (any process)");

            parser.DefineOptionalQualifier("Process", ref Process, "A process name (exe file name without directory or extension) or the Decimal Process ID.  " +
                                           "If used with the /StopOn* qualifiers using ETW events, will restrict events to only that process.");
            parser.DefineOptionalQualifier("DecayToZeroHours", ref DecayToZeroHours,
                                           "The trigger value used in StopOnPerfCounter or StopOn*OverMSec will decay to zero in this interval of time.");
            parser.DefineOptionalQualifier("MinSecForTrigger", ref MinSecForTrigger,
                                           "The number of seconds a perf Counter has to be above threshold before it is considered triggered.");
            parser.DefineOptionalQualifier("DelayAfterTriggerSec", ref DelayAfterTriggerSec,
                                           "Wait this number of seconds after a trigger before actually stopping the trace.");
            parser.DefineOptionalQualifier("CollectMultiple", ref CollectMultiple, "Collect Multiple instance (used in conjunction with StopTrigger).");
            parser.DefineOptionalQualifier("StartOnPerfCounter", ref StartOnPerfCounter,
                                           "This is of the form CATEGORY:COUNTERNAME:INSTANCE OP NUM  where CATEGORY:COUNTERNAME:INSTANCE, identify " +
                                           "a performance counter (same as PerfMon), OP is either < or >, and NUM is a number.  " +
                                           "When that condition is true then collection will start.  You can specify this qualifier more than once.  Search for 'MonitorPerfCounter' in the users guide for more.");
            parser.DefineOptionalQualifier("StopCommand", ref StopCommand,
                                           "If present this command is executed when a PerfView stops.  It is useful to stopping other tracing logic external to PerfView.");

            List <string> etwStopEvents = new List <string>();

            if (StopOnRequestOverMsec != 0)
            {
                etwStopEvents.Add("Microsoft-Windows-IIS/EventID(1);Level=Critical;TriggerMSec=" + StopOnRequestOverMsec);
            }

            if (StopOnGCSuspendOverMSec != 0)
            {
                etwStopEvents.Add("E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4/GC/SuspendEEStart;StopEvent=GC/SuspendEEStop;StartStopID=ThreadID;Keywords=0x1;TriggerMSec=" + StopOnGCSuspendOverMSec);
            }

            if (0 < etwStopEvents.Count)
            {
                if (StopOnEtwEvent != null)
                {
                    etwStopEvents.AddRange(StopOnEtwEvent);
                }

                StopOnEtwEvent = etwStopEvents.ToArray();
            }

            // Respect the /Process and /DecayToZeroHours options by tacking them on the end if they are not already present.
            if (StopOnEtwEvent != null && (Process != null || DecayToZeroHours != 0))
            {
                etwStopEvents.Clear();
                foreach (var stopEtwEvent in StopOnEtwEvent)
                {
                    var newStopEtwEvent = stopEtwEvent;
                    if (Process != null && !stopEtwEvent.Contains(";Process="))
                    {
                        newStopEtwEvent += ";Process=" + Process;
                    }

                    if (DecayToZeroHours != 0 && !stopEtwEvent.Contains(";DecayToZeroHours="))
                    {
                        newStopEtwEvent += ";DecayToZeroHours=" + DecayToZeroHours;
                    }

                    etwStopEvents.Add(newStopEtwEvent);
                }
                StopOnEtwEvent = etwStopEvents.ToArray();
            }

            parser.DefineOptionalQualifier("MonitorPerfCounter", ref MonitorPerfCounter,
                                           "This is of the form CATEGORY:COUNTERNAME:INSTANCE@NUM  where CATEGORY:COUNTERNAME:INSTANCE, identify " +
                                           "a performance counter (same as PerfMon), and NUM is a number representing seconds.  The @NUM part is " +
                                           "optional and defaults to 2.   The value of the performance counter is logged to the ETL file as an " +
                                           "event ever NUM seconds");
            parser.DefineOptionalQualifier("CpuSampleMSec", ref CpuSampleMSec,
                                           "The interval (MSec) between CPU samples (.125Msec min).");

            // These apply to Stop Collect and Run
            parser.DefineOptionalQualifier("Merge", ref Merge, "Do a merge after stopping collection.");
            parser.DefineOptionalQualifier("Zip", ref Zip, "Zip the ETL file (implies /Merge).");
            parser.DefineOptionalQualifier("Wpr", ref Wpr, "Make output mimic WPR (Windows Performance Recorder). Don't ZIP, make a .ngenpdbs directory.  " +
                                           "This also enables threadTime as well as user mode providers WPR would normally collect by default.   This option can also be used " +
                                           "On the unzip command.   See 'Working with WPA' in the help for more.");
            parser.DefineOptionalQualifier("LowPriority", ref LowPriority, "Do merging and ZIPing at low priority to minimize impact to system.");
            parser.DefineOptionalQualifier("NoRundown", ref NoRundown, "Don't collect rundown events.  Use only if you know the process of interest has exited.");
            parser.DefineOptionalQualifier("NoNGenPdbs", ref NoNGenPdbs, "Don't generate NGEN Pdbs");
            parser.DefineOptionalQualifier("NoNGenRundown", ref NoNGenRundown,
                                           "Don't do rundown of symbolic information in NGEN images (only needed pre V4.5).");
            parser.DefineOptionalQualifier("NoClrRundown", ref NoClrRundown,
                                           "Don't do rundown .NET (CLR) rundown information )(for symbolic name lookup).");
            parser.DefineOptionalQualifier("RundownTimeout", ref RundownTimeout,
                                           "Maximum number of seconds to wait for CLR rundown to complete.");
            parser.DefineOptionalQualifier("MinRundownTime", ref MinRundownTime,
                                           "Minimum number of seconds to wait for CLR rundown to complete.");
            parser.DefineOptionalQualifier("KeepAllEvents", ref KeepAllEvents,
                                           "A debug option to keep all events, even symbolic rundown events.");
            parser.DefineOptionalQualifier("MaxEventCount", ref MaxEventCount, "Limits the total number of events.  " +
                                           "Useful for trimming large ETL files. 1M typically yields 300-400 Meg of data considered.");
            parser.DefineOptionalQualifier("SkipMSec", ref SkipMSec, "Skips the first N MSec of the trace.  " +
                                           "Useful for trimming large ETL files in conjunction with the /MaxEventCount qualifier.");
            parser.DefineOptionalQualifier("ContinueOnError", ref ContinueOnError, "Processes bad traces as best it can.");

            parser.DefineOptionalQualifier("CpuCounters", ref CpuCounters,
                                           "A comma separated list of hardware CPU counters specifications NAME:COUNT to turn on.  " +
                                           "See Users guide for details.  See ListCpuCounters for available sources (Win8 only)");

            parser.DefineOptionalQualifier("Providers", ref Providers,
                                           "Additional providers.  This is comma separated list of ProviderGuid:Keywords:Level:Stack specs.  " +
                                           "This qualifier has the same syntax as the Additional Providers TextBox in the collection window.  " +
                                           " See help on that for more.");

            string[] onlyProviders = null;
            parser.DefineOptionalQualifier("OnlyProviders", ref onlyProviders,
                                           "Like the Providers qualifier, but also turns off the default Kernel and CLR providers.");
            if (onlyProviders != null)
            {
                // Allow stack traces to work if 'stacks' was specified.
                bool hasStacks = false;
                bool hasTpl    = false;
                foreach (var provider in onlyProviders)
                {
                    if (0 <= provider.IndexOf("@StacksEnabled=true", StringComparison.OrdinalIgnoreCase))
                    {
                        hasStacks = true;
                    }

                    if (0 <= provider.IndexOf("@EventIDStacksToEnable", StringComparison.OrdinalIgnoreCase))
                    {
                        hasStacks = true;
                    }

                    if (provider.StartsWith(".NETTasks", StringComparison.OrdinalIgnoreCase))
                    {
                        hasTpl = true;
                    }
                }

                if (hasStacks)
                {
                    KernelEvents = KernelTraceEventParser.Keywords.Process | KernelTraceEventParser.Keywords.Thread | KernelTraceEventParser.Keywords.ImageLoad;
                    ClrEvents    = ClrTraceEventParser.Keywords.Jit | ClrTraceEventParser.Keywords.Loader;
                }
                else
                {
                    KernelEvents  = KernelTraceEventParser.Keywords.None;
                    ClrEvents     = ClrTraceEventParser.Keywords.None;
                    NoNGenRundown = true;   // We still do normal rundown because EventSource rundown is done there.
                    NoClrRundown  = true;
                }

                if (!hasTpl)
                {
                    // Turn on causality tracking.
                    TplEvents = TplEtwProviderTraceEventParser.Keywords.TasksFlowActivityIds;
                }

                Providers = onlyProviders;
            }
            parser.DefineOptionalQualifier("ThreadTime", ref ThreadTime, "Shortcut for turning on context switch and readyThread events");
            if (ThreadTime)
            {
                KernelEvents = KernelTraceEventParser.Keywords.ThreadTime;
            }

            parser.DefineOptionalQualifier("GCOnly", ref GCOnly, "Turns on JUST GC collections an allocation sampling.");
            if (GCOnly)
            {
                // TODO this logic is cloned.  We need it in only one place.  If you update it do the other location as well
                // For stack parsing.
                KernelEvents = KernelTraceEventParser.Keywords.Process | KernelTraceEventParser.Keywords.Thread | KernelTraceEventParser.Keywords.ImageLoad | KernelTraceEventParser.Keywords.VirtualAlloc;
                ClrEvents    = ClrTraceEventParser.Keywords.GC | ClrTraceEventParser.Keywords.GCHeapSurvivalAndMovement | ClrTraceEventParser.Keywords.Stack |
                               ClrTraceEventParser.Keywords.Jit | ClrTraceEventParser.Keywords.StopEnumeration | ClrTraceEventParser.Keywords.SupressNGen |
                               ClrTraceEventParser.Keywords.Loader | ClrTraceEventParser.Keywords.Exception;
                TplEvents = TplEtwProviderTraceEventParser.Keywords.None;

                // This is not quite correct if you have providers of your own, but this covers the most important case.
                if (Providers == null)
                {
                    Providers = new string[] { "Microsoft-Windows-Kernel-Memory:0x60" };
                }

                CommandProcessor.s_UserModeSessionName = "PerfViewGCSession";
                DataFile = "PerfViewGCOnly.etl";
            }
            parser.DefineOptionalQualifier("GCCollectOnly", ref GCCollectOnly, "Turns on GC collections (no allocation sampling).");
            if (GCCollectOnly)
            {
                // TODO this logic is cloned.  We need it in only one place.  If you update it do the other location as well
                // The process events are so we get process names.  The ImageLoad events are so that we get version information about the DLLs
                KernelEvents  = KernelTraceEventParser.Keywords.Process | KernelTraceEventParser.Keywords.ImageLoad;
                ClrEvents     = ClrTraceEventParser.Keywords.GC | ClrTraceEventParser.Keywords.Exception;
                ClrEventLevel = TraceEventLevel.Informational;
                TplEvents     = TplEtwProviderTraceEventParser.Keywords.None;
                NoRundown     = true;
                CommandProcessor.s_UserModeSessionName = "PerfViewGCSession";
                DataFile = "PerfViewGCCollectOnly.etl";
            }

            // WPR option implies a bunch of kernel events.
            if (Wpr)
            {
                KernelEvents = KernelTraceEventParser.Keywords.ThreadTime |
                               KernelTraceEventParser.Keywords.DeferedProcedureCalls |
                               KernelTraceEventParser.Keywords.Driver |
                               KernelTraceEventParser.Keywords.Interrupt;
            }

            parser.DefineOptionalQualifier("DumpHeap", ref DumpHeap, "Capture a heap snapshot on profile stop");
            parser.DefineOptionalQualifier("ClrEventLevel", ref ClrEventLevel, "The verbosity for CLR events");
            parser.DefineOptionalQualifier("ClrEvents", ref ClrEvents,
                                           "A comma separated list of .NET CLR events to turn on.  See Users guide for details.");
            parser.DefineOptionalQualifier("KernelEvents", ref KernelEvents,
                                           "A comma separated list of windows OS kernel events to turn on.  See Users guide for details.");
            parser.DefineOptionalQualifier("TplEvents", ref TplEvents,
                                           "A comma separated list of Task Parallel Library (TPL) events to turn on.  See Users guide for details.");

            parser.DefineOptionalQualifier("DotNetAlloc", ref DotNetAlloc, "Turns on per-allocation .NET profiling.");
            parser.DefineOptionalQualifier("DotNetAllocSampled", ref DotNetAllocSampled, "Turns on per-allocation .NET profiling, sampling types in a smart way to keep overhead low.");
            parser.DefineOptionalQualifier("DotNetCalls", ref DotNetCalls, "Turns on per-call .NET profiling.");
            parser.DefineOptionalQualifier("DotNetCallsSampled", ref DotNetCallsSampled, "Turns on per-call .NET profiling, sampling types in a smart way to keep overhead low.");
            parser.DefineOptionalQualifier("DisableInlining", ref DisableInlining, "Turns off inlining (but only affects processes that start after trace start.");
            parser.DefineOptionalQualifier("JITInlining", ref JITInlining, "Turns on logging of successful and failed JIT inlining attempts.");
            parser.DefineOptionalQualifier("CCWRefCount", ref CCWRefCount, "Turns on logging of information about .NET Native CCW reference counting.");
            parser.DefineOptionalQualifier("OSHeapProcess", ref OSHeapProcess, "Turn on per-allocation profiling of allocation from the OS heap for the process with the given process ID.");
            parser.DefineOptionalQualifier("OSHeapExe", ref OSHeapExe, "Turn on per-allocation profiling of allocation from the OS heap for the process with the given EXE (only filename WITH extension).");

            parser.DefineOptionalQualifier("NetworkCapture", ref NetworkCapture, "Captures the full data of every network packet entering or leaving the OS.");
            parser.DefineOptionalQualifier("NetMonCapture", ref NetMonCapture, "Create _netmon.etl file that NetMon.exe can read, along with the standard ETL file.   Implies /NetworkCapture.");

            parser.DefineOptionalQualifier("ForceNgenRundown", ref ForceNgenRundown,
                                           "By default on a V4.0 runtime NGEN rundown is suppressed, because NGEN PDB are a less expensive way of getting symbolic " +
                                           "information for NGEN images.  This option forces NGEN rundown, so NGEN PDBs are not needed.  This can be useful " +
                                           "in some scenarios where NGEN PDB are not working properly.");
            parser.DefineOptionalQualifier("NoV2Rundown", ref NoV2Rundown,
                                           "Don't do rundown for .NET (CLR) V2 processes.");
            parser.DefineOptionalQualifier("TrustPdbs", ref TrustPdbs, "Normally PerfView does not trust PDBs outside the _NT_SYMBOL_PATH and pops a dialog box.  Suppress this.");
            parser.DefineOptionalQualifier("AcceptEULA", ref AcceptEULA, "Accepts the EULA associated with PerfView.");
            parser.DefineOptionalQualifier("DataFile", ref DataFile,
                                           "FileName of the profile data to generate.");
            parser.DefineOptionalQualifier("NoView", ref NoView,
                                           "Normally after collecting data the data is viewed.  This suppresses that.");
            parser.DefineOptionalQualifier("UnsafePDBMatch", ref UnsafePDBMatch,
                                           "Allow the use of PDBs even when the trace does not contain PDB signatures.");
            parser.DefineOptionalQualifier("ShowUnknownAddresses", ref ShowUnknownAddresses,
                                           "Displays the hexadecimal address rather than ? when the address is unknown.");
            parser.DefineOptionalQualifier("NoGui", ref NoGui,
                                           "Use the Command line version of the command (like on ARM).  Brings up a console window.  For batch scripts/automation use /LogFile instead (see users guide under 'Scripting' for more).");
            parser.DefineOptionalQualifier("SafeMode", ref SafeMode, "Turn off parallelism and other risky features.");
            parser.DefineOptionalQualifier("RestartingToElevelate", ref RestartingToElevelate, "Internal: indicates that perfView is restarting to get Admin privileges.");

            // TODO FIX NOW this is a hack, does not handle kernel mode ...
            parser.DefineOptionalQualifier("SessionName", ref CommandProcessor.s_UserModeSessionName, "Define the name for the user mode session, if kernel events are off.");

            parser.DefineOptionalQualifier("MaxNodeCountK", ref MaxNodeCountK,
                                           "The maximum number of objects (in K or thousands) that will even be examined when dumping the heap.  Avoids memory use at collection time.  " +
                                           "This is useful if heap dumping causes out of memory exceptions.");


            /* end of qualifier that apply to more than one parameter set (command) */
            /****************************************************************************************/
            /* Parameter set (command) definitions */
            parser.DefineParameterSet("run", ref DoCommand, App.CommandProcessor.Run,
                                      "Starts data collection, runs a command and stops.");
            parser.DefineParameter("CommandAndArgs", ref CommandAndArgs,
                                   "Command to run and arguments (PerfView options must come before run command).");

            parser.DefineParameterSet("collect", ref DoCommand, App.CommandProcessor.Collect,
                                      "Starts data collection, wait for user input, then stops.");
            parser.DefineOptionalParameter("DataFile", ref DataFile,
                                           "ETL file containing profile data.");

            parser.DefineParameterSet("start", ref DoCommand, App.CommandProcessor.Start,
                                      "Starts machine wide profile data collection.");
            parser.DefineOptionalParameter("DataFile", ref DataFile, "ETL file containing profile data.");

            parser.DefineParameterSet("stop", ref DoCommand, App.CommandProcessor.Stop,
                                      "Stop collecting profile data (machine wide).  If you specified EventSources with the /Providers qualifier on start you should repeat them here to insure manifest rundown.");

            parser.DefineParameterSet("mark", ref DoCommand, App.CommandProcessor.Mark,
                                      "Add a PerfView 'Mark' event to the event stream with a optional string message");
            parser.DefineOptionalParameter("Message", ref Message, "The string message to attach to the PerfView Mark event.");

            parser.DefineParameterSet("abort", ref DoCommand, App.CommandProcessor.Abort,
                                      "Insures that any active PerfView sessions are stopped.");

            parser.DefineParameterSet("merge", ref DoCommand, App.CommandProcessor.Merge,
                                      "Combine separate ETL files into a single ETL file (that can be decoded on another machine).");
            parser.DefineOptionalParameter("DataFile", ref DataFile, "ETL file containing profile data.");

            parser.DefineParameterSet("unzip", ref DoCommand, App.CommandProcessor.Unzip,
                                      "Unpack a ZIP file into its ETL file (and possibly its NGEN PDBS) /WPR option can be specified.");
            parser.DefineOptionalParameter("DataFile", ref DataFile, "ETL file containing profile data.");

            parser.DefineParameterSet("listSessions", ref DoCommand, App.CommandProcessor.ListSessions,
                                      "Lists active ETW sessions.");

            parser.DefineParameterSet("ListCpuCounters", ref DoCommand, App.CommandProcessor.ListCpuCounters,
                                      "Lists the ListCpuCounters CPU counters available on the system (win8+ only).");

            parser.DefineParameterSet("EnableKernelStacks", ref DoCommand, App.CommandProcessor.EnableKernelStacks,
                                      "On X64 machines if you have problems with broken stacks when the code is executing in the kernel," +
                                      " setting this option and rebooting may improve things");

            parser.DefineParameterSet("DisableKernelStacks", ref DoCommand, App.CommandProcessor.DisableKernelStacks,
                                      "Resets the registry keys set by EnableKernelStack.");

            string ProcessParam = null;

            parser.DefineParameterSet("HeapSnapshot", ref DoCommand, App.CommandProcessor.HeapSnapshot,
                                      "Take a snapshot of the CLR GC heap of a process.");
            parser.DefineParameter("Process", ref ProcessParam, "The process ID or Process Name (Exe without extension) of the process  take a heap snapshot.");
            parser.DefineOptionalParameter("DataFile", ref DataFile, "The name of the file to place the heap snapshot.");
            parser.DefineOptionalQualifier("SaveETL", ref SaveETL, "Save an ETL file along with the GCDump file when dumping the JS Heap.");
            parser.DefineOptionalQualifier("MaxDumpCountK", ref MaxDumpCountK,
                                           "The maximum number of objects (in K or thousands) to place int the .gcDump file.   Sample sufficiently to hit this metric.");
            parser.DefineOptionalQualifier("Freeze", ref Freeze, "Freeze the dump while data is taken.");

            parser.DefineParameterSet("ForceGC", ref DoCommand, App.CommandProcessor.ForceGC,
                                      "Forces a GC on the specified process");
            parser.DefineParameter("Process", ref ProcessParam, "The process ID or Process Name (Exe without extension) of the process to force a GC.");

            // We have both a qualifier and a parameter named Process. It is OK that they use the same variable, but the parameter should not
            // overwrite the qualifier if it is null.
            if (ProcessParam != null)
            {
                Process = ProcessParam;
            }

            parser.DefineParameterSet("HeapSnapshotFromProcessDump", ref DoCommand, App.CommandProcessor.HeapSnapshotFromProcessDump,
                                      "Extract the CLR GC heap from a process dump file specified.");
            parser.DefineParameter("ProcessDumpFile", ref ProcessDumpFile, "The name of the input process dump file.");
            parser.DefineOptionalParameter("DataFile", ref DataFile, "The name of the file to place the heap snapshot.");
            // TODO FIX NOW parser.DefineOptionalQualifier("DumpData", ref DumpData, "Dump the data as well as the connectivity information.");

            parser.DefineParameterSet("GuiRun", ref DoCommand, App.CommandProcessor.GuiRun, "Opens the 'Run' dialog box.");
            parser.DefineParameterSet("GuiCollect", ref DoCommand, App.CommandProcessor.GuiCollect, "Opens the 'Collect' dialog box.");
            parser.DefineParameterSet("GuiHeapSnapshot", ref DoCommand, App.CommandProcessor.GuiHeapSnapshot,
                                      "Opens the 'TakeHeapSnapshot' dialog box.");

            parser.DefineParameterSet("UserCommand", ref DoCommand, App.CommandProcessor.UserCommand,
                                      "Runs a user defined command.  Type 'PerfView UserCommandHelp' to see the help for all the user commands. " +
                                      "See PerfView Extensions in the users guide for more on creating user commands.");
            parser.DefineParameter("CommandAndArgs", ref CommandAndArgs, "User command to run and any arguments.");

            parser.DefineParameterSet("UserCommandHelp", ref DoCommand, App.CommandProcessor.UserCommandHelp,
                                      "Displays help for user commands.  Also see Help->User Command Help in the GUI.");

            parser.DefineParameterSet("CreateExtensionProject", ref DoCommand, App.CommandProcessor.CreateExtensionProject,
                                      "Creates a VS project for creates a perfView extension.");
            parser.DefineOptionalParameter("ExtensionName", ref ExtensionName, "The name of the extension (no .DLL)");

#if CROSS_GENERATION_LIVENESS
            parser.DefineParameterSet("CollectCrossGenerationLiveness", ref DoCommand, App.CommandProcessor.CollectCrossGenerationLiveness,
                                      "Collect a heap snapshot that can be used to do cross-generation liveness analysis.");
            parser.DefineQualifier("PID", ref CGL_PID, "The process ID of the process to snapshot.");
            parser.DefineQualifier("Generation", ref CGL_Generation, "The generation of the GC to collect.");
            parser.DefineQualifier("PromotedBytesThreshold", ref CGL_PromotedBytesThreshold, "The threshold of promoted bytes after which a snapshot of the heap should be collected.");
            parser.DefineQualifier("OutputFile", ref CGL_PathToOutputFile, "The full path including filename where the resulting gcdump file should be stored.");
#endif

            parser.DefineDefaultParameterSet(ref DoCommand, App.CommandProcessor.View, "View profile data.");
            parser.DefineOptionalParameter("DataFile", ref DataFile, "ETL or ETLX file containing profile data.");
        }
 public bool ShouldTraceToTraceSource(TraceEventLevel level)
 {
     return ShouldTrace(TraceLevelHelper.GetTraceEventType(level));
 }
Exemple #37
0
        private static System.Diagnostics.Eventing.EventDescriptor GetEventDescriptor(int eventId, TraceChannel channel, TraceEventLevel traceEventLevel)
        {
            long keywords = 0L;

            if (channel == TraceChannel.Admin)
            {
                keywords |= -9223372036854775808L;
            }
            else if (channel == TraceChannel.Operational)
            {
                keywords |= 0x4000000000000000L;
            }
            else if (channel == TraceChannel.Analytic)
            {
                keywords |= 0x2000000000000000L;
            }
            else if (channel == TraceChannel.Debug)
            {
                keywords |= 0x100000000000000L;
            }
            else if (channel == TraceChannel.Perf)
            {
                keywords |= 0x800000000000000L;
            }
            return(new System.Diagnostics.Eventing.EventDescriptor(eventId, 0, (byte)channel, (byte)traceEventLevel, 0, 0, keywords));
        }
 public bool ShouldTraceToEtw(TraceEventLevel level)
 {
     return (this.EtwProvider != null && this.EtwProvider.IsEnabled((byte)level, 0));
 }
Exemple #39
0
 public bool ShouldTraceToEtw(TraceEventLevel level)
 {
     return((this.EtwProvider != null) && this.EtwProvider.IsEnabled((byte)level, 0L));
 }
 static EventDescriptor GetEventDescriptor(int eventId, TraceChannel channel, TraceEventLevel traceEventLevel)
 {
     unchecked
     {
         //map channel to keywords
         long keyword = (long)0x0;
         if (channel == TraceChannel.Admin)
         {
             keyword = keyword | (long)0x8000000000000000;
         }
         else if (channel == TraceChannel.Operational)
         {
             keyword = keyword | 0x4000000000000000;
         }
         else if (channel == TraceChannel.Analytic)
         {
             keyword = keyword | 0x2000000000000000;
         }
         else if (channel == TraceChannel.Debug)
         {
             keyword = keyword | 0x100000000000000;
         }
         else if (channel == TraceChannel.Perf)
         {
             keyword = keyword | 0x0800000000000000;
         }
         return new EventDescriptor(eventId, 0x0, (byte)channel, (byte)traceEventLevel, 0x0, 0x0, (long)keyword);
     }
 }
 public virtual bool ShouldTrace(TraceEventLevel level)
 {
     return(this.ShouldTraceToTraceSource(level));
 }