public void Run() { var monitoredAppPools = ConfigTools.GetConfiguredAppPools(); var monitoredApps = ConfigTools.GetConfiguredApps(); var console = Boolean.Parse(ConfigurationManager.AppSettings["ConsoleOutput"]); var api = Boolean.Parse(ConfigurationManager.AppSettings["APIOutput"]); if (TraceEventSession.IsElevated() != true) { Console.WriteLine("Must be elevated (Admin) to run this method."); Debugger.Break(); return; } try { var appPoolNames = IISAdminTools.GetApplicationPools(); foreach (var appPoolName in appPoolNames) { appPools.Add(appPoolName, IISAdminTools.GetAppPoolProcesses(appPoolName)); } } catch (Exception ex) { if (ex.Message.Contains("not registered")) { Console.WriteLine("Could not initialize; IIS isn't installed upon this machine."); } Debugger.Break(); } //var monitoringTimeSec = 60; //Console.WriteLine("The monitor will run for a maximum of {0} seconds", monitoringTimeSec); //Console.WriteLine("Press Ctrl-C to stop monitoring of GC Allocs"); // create a real time user mode session using (var userSession = new TraceEventSession("ObserveGCAllocs")) { // Set up Ctrl-C to stop the session SetupCtrlCHandler(() => { userSession.Stop(); }); // enable the CLR provider with default keywords (minus the rundown CLR events) userSession.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose, (ulong)(ClrTraceEventParser.Keywords.GC)); // Create a stream of GC Allocation events (happens every time 100K of allocations happen) IObservable <GCAllocationTickTraceData> gcAllocStream = userSession.Source.Clr.Observe <GCAllocationTickTraceData>(); // Print the outgoing stream to the console //gcAllocStream.Subscribe(allocData => //{ // if (GetProcessName(allocData.ProcessID) == "devenv") // { // //Out.WriteLine("GC Alloc : Proc: {0,10}({1,3}) Amount: {2,6:f1}K TypeSample: {3}", GetProcessName(allocData.ProcessID), GetProcessCPU(allocData.ProcessID), allocData.AllocationAmount / 1000.0, allocData.TypeName); // } //}); // Create a stream of GC Collection events IObservable <GCHeapStatsTraceData> gcCollectStream = userSession.Source.Clr.Observe <GCHeapStatsTraceData>(); // Print the outgoing stream to the console gcCollectStream.Subscribe(collectData => { var appName = GetProcessName(collectData.ProcessID); var metricsList = new List <MetricPackage>(); if (DEBUG_LEVEL == "DEBUG") { Out.WriteLine("Application Name : {0} is reporting in..", appName); } if (DoesProcessIdExist(collectData.ProcessID)) { var appPoolName = GetAppPoolName(collectData.ProcessID); if (DEBUG_LEVEL == "DEBUG") { Out.WriteLine("App Pool Name : {0}", appPoolName); } if (monitoredAppPools.Contains(appPoolName)) { int pid = collectData.ProcessID; Process toMonitor = Process.GetProcessById(pid); int threadCt = toMonitor.Threads.Count; long memoryUsed = toMonitor.WorkingSet64; long memoryCommitted = toMonitor.PeakWorkingSet64; var machineName = System.Environment.MachineName; if (api) { metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appPoolName, "Memory Heap - Gen 0 Usage"), collectData.GenerationSize0)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appPoolName, "Memory Heap - Gen 1 Usage"), collectData.GenerationSize1)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appPoolName, "Memory Heap - Gen 2 Usage"), collectData.GenerationSize2)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appPoolName, "Large Object Heap - Current Usage"), collectData.GenerationSize3)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|Usage Metrics|{2}", machineName, appPoolName, "Current Usage"), memoryUsed)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|Usage Metrics|{2}", machineName, appPoolName, "Current Committed"), memoryCommitted)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|Usage Metrics|{2}", machineName, appPoolName, "Thread Count"), threadCt)); } if (console) { Out.WriteLine("name = Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appPoolName, "Memory Heap - Gen 0 Usage", collectData.GenerationSize0); Out.WriteLine("name = Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appPoolName, "Memory Heap - Gen 1 Usage", collectData.GenerationSize1); Out.WriteLine("name = Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appPoolName, "Memory Heap - Gen 2 Usage", collectData.GenerationSize2); Out.WriteLine("name = Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appPoolName, "Large Object Heap - Current Usage", collectData.GenerationSize3); Out.WriteLine("name = Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appPoolName, "Current Usage", memoryUsed); Out.WriteLine("name = Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appPoolName, "Current Committed", memoryCommitted); Out.WriteLine("name = Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appPoolName, "Thread Count", threadCt); } } } else if (monitoredApps.Contains(appName)) { { var machineName = System.Environment.MachineName; int pid = collectData.ProcessID; Process toMonitor = Process.GetProcessById(pid); long memoryUsed = toMonitor.WorkingSet64; long memoryCommitted = toMonitor.PeakWorkingSet64; if (api) { metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appName, "Memory Heap - Gen 0 Usage"), collectData.GenerationSize0)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appName, "Memory Heap - Gen 1 Usage"), collectData.GenerationSize1)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appName, "Memory Heap - Gen 2 Usage"), collectData.GenerationSize2)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}", machineName, appName, "Large Object Heap - Current Usage"), collectData.GenerationSize3)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|Usage Metrics|{2}", machineName, appName, "Current Usage"), memoryUsed)); metricsList.Add(CreateMetricPackage(string.Format("Custom Metrics|Memory|Nodes|{0}|{1}|Usage Metrics|{2}", machineName, appName, "Current Committed"), memoryCommitted)); } if (console) { Out.WriteLine("name=Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appName, "Memory Heap - Gen 0 Usage", collectData.GenerationSize0); Out.WriteLine("name=Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appName, "Memory Heap - Gen 1 Usage", collectData.GenerationSize1); Out.WriteLine("name=Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appName, "Memory Heap - Gen 2 Usage", collectData.GenerationSize2); Out.WriteLine("name=Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appName, "Large Object Heap - Current Usage", collectData.GenerationSize3); Out.WriteLine("name=Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appName, "Current Usage", memoryUsed); Out.WriteLine("name=Custom Metrics|Memory|Nodes|{0}|{1}|GC Metrics|{2}, value={3}", machineName, appName, "Current Committed", memoryCommitted); } } // Out.WriteLine("GC Collect: Proc: {0,10}({1,3}) Gen0: {2,6:f1}M Gen1: {3,6:f1}M Gen2: {4,6:f1}M LargeObj: {5,6:f1}M", // GetProcessName(collectData.ProcessID), // GetProcessCPU(collectData.ProcessID), // collectData.GenerationSize0 / 1000000.0, // collectData.GenerationSize1 / 1000000.0, // collectData.GenerationSize2 / 1000000.0, // collectData.GenerationSize3 / 1000000.0); } if (metricsList.Count > 0) { WriteLines(metricsList); } }); //IObservable<long> timer = Observable.Timer(new TimeSpan(0, 0, monitoringTimeSec)); //timer.Subscribe(delegate //{ // Console.WriteLine("Stopped after {0} sec", monitoringTimeSec); // userSession.Dispose(); //}); // OK we are all set up, time to listen for events and pass them to the observers. userSession.Source.Process(); } Console.WriteLine("Done with program."); }