Example #1
0
        public static bool TryStartNoGCRegion(long totalSize, Action actionWhenAllocatedMore)
        {
            _evListener = new GcEventListener(actionWhenAllocatedMore);
            var succeeded = GC.TryStartNoGCRegion(totalSize, disallowFullBlockingGC: false);

            _evListener.Start();

            return(succeeded);
        }
Example #2
0
        protected override void OnStop()
        {
            if (_listener == null)
            {
                throw new InvalidOperationException("Can't stop if not started");
            }

            _listener.Stop();
            _listener = null;
        }
Example #3
0
        public GcMetricsProvider(IApmLogger logger, bool collectGcCount = true, bool collectGcGen0Size = true, bool collectGcGen1Size = true,
                                 bool collectGcGen2Size = true, bool collectGcGen3Size = true, bool collectGcTime = true
                                 )
        {
            _collectGcCount    = collectGcCount;
            _collectGcTime     = collectGcTime;
            _collectGcGen0Size = collectGcGen0Size;
            _collectGcGen1Size = collectGcGen1Size;
            _collectGcGen2Size = collectGcGen2Size;
            _collectGcGen3Size = collectGcGen3Size;
            _logger            = logger.Scoped(DbgName);

            if (PlatformDetection.IsDotNetFullFramework)
            {
                try
                {
                    TraceEventSessionName = SessionNamePrefix + Guid.NewGuid();
                    _traceEventSession    = new TraceEventSession(TraceEventSessionName);
                    _currentProcessId     = Process.GetCurrentProcess().Id;

                    _traceEventSession.Source.NeedLoadedDotNetRuntimes();
                    _traceEventSession.EnableProvider(
                        ClrTraceEventParser.ProviderGuid,
                        TraceEventLevel.Informational,
                        (ulong)ClrTraceEventParser.Keywords.GC                         // garbage collector details
                        );

                    _traceEventSession.Source.AddCallbackOnProcessStart(process =>
                    {
                        process.AddCallbackOnDotNetRuntimeLoad(runtime =>
                        {
                            _traceLoadedDotNetRuntime = runtime;
                            runtime.GCEnd            += RuntimeGCEnd;
                        });
                    });

                    _traceEventSession.Source.Clr.GCHeapStats += ClrOnGCHeapStats;

                    _traceEventSessionTask = Task.Run(() =>
                    {
                        _traceEventSession.Source.Process();
                    });
                }
                catch (Exception e)
                {
                    _logger.Warning()?.LogException(e, "TraceEventSession initialization failed - GC metrics won't be collected");
                    return;
                }
            }

            if (PlatformDetection.IsDotNetCore || PlatformDetection.IsDotNet5)
            {
                _eventListener = new GcEventListener(this, logger);
            }
        }
Example #4
0
        protected override void OnStart()
        {
            if (_listener != null)
            {
                throw new InvalidOperationException("Already started");
            }

            _listener = new GcEventListener();

            _listener.GcEvents += OnGc;
            //WriteLine(Header);
        }
Example #5
0
        static void Main(string[] args)
        {
            GcEventListener.EnableAllocationEvents();
            new GcEventListener((ulong size, string type) => {
                Console.WriteLine($"[{type}]: {size} -- Allocated");
            }, (ulong gen0Size, ulong gen0Promoted, ulong gen1Size, ulong gen1Promoted, ulong gen2Size, ulong gen2Survived, ulong lohSize, ulong lohSurvived) => {
                Console.WriteLine($"[GC Event]: Gen0Size: {gen0Size}, Gen0Promoted: {gen0Promoted}, Gen1Size: {gen1Size}, Gen1Promoted: {gen1Promoted}, Gen2Size: {gen2Size}, Gen2Survived: {gen2Survived}, LOHSize: {lohSize}, LOHSurvived: {lohSurvived}");
            });

            int threadCount = 50;

            for (int i = 0; i < threadCount; ++i)
            {
                Task.Run(() => { Allocate(); });
            }

            Allocate();
        }
        public GcMetricsProvider(IApmLogger logger, bool collectGcCount = true, bool collectGcGen0Size = true, bool collectGcGen1Size = true,
                                 bool collectGcGen2Size = true, bool collectGcGen3Size = true
                                 )
        {
            _collectGcCount    = collectGcCount;
            _collectGcGen0Size = collectGcGen0Size;
            _collectGcGen1Size = collectGcGen1Size;
            _collectGcGen2Size = collectGcGen2Size;
            _collectGcGen3Size = collectGcGen3Size;

            _logger = logger.Scoped(nameof(SystemTotalCpuProvider));
            if (PlatformDetection.IsDotNetFullFramework)
            {
                TraceEventSessionName  = SessionNamePrefix + Guid.NewGuid();
                _traceEventSession     = new TraceEventSession(TraceEventSessionName);
                _currentProcessId      = Process.GetCurrentProcess().Id;
                _traceEventSessionTask = Task.Run(() =>
                {
                    try
                    {
                        _traceEventSession.EnableProvider(
                            ClrTraceEventParser.ProviderGuid,
                            TraceEventLevel.Informational,
                            (ulong)ClrTraceEventParser.Keywords.GC                             // garbage collector details
                            );
                    }
                    catch (Exception e)
                    {
                        _logger.Warning()?.LogException(e, "TraceEventSession initialization failed - GC metrics won't be collected");
                        return;
                    }

                    _traceEventSession.Source.Clr.GCStop      += ClrOnGCStop;
                    _traceEventSession.Source.Clr.GCHeapStats += ClrOnGCHeapStats;
                    _traceEventSession.Source.Process();
                });
            }

            if (PlatformDetection.IsDotNetCore || PlatformDetection.IsDotNet5)
            {
                _eventListener = new GcEventListener(this, logger);
            }
        }
 public Task StartAsync(CancellationToken cancellationToken)
 {
     _timer           = new System.Threading.Timer(CollectData, null, 0, _options.CollectIntervalMilliseconds);
     _gcEventListener = new GcEventListener(_metrics);
     return(Task.CompletedTask);
 }
Example #8
0
        public GcMetricsProvider(IApmLogger logger, bool collectGcCount = true, bool collectGcGen0Size = true, bool collectGcGen1Size = true,
                                 bool collectGcGen2Size = true, bool collectGcGen3Size = true
                                 )
        {
            _collectGcCount    = collectGcCount;
            _collectGcGen0Size = collectGcGen0Size;
            _collectGcGen1Size = collectGcGen1Size;
            _collectGcGen2Size = collectGcGen2Size;
            _collectGcGen3Size = collectGcGen3Size;

            _logger = logger.Scoped(nameof(SystemTotalCpuProvider));
            if (PlatformDetection.IsDotNetFullFramework)
            {
                var sessionName = SessionNamePrefix + Guid.NewGuid().ToString();
                using (_traceEventSession = new TraceEventSession(sessionName))
                {
                    Task.Run(() =>
                    {
                        try
                        {
                            _traceEventSession.EnableProvider(
                                ClrTraceEventParser.ProviderGuid,
                                TraceEventLevel.Verbose,
                                (ulong)
                                ClrTraceEventParser.Keywords.GC                                 // garbage collector details
                                );
                        }
                        catch (Exception e)
                        {
                            _logger.Warning()?.LogException(e, "TraceEventSession initialization failed - GC metrics won't be collected");
                            return;
                        }

                        var source = _traceEventSession.Source;
                        source.NeedLoadedDotNetRuntimes();
                        source.AddCallbackOnProcessStart((proc) =>
                        {
                            proc.AddCallbackOnDotNetRuntimeLoad((runtime) =>
                            {
                                runtime.GCEnd += (process, gc) =>
                                {
                                    _logger.Trace()
                                    ?.Log("GCEnd called");

                                    _gen0Size = (ulong)gc.HeapStats.GenerationSize0;
                                    _gen1Size = (ulong)gc.HeapStats.GenerationSize1;
                                    _gen2Size = (ulong)gc.HeapStats.GenerationSize2;
                                    _gen3Size = (ulong)gc.HeapStats.GenerationSize3;
                                    _gcCount  = (uint)runtime.GC.GCs.Count;
                                };
                            });
                        });

                        _traceEventSession.Source.Process();
                    });
                }
            }

            if (PlatformDetection.IsDotNetCore)
            {
                _eventListener = new GcEventListener(this, logger);
            }
        }
Example #9
0
        public GcMetricsProvider(IApmLogger logger, bool collectGcCount = true, bool collectGcGen0Size = true, bool collectGcGen1Size = true,
                                 bool collectGcGen2Size = true, bool collectGcGen3Size = true
                                 )
        {
            _collectGcCount    = collectGcCount;
            _collectGcGen0Size = collectGcGen0Size;
            _collectGcGen1Size = collectGcGen1Size;
            _collectGcGen2Size = collectGcGen2Size;
            _collectGcGen3Size = collectGcGen3Size;

            _logger = logger.Scoped(nameof(SystemTotalCpuProvider));
            if (PlatformDetection.IsDotNetFullFramework)
            {
                var sessionName = SessionNamePrefix + Guid.NewGuid();
                using (_traceEventSession = new TraceEventSession(sessionName))
                {
                    Task.Run(() =>
                    {
                        try
                        {
                            _traceEventSession.EnableProvider(
                                ClrTraceEventParser.ProviderGuid,
                                TraceEventLevel.Informational,
                                (ulong)
                                ClrTraceEventParser.Keywords.GC                                 // garbage collector details
                                );
                        }
                        catch (Exception e)
                        {
                            _logger.Warning()?.LogException(e, "TraceEventSession initialization failed - GC metrics won't be collected");
                            return;
                        }

                        _traceEventSession.Source.Clr.GCStop += (a) =>
                        {
                            if (a.ProcessID == Process.GetCurrentProcess().Id)
                            {
                                if (!_isMetricAlreadyCaptured)
                                {
                                    lock (_lock)
                                        _isMetricAlreadyCaptured = true;
                                }
                                _gcCount = (uint)a.Count;
                            }
                        };

                        _traceEventSession.Source.Clr.GCHeapStats += (a) =>
                        {
                            if (a.ProcessID == Process.GetCurrentProcess().Id)
                            {
                                if (!_isMetricAlreadyCaptured)
                                {
                                    lock (_lock)
                                        _isMetricAlreadyCaptured = true;
                                }
                                _gen0Size = (ulong)a.GenerationSize0;
                                _gen1Size = (ulong)a.GenerationSize1;
                                _gen2Size = (ulong)a.GenerationSize2;
                                _gen3Size = (ulong)a.GenerationSize3;
                            }
                        };

                        _traceEventSession.Source.Process();
                    });
                }
            }

            if (PlatformDetection.IsDotNetCore || PlatformDetection.IsDotNet5)
            {
                _eventListener = new GcEventListener(this, logger);
            }
        }
Example #10
0
        public GcMetricsProvider(IApmLogger logger, IReadOnlyList <WildcardMatcher> disabledMetrics)
        {
            _collectGcCount    = !WildcardMatcher.IsAnyMatch(disabledMetrics, GcCountName);
            _collectGcTime     = !WildcardMatcher.IsAnyMatch(disabledMetrics, GcTimeName);
            _collectGcGen0Size = !WildcardMatcher.IsAnyMatch(disabledMetrics, GcGen0SizeName);
            _collectGcGen1Size = !WildcardMatcher.IsAnyMatch(disabledMetrics, GcGen1SizeName);
            _collectGcGen2Size = !WildcardMatcher.IsAnyMatch(disabledMetrics, GcGen2SizeName);
            _collectGcGen3Size = !WildcardMatcher.IsAnyMatch(disabledMetrics, GcGen3SizeName);

            if (!IsEnabled(disabledMetrics))
            {
                return;
            }

            _logger = logger.Scoped(DbgName);

            if (PlatformDetection.IsDotNetFullFramework)
            {
                // if the OS doesn't support filtering, the processes and runtimes tracked by the trace event session source can grow
                // unbounded, leading to the application consuming ever more memory.
                if (!TraceEventProviderOptions.FilteringSupported)
                {
                    _logger.Info()?.Log("TraceEventSession does not support filtering on this operating system. GC metrics won't be collected");
                    return;
                }

                try
                {
                    TraceEventSessionName = SessionNamePrefix + Guid.NewGuid();
                    _traceEventSession    = new TraceEventSession(TraceEventSessionName);
                    _traceEventSession.Source.NeedLoadedDotNetRuntimes();
                    _traceEventSession.EnableProvider(
                        ClrTraceEventParser.ProviderGuid,
                        TraceEventLevel.Informational,
                        (ulong)ClrTraceEventParser.Keywords.GC,                         // garbage collector details
                        new TraceEventProviderOptions {
                        ProcessIDFilter = new List <int>(1)
                        {
                            Process.GetCurrentProcess().Id
                        }
                    }
                        );

                    _traceEventSession.Source.Clr.GCHeapStats += ClrOnGCHeapStats;
                    _traceEventSession.Source.AddCallbackOnProcessStart(process =>
                    {
                        process.AddCallbackOnDotNetRuntimeLoad(runtime =>
                        {
                            runtime.GCEnd += RuntimeGCEnd;
                        });
                    });

                    _traceEventSessionTask = Task.Run(() => _traceEventSession.Source.Process());
                }
                catch (Exception e)
                {
                    _logger.Warning()?.LogException(e, "TraceEventSession initialization failed - GC metrics won't be collected");
                    return;
                }
            }

            if (PlatformDetection.IsDotNetCore || PlatformDetection.IsDotNet)
            {
                _eventListener = new GcEventListener(this, logger);
            }
        }