public void MonitorGarbageCollections()
        {
            string[] compactingGcTags = { "compacting_gc:true" };

            var statsd = new Mock <IDogStatsd>();

            var mutex = new ManualResetEventSlim();

            // GcPauseTime is pushed on the GcRestartEnd event, which should be the last event for any GC
            statsd.Setup(s => s.Timer(MetricsNames.GcPauseTime, It.IsAny <double>(), It.IsAny <double>(), null))
            .Callback(() => mutex.Set());

            using var listener = new RuntimeEventListener(statsd.Object);

            statsd.ResetCalls();

            for (int i = 0; i < 3; i++)
            {
                mutex.Reset(); // In case a GC was triggered when creating the listener

                GC.Collect(2, GCCollectionMode.Forced, blocking: true, compacting: true);

                // GC events are pushed asynchronously, wait for the last one to be processed
                mutex.Wait();
            }

            statsd.Verify(s => s.Gauge(MetricsNames.Gen0HeapSize, It.IsAny <ulong>(), It.IsAny <double>(), null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.Gen1HeapSize, It.IsAny <ulong>(), It.IsAny <double>(), null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.Gen2HeapSize, It.IsAny <ulong>(), It.IsAny <double>(), null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.LohSize, It.IsAny <ulong>(), It.IsAny <double>(), null), Times.AtLeastOnce);
            statsd.Verify(s => s.Timer(MetricsNames.GcPauseTime, It.IsAny <double>(), It.IsAny <double>(), null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.GcMemoryLoad, It.IsAny <uint>(), It.IsAny <double>(), null), Times.AtLeastOnce);
            statsd.Verify(s => s.Increment(MetricsNames.Gen2CollectionsCount, 1, It.IsAny <double>(), compactingGcTags), Times.AtLeastOnce);
        }
        public void PushEvents()
        {
            var statsd = new Mock <IDogStatsd>();

            using var listener = new RuntimeEventListener(statsd.Object);

            listener.Refresh();

            statsd.Verify(s => s.Gauge(MetricsNames.ContentionTime, It.IsAny <double>(), 1, null), Times.Once);
            statsd.Verify(s => s.Counter(MetricsNames.ContentionCount, It.IsAny <long>(), 1, null), Times.Once);
            statsd.Verify(s => s.Gauge(MetricsNames.ThreadPoolWorkersCount, It.IsAny <int>(), 1, null), Times.Once);
        }
Beispiel #3
0
        public void PushEventCounters()
        {
            // Pretending we're aspnetcore
            var eventSource = new EventSource("Microsoft.AspNetCore.Hosting");

            var mutex = new ManualResetEventSlim();

            Func <double> callback = () =>
            {
                mutex.Set();
                return(0.0);
            };

            var counters = new List <DiagnosticCounter>
            {
                new PollingCounter("current-requests", eventSource, () => 1.0),
                new PollingCounter("failed-requests", eventSource, () => 2.0),
                new PollingCounter("total-requests", eventSource, () => 4.0),
                new PollingCounter("request-queue-length", eventSource, () => 8.0),
                new PollingCounter("connection-queue-length", eventSource, () => 16.0),
                new PollingCounter("total-connections", eventSource, () => 32.0),

                // This counter sets the mutex, so it needs to be created last
                new PollingCounter("Dummy", eventSource, callback)
            };

            var statsd = new Mock <IDogStatsd>();

            using var listener = new RuntimeEventListener(statsd.Object, TimeSpan.FromSeconds(1));

            // Wait for the counters to be refreshed
            mutex.Wait();

#if NETCOREAPP3_1
            // Reduce the probability of a crash on .NET Core 3.1.9/3.1.10: https://github.com/dotnet/coreclr/pull/28112/
            // The crash happens if disposing counters while they're being refreshed.
            // Since the mutex is set when refreshing the counters, there's a high probability for the disposing to occur concurrently.
            // The small pause should help de-syncing the two operations.
            Thread.Sleep(100);
#endif

            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreCurrentRequests, 1.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreFailedRequests, 2.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreTotalRequests, 4.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreRequestQueueLength, 8.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreConnectionQueueLength, 16.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreTotalConnections, 32.0, 1, null), Times.AtLeastOnce);

            foreach (var counter in counters)
            {
                counter.Dispose();
            }
        }
Beispiel #4
0
        public void PushEventCounters()
        {
            // Pretending we're aspnetcore
            var eventSource = new EventSource("Microsoft.AspNetCore.Hosting");

            var mutex = new ManualResetEventSlim();

            Func <double> callback = () =>
            {
                mutex.Set();
                return(0.0);
            };

            var counters = new List <DiagnosticCounter>
            {
                new PollingCounter("current-requests", eventSource, () => 1.0),
                new PollingCounter("failed-requests", eventSource, () => 2.0),
                new PollingCounter("total-requests", eventSource, () => 4.0),
                new PollingCounter("request-queue-length", eventSource, () => 8.0),
                new PollingCounter("connection-queue-length", eventSource, () => 16.0),
                new PollingCounter("total-connections", eventSource, () => 32.0),

                // This counter sets the mutex, so it needs to be created last
                new PollingCounter("Dummy", eventSource, callback)
            };

            var statsd = new Mock <IDogStatsd>();

            using var listener = new RuntimeEventListener(statsd.Object, TimeSpan.FromSeconds(1));

            // Wait for the counters to be refreshed
            mutex.Wait();

            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreCurrentRequests, 1.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreFailedRequests, 2.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreTotalRequests, 4.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreRequestQueueLength, 8.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreConnectionQueueLength, 16.0, 1, null), Times.AtLeastOnce);
            statsd.Verify(s => s.Gauge(MetricsNames.AspNetCoreTotalConnections, 32.0, 1, null), Times.AtLeastOnce);

            foreach (var counter in counters)
            {
                counter.Dispose();
            }
        }
Beispiel #5
0
        static void Main(string[] args)
        {
            Options options = null;
            RuntimeEventListener eventListener = null;

            Parser.Default.ParseArguments <Options>(args)
            .WithParsed(_options =>
            {
                options = _options;
            });

            if (options == null)
            {
                return;
            }
            if (options.Verbose)
            {
                eventListener = new RuntimeEventListener();
            }

            IPAddress  address  = IPAddress.Parse(options.Address);
            IPEndPoint endpoint = new IPEndPoint(address, options.Port);

            switch (options.testType)
            {
            case TestType.Pipeline:
            {
                PipeEchoServer server = new PipeEchoServer();
                server.Listen(endpoint, listenBacklog: 5000);
            }
            break;

            case TestType.TcpSocket:
            {
                TcpEchoServer server = new TcpEchoServer();
                server.Listen(endpoint, 5000);
            }
            break;
            }

            Console.WriteLine("enter return to exit");
            Console.ReadLine();
        }
Beispiel #6
0
        static void Main(string[] args)
        {
            Options options = null;

            RuntimeEventListener listener = null;

            Parser.Default.ParseArguments <Options>(args)
            .WithParsed(_options =>
            {
                options = _options;
            });


            if (options == null)
            {
                return;
            }

            if (options.Verbose)
            {
                listener = new RuntimeEventListener();
            }

            EchoClient[] clients   = new EchoClient[options.Clients];
            Task[]       echoTasks = new Task[options.Clients];

            Random r = new Random();

            byte[] payload = new byte[options.Payload];
            r.NextBytes(payload);

            IPAddress address  = IPAddress.Parse(options.Address);
            EndPoint  endpoint = new IPEndPoint(address, options.Port);

            if (options.WarnupRound > 0)
            {
                Task[] warnupTask = new Task[options.WarnupRound];
                for (int i = 0; i < options.WarnupRound; i++)
                {
                    EchoClient client = new EchoClient(endpoint, options.Rounds, payload);
                    warnupTask[i] = client.Start(options.TransportType);
                }
                Task.WaitAll(warnupTask);
            }

            for (int i = 0; i < options.Clients; i++)
            {
                clients[i] = new EchoClient(endpoint, options.Rounds, payload);
            }

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            if (listener != null)
            {
                listener.ThreadPoolWorkerThreadWait += () =>
                {
                    Console.WriteLine("==============> eq:{0} dq:{1} cnnBegin:{2} cnnFinish:{3} writeBegin:{4} writeFinish:{5} readFinish{6} {7}ms",
                                      Interlocked.Read(ref RuntimeEventListener.s_enqueueCnt),
                                      Interlocked.Read(ref RuntimeEventListener.s_dequeueCnt),
                                      Interlocked.Read(ref EchoClient.s_connectBeginCnt),
                                      Interlocked.Read(ref EchoClient.s_connectFinishCnt),
                                      Interlocked.Read(ref EchoClient.s_writeBeginCnt),
                                      Interlocked.Read(ref EchoClient.s_writeBeginCnt),
                                      Interlocked.Read(ref EchoClient.s_readFinishCnt),
                                      stopwatch.ElapsedMilliseconds
                                      );
                };
            }

            for (int i = 0; i < options.Clients; i++)
            {
                echoTasks[i] = clients[i].Start(options.TransportType);
            }
            Task.WaitAll(echoTasks);
            stopwatch.Stop();

            int errorNum = 0;

            foreach (EchoClient cli in clients)
            {
                if (cli.Error != null)
                {
                    errorNum++;
                }
            }

            Console.WriteLine($"{options.Clients} clients, payload {options.Payload} bytes, {options.Rounds} rounds");
            Console.WriteLine("Total Time Elapsed: {0} Milliseconds", stopwatch.Elapsed.TotalMilliseconds);
            Console.WriteLine("{0} error of {1}", errorNum, options.Clients);

            double[] connect = clients.Where(cli => cli.Error == null).Select(cli => cli.ConnectDuration.TotalMilliseconds).ToArray();
            double[] echo    = clients.Where(cli => cli.Error == null).Select(cli => cli.EchoDuration.TotalMilliseconds).ToArray();
            double[] total   = clients.Where(cli => cli.Error == null).Select(cli => cli.ConnectDuration.TotalMilliseconds + cli.EchoDuration.TotalMilliseconds).ToArray();

            Console.WriteLine("connect\tp90:{0:N2}ms\tp95:{1:N2}ms\tp99:{2:N2}ms\tp99.9:{3:N2}ms",
                              Percentile(connect, 0.9),
                              Percentile(connect, 0.95),
                              Percentile(connect, 0.99),
                              Percentile(connect, 0.999));

            Console.WriteLine("echo\tp90:{0:N2}ms\tp95:{1:N2}ms\tp99:{2:N2}ms\tp99.9:{3:N2}ms",
                              Percentile(echo, 0.9),
                              Percentile(echo, 0.95),
                              Percentile(echo, 0.99),
                              Percentile(echo, 0.999));

            Console.WriteLine("total\tp90:{0:N2}ms\tp95:{1:N2}ms\tp99:{2:N2}ms\tp99.9:{3:N2}ms",
                              Percentile(total, 0.9),
                              Percentile(total, 0.95),
                              Percentile(total, 0.99),
                              Percentile(total, 0.999));

            Console.WriteLine("==============> eq:{0} dq:{1} cnnBegin:{2} cnnFinish:{3} writeBegin:{4} writeFinish:{5} readFinish{6} {7}ms",
                              Interlocked.Read(ref RuntimeEventListener.s_enqueueCnt),
                              Interlocked.Read(ref RuntimeEventListener.s_dequeueCnt),
                              Interlocked.Read(ref EchoClient.s_connectBeginCnt),
                              Interlocked.Read(ref EchoClient.s_connectFinishCnt),
                              Interlocked.Read(ref EchoClient.s_writeBeginCnt),
                              Interlocked.Read(ref EchoClient.s_writeBeginCnt),
                              Interlocked.Read(ref EchoClient.s_readFinishCnt),
                              stopwatch.ElapsedMilliseconds
                              );
        }