예제 #1
1
        void ProcessData()
        {
            try
            {
                using (myRealtimeSession = new TraceEventSession("WMIWatcher_Realtime"))
                {
                    myRealtimeSession.EnableKernelProvider(KernelTraceEventParser.Keywords.ImageLoad | KernelTraceEventParser.Keywords.Process, KernelTraceEventParser.Keywords.None);
                    myRealtimeSession.EnableProvider(WMIProviderDefinitions.WMI_Activity_Provider_Name, TraceEventLevel.Verbose, WMIProviderDefinitions.Keyword_WMI_Activity_Trace);

                    using (myTraceLogSource = TraceLog.CreateFromTraceEventSession(myRealtimeSession))
                    {
                        WMIEventParser parser = new WMIEventParser(myTraceLogSource, "WmiWatcher", AutoLoggerFileName);
                        myTraceLogSource.Dynamic.All += parser.Parse;
                        parser.OnWMIOperationStart   += Parser_OnWMIOperationStart;
                        //parser.OnWMIOperationStop += Parser_OnWMIOperationStop;
                        parser.OnWMIExecAsync             += Parser_OnWMIExecAsync;
                        parser.OnProcessEndedWithDuration += Parser_OnProcessEndedWithDuration;

                        myTraceLogSource.Process();
                    }
                }
            }
            catch (Exception ex)
            {
                FileLogger.Logger.Log($"Error: Got Exception while leaving ProcessData: {ex}");
                throw;
            }
        }
        public async Task StartAsync()
        {
            if (Interlocked.CompareExchange(ref _started, 1, 0) == 1)
            {
                throw new InvalidOperationException("Impossible to start profiling more than once.");
            }

            await Task.Factory.StartNew(() =>
            {
                using (_session)
                {
                    SetupProviders(_session);

                    using (TraceLogEventSource source = TraceLog.CreateFromTraceEventSession(_session))
                    {
                        SetupListeners(source);

                        source.Process();
                    }
                }

                // dump the symbol related error messages if required
                if (_verbose)
                {
                    Console.WriteLine(_symbolLookupMessages.ToString());
                }
            });
        }
예제 #3
0
        protected override void Capture(TraceEventSession session)
        {
            session.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP, KernelTraceEventParser.Keywords.NetworkTCPIP);

            //TraceLogEventSource is required on win 7
            //see: https://github.com/Microsoft/dotnetsamples/blob/master/Microsoft.Diagnostics.Tracing/TraceEvent/TraceEvent/41_TraceLogMonitor.cs
            using (TraceLogEventSource traceLogSource = TraceLog.CreateFromTraceEventSession(session))
            {
                //two events in a row for same process and IP/port means failure.
                //It could be a firewall intervention, silently droping packets to that destination
                //or the end service is down.
                traceLogSource.Kernel.TcpIpReconnect += (TcpIpTraceData data) =>
                {
                    try
                    {
                        _sender.Send(data.ProcessID, data.daddr + ":" + data.dport, TCP_RECONNECT);
                    }
                    catch (Exception)
                    {
                        //TODO: log it
                        //TODO: check all Exceptions that can be thrown by the _sender instance.
                        throw;
                    }
                };

                traceLogSource.Kernel.TcpIpConnect += (TcpIpConnectTraceData data) =>
                {
                    try
                    {
                        _sender.Send(data.ProcessID, data.ToXml(new System.Text.StringBuilder()).ToString(), TCP_CONNECT);
                    }
                    catch (Exception)
                    {
                        //TODO: log it
                        //TODO: check all Exceptions that can be thrown by the _sender instance.
                        throw;
                    }
                };

                traceLogSource.Kernel.TcpIpDisconnect += (TcpIpTraceData data) =>
                {
                    try
                    {
                        _sender.Send(data.ProcessID, data.ToXml(new System.Text.StringBuilder()).ToString(), TCP_CONNECT);
                    }
                    catch (Exception)
                    {
                        //TODO: log it
                        //TODO: check all Exceptions that can be thrown by the _sender instance.
                        throw;
                    }
                };
                traceLogSource.Process();
            }
        }
예제 #4
0
        static void Main(string[] args)
        {
            using (var session = new TraceEventSession("MonitorKernelAndClrEventsSession"))
            {
                Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs cancelArgs) =>
                {
                    session.Dispose();
                    cancelArgs.Cancel = true;
                };

                //session.EnableKernelProvider(KernelTraceEventParser.Keywords.ImageLoad | KernelTraceEventParser.Keywords.Process | KernelTraceEventParser.Keywords.Thread);

                var optionsWithStacks = new TraceEventProviderOptions()
                {
                    StacksEnabled = true
                };
                //session.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (ulong)ClrTraceEventParser.Keywords.Default);
                //session.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (ulong)ClrTraceEventParser.Keywords.Exception, optionsWithStacks);

                //session.EnableProvider(ClrRundownTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (ulong)ClrRundownTraceEventParser.Keywords.Default);

                session.EnableProvider("Microsoft-Windows-TCPIP", TraceEventLevel.Verbose);
#if TRACELOG
                using (TraceLogEventSource traceLogSource = TraceLog.CreateFromTraceEventSession(session))
                {
                    traceLogSource.Clr.ExceptionStart += ClrOnExceptionStart;
                    traceLogSource.Process();
                }
#else
                session.Source.Clr.GCStart     += ClrOnGcStart;
                session.Source.Clr.GCStop      += ClrOnGcStop;
                session.Source.Clr.GCHeapStats += ClrOnGcHeapStats;

                session.Source.Dynamic.All += delegate(Microsoft.Diagnostics.Tracing.TraceEvent data)
                {
                    // ETW buffers events and only delivers them after buffering up for some amount of time.  Thus
                    // there is a small delay of about 2-4 seconds between the timestamp on the event (which is very
                    // accurate), and the time we actually get the event.  We measure that delay here.
                    var delay = (DateTime.Now - data.TimeStamp).TotalSeconds;
                    //Console.WriteLine("GOT Event Delay={0:f1}sec: {1}/{2} ", delay, data.ProviderName, data.EventName);
                };
                session.Source.Dynamic.AddCallbackForProviderEvent("Microsoft-Windows-TCPIP", "TcpSendTransmitted",
                                                                   data => Console.WriteLine($"PID {data.ProcessID} sent {data.PayloadByName("NumBytes")} B"));

                //session.Source.Kernel.ProcessStart += KernelOnProcessStart;
                //session.Source.Kernel.ProcessStop += KernelOnProcessStop;
                session.Source.Process();
#endif
            }
        }
예제 #5
0
        protected override bool OnStart()
        {
            if (_session != null)
            {
                throw new InvalidOperationException("Profiling session already started...");
            }

            string sessionName = "LiveCpu_Profiling_Session+" + Guid.NewGuid().ToString();

            _session = new TraceEventSession(sessionName, TraceEventSessionOptions.Create);
            if (!EnableProviders(_session))
            {
                _session.Dispose();
                _session = null;
                return(false);
            }

            _profilingTask = Task.Factory.StartNew(() =>
            {
                using (TraceLogEventSource source = TraceLog.CreateFromTraceEventSession(_session))
                {
                    // CPU sampling kernel events
                    source.Kernel.PerfInfoSample += (SampledProfileTraceData data) =>
                    {
                        if (data.ProcessID != Pid)
                        {
                            return;
                        }

                        var callstack = data.CallStack();
                        if (callstack == null)
                        {
                            return;
                        }

                        MergeCallStack(callstack, Reader);
                    };

                    // this call exits when the session is stopped
                    source.Process();
                }
            });

            return(true);
        }
        public async Task StartAsync()
        {
            if (Interlocked.CompareExchange(ref _started, 1, 0) == 1)
            {
                throw new InvalidOperationException("Impossible to start profiling more than once.");
            }

            await Task.Factory.StartNew(() =>
            {
                using (_session)
                {
                    SetupProviders(_session);

                    using (TraceLogEventSource source = TraceLog.CreateFromTraceEventSession(_session))
                    {
                        SetupListeners(source);

                        source.Process();
                    }
                }
            });
        }
        public static void Run()
        {
            var monitoringTimeSec = 10;

            Out.WriteLine("******************** RealTimeTraceLog DEMO (win8) ********************");
            Out.WriteLine("This program Shows how to use the real-time support in TraceLog");
            Out.WriteLine("We do this by showing how to monitor exceptions in real time ");
            Out.WriteLine();
            Out.WriteLine("This code depends on a Feature of Windows 8.1 (combined user and kernel sessions)");
            Out.WriteLine();
            Out.WriteLine("Note that this support is currently experimental and subject to change");
            Out.WriteLine();
            Out.WriteLine("Monitoring .NET Module load and Exception events (with stacks).");
            Out.WriteLine("Run some managed code (ideally that has exceptions) while the monitor is running.");
            Out.WriteLine();

            if (Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor < 62)
            {
                Out.WriteLine("This demo only works on Win8 / Win 2012 an above)");
                return;
            }

            TraceEventSession session = null;

            // Set up Ctrl-C to stop both user mode and kernel mode sessions
            Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs cancelArgs) =>
            {
                if (session != null)
                {
                    session.Dispose();
                }
                cancelArgs.Cancel = true;
            };

            // Cause an exception to be thrown a few seconds in (so we have something interesting to look at)
            var exceptionGeneationTask = Task.Factory.StartNew(delegate
            {
                Thread.Sleep(3000);
                ThrowException();
            });

            Timer timer = null;

            // Create the new session to receive the events.
            // Because we are on Win 8 this single session can handle both kernel and non-kernel providers.
            using (session = new TraceEventSession("TraceLogSession"))
            {
                // Enable the events we care about for the kernel
                // For this instant the session will buffer any incoming events.
                // Enabling kernel events must be done before anything else.
                // This will fail on Win7.
                //
                // Note that if you turn on the KernelTraceEventParser.Keywords.Profile, you can also get stacks for CPU sampling
                // (every millisecond).  (You can use the traceLogSource.Kernel.PerfInfoSample callback).
                Out.WriteLine("Enabling Image load, Process and Thread events.  These are needed to look up native method names.");
                session.EnableKernelProvider(
                    // KernelTraceEventParser.Keywords.Profile |            // If you want CPU sampling events
                    // KernelTraceEventParser.Keywords.ContextSwitch |      // If you want context switch events
                    // KernelTraceEventParser.Keywords.Thread |             // If you want context switch events you also need thread start events.
                    KernelTraceEventParser.Keywords.ImageLoad |
                    KernelTraceEventParser.Keywords.Process,   /****** The second parameter indicates which kernel events should have stacks *****/
                    // KernelTraceEventParser.Keywords.ImageLoad |          // If you want Stacks image load (load library) events
                    // KernelTraceEventParser.Keywords.Profile |            // If you want Stacks for CPU sampling events
                    // KernelTraceEventParser.Keywords.ContextSwitch |      // If you want Stacks for context switch events
                    KernelTraceEventParser.Keywords.None
                    );

                Out.WriteLine("Enabling CLR Exception and Load events (and stack for those events)");
                // We are monitoring exception events (with stacks) and module load events (with stacks)
                session.EnableProvider(
                    ClrTraceEventParser.ProviderGuid,
                    TraceEventLevel.Informational,
                    (ulong)(ClrTraceEventParser.Keywords.Jit |                       // Turning on JIT events is necessary to resolve JIT compiled code
                            ClrTraceEventParser.Keywords.JittedMethodILToNativeMap | // This is needed if you want line number information in the stacks
                            ClrTraceEventParser.Keywords.Loader |                    // You must include loader events as well to resolve JIT compiled code.
                            ClrTraceEventParser.Keywords.Exception |                 // We want to see the exception events.
                            ClrTraceEventParser.Keywords.Stack));                    // And stacks on all CLR events where it makes sense.

                // The CLR events turned on above will let you resolve JIT compiled code as long as the JIT compilation
                // happens AFTER the session has started.   To handle the case for JIT compiled code that was already
                // compiled we need to tell the CLR to dump 'Rundown' events for all existing JIT compiled code.  We
                // do that here.
                Out.WriteLine("Enabling CLR Events to 'catch up' on JIT compiled code in running processes.");
                session.EnableProvider(ClrRundownTraceEventParser.ProviderGuid, TraceEventLevel.Informational,
                                       (ulong)(ClrTraceEventParser.Keywords.Jit |                       // We need JIT events to be rundown to resolve method names
                                               ClrTraceEventParser.Keywords.JittedMethodILToNativeMap | // This is needed if you want line number information in the stacks
                                               ClrTraceEventParser.Keywords.Loader |                    // As well as the module load events.
                                               ClrTraceEventParser.Keywords.StartEnumeration));         // This indicates to do the rundown now (at enable time)

                // Because we care about symbols in native code or NGEN images, we need a SymbolReader to decode them.

                // There is a lot of messages associated with looking up symbols, but we don't want to clutter up
                // The output by default, so we save it to an internal buffer you can ToString in debug code.
                // A real app should make this available somehow to the user, because sooner or later you DO need it.
                TextWriter SymbolLookupMessages = new StringWriter();
                // TextWriter SymbolLookupMessages = Out;           // If you want the symbol debug spew to go to the output, use this.

                // By default a symbol Reader uses whatever is in the _NT_SYMBOL_PATH variable.  However you can override
                // if you wish by passing it to the SymbolReader constructor.  Since we want this to work even if you
                // have not set an _NT_SYMBOL_PATH, so we add the Microsoft default symbol server path to be sure/
                var          symbolPath   = new SymbolPath(SymbolPath.SymbolPathFromEnvironment).Add(SymbolPath.MicrosoftSymbolServerPath);
                SymbolReader symbolReader = new SymbolReader(SymbolLookupMessages, symbolPath.ToString());

                Out.WriteLine("Open a real time TraceLog session (which understands how to decode stacks).");
                using (TraceLogEventSource traceLogSource = TraceLog.CreateFromTraceEventSession(session))
                {
                    // We use this action in the particular callbacks below.  Basically we pass in a symbol reader so we can decode the stack.
                    // Often the symbol reader is a global variable instead.
                    Action <TraceEvent> PrintEvent = ((TraceEvent data) => Print(data, symbolReader));

                    // We will print Exceptions and ModuleLoad events. (with stacks).
                    traceLogSource.Clr.ExceptionStart   += PrintEvent;
                    traceLogSource.Clr.LoaderModuleLoad += PrintEvent;
                    // traceLogSource.Clr.All += PrintEvent;

                    // If you want to see stacks for various other kernel events, uncomment these (you also need to turn on the events above)
                    traceLogSource.Kernel.PerfInfoSample += ((SampledProfileTraceData data) => Print(data, symbolReader));
                    // traceLogSource.Kernel.ImageLoad += ((ImageLoadTraceData data) => Print(data, symbolReader));

                    // process events until Ctrl-C is pressed or timeout expires
                    Out.WriteLine("Waiting {0} sec for Events.  Run managed code to see data. ", monitoringTimeSec);
                    Out.WriteLine("Keep in mind there is a several second buffering delay");

                    // Set up a timer to stop processing after monitoringTimeSec
                    timer = new Timer(delegate(object state)
                    {
                        Out.WriteLine("Stopped Monitoring after {0} sec", monitoringTimeSec);
                        if (session != null)
                        {
                            session.Dispose();
                        }
                        session = null;
                    }, null, monitoringTimeSec * 1000, Timeout.Infinite);

                    traceLogSource.Process();
                }
            }
            Out.WriteLine("Finished");
            if (timer != null)
            {
                timer.Dispose();    // Turn off the timer.
            }
        }