コード例 #1
0
        public ActionResult <string> WatchingMethodWithExecutedCommands(uint value)
        {
            // create custom data (anonymous class)
            var testClass = new
            {
                TestInternalClass = new
                {
                    Key   = 1,
                    Value = "2"
                },
                Value = "3"
            };

            // method performance info will reach with HttpContextAccessor and custom data
            // custom "CustomDataCommand" will be executed after performance watching is completed (work with method calls custom data)
            using (PerformanceMeter <PerformanceMeterController>
                   .WatchingMethod(nameof(WatchingMethodWithExecutedCommands))
                   .WithSettingData
                   .CallerFrom(_httpContextAccessor)
                   .CallerSourceData()
                   .CustomData(nameof(value), value)
                   .CustomData(nameof(testClass), testClass)
                   .WithExecutingOnComplete
                   .Command(new CustomDataCommand())
                   .Command(new ExecutedCommand("bla-bla-bla"))
                   .Action((pi) =>
            {
                Debug.WriteLine($"Class name: {pi.ClassName}");
            })
                   .Start())
            {
                return(Ok($"{value}"));
            }
        }
        public ActionResult SimpleStartWatchingWithSteps()
        {
            //using var pm = PerformanceMeter<PerformanceMeterController>.StartWatching();
            using (var pm = PerformanceMeter <PerformanceMeterController>
                            .WatchingMethod()
                            .WithSettingData
                            .CustomData("coins", 1)
                            .CustomData("Coins sets", new
            {
                Gold = "Many",
                Silver = 5
            })
                            .Start())
            {
                // put your code with some logic here

                // add "Step 1"
                using (pm.Step("Step 1"))
                {
                    Thread.Sleep(1000);
                }

                // skip this step with minSavems (not save, but consider duration in method performance watching)
                using (pm.StepIf("Skipped step", minSaveMs: 100))
                {
                    Thread.Sleep(10);
                }

                // ignore this block in performance watching
                using (pm.Ignore())
                {
                    Thread.Sleep(5000);
                }

                // add "Step 2" with custom data
                using (var pmStep = pm.Step("Step 2").AddCustomData("step2 custom data", "data!"))
                {
                    // add "Step 3 in Step 2"
                    using (pm.Step("Step 3 in Step 2"))
                    {
                        Thread.Sleep(1000);
                    }

                    // execute action without performance watching
                    pm.Executing().WithoutWatching().Start(() => Thread.Sleep(2000));

                    // add custom data to "Step 2"
                    pmStep.AddCustomData("step2 another custom data", "data2!");

                    // get and remove custom data from "Step 2"
                    var customData = pmStep.GetAndRemoveCustomData <string>("step2 custom data");
                    Debug.WriteLine($"{customData}!!!");

                    // get custom data from "Step 2" (without removing)
                    var anotherCustomData = pmStep.GetCustomData <string>("step2 another custom data");
                }

                return(Ok());
            }
        }
コード例 #3
0
        public ActionResult SimpleWatchingMethodStart()
        {
            using var pm = PerformanceMeter <PerformanceMeterController> .WatchingMethod().Start();

            //put your code with some logic here

            return(Ok());
        }
        /// <summary>
        /// Executes the Unchase.FluentPerformanceMeter-wrapped middleware.
        /// </summary>
        /// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
        /// <returns>A task that represents the execution of the MiniProfiler-wrapped middleware.</returns>
        /// <exception cref="ArgumentNullException">Throws when <paramref name="context"/> is <c>null</c>.</exception>
        public async Task Invoke(HttpContext context)
        {
            _ = context ?? throw new ArgumentNullException(nameof(context));

            if (PerformanceMeterCommonMethods.ShouldWatching(context.Request, Options))
            {
                var controllerActionDescriptor = (context.Features[typeof(IEndpointFeature)] as IEndpointFeature)?.Endpoint?.Metadata?.GetMetadata <ControllerActionDescriptor>();
                if (controllerActionDescriptor != null)
                {
                    if (PerformanceMeterCommonMethods.CheckExcludedMethods(controllerActionDescriptor, Options))
                    {
                        await _next(context); // don't watching, only relay
                    }

                    if (PerformanceMeterCommonMethods.CheckAnnotatedAttribute(controllerActionDescriptor, Options,
                                                                              typeof(WatchingPerformanceAttribute)))
                    {
                        await _next(context); // don't watching, only relay
                    }

                    if (PerformanceMeterCommonMethods.CheckIgnoreMethodPerformanceAttribute(controllerActionDescriptor, Options))
                    {
                        await _next(context); // don't watching, only relay
                    }

                    if (controllerActionDescriptor.ControllerTypeInfo.UnderlyingSystemType != typeof(TClass))
                    {
                        await _next(context); // don't watching, only relay
                    }

                    var performanceMeterBuilder = PerformanceMeter <TClass>
                                                  .WatchingMethod(controllerActionDescriptor.ActionName)
                                                  .WithSettingData;

                    // add custom data from custom attributes
                    performanceMeterBuilder =
                        performanceMeterBuilder.AddCustomDataFromCustomAttributes(context, controllerActionDescriptor,
                                                                                  Options);

                    using (performanceMeterBuilder.Start())
                    {
                        // execute the pipe
                        await _next(context);
                    }
                }
                else
                {
                    // don't watching, only relay
                    await _next(context);
                }
            }
            else
            {
                // don't watching, only relay
                await _next(context);
            }
        }
コード例 #5
0
        public ActionResult <string> GetThreadSleepFromActionPerformance()
        {
            using (PerformanceMeter <Thread> .WatchingMethod <int>(Thread.Sleep).Start())
            {
                Thread.Sleep(1000);
            }

            return(Ok(PerformanceMeter <Thread> .PerformanceInfo.MethodCalls.FirstOrDefault(ta => ta.MethodName == nameof(Thread.Sleep))?.Elapsed));
        }
コード例 #6
0
        public void PerformanceMeterStartWaychingPublicVoidMethodWithHttpContectAccessorReturnsSuccess()
        {
            // Arrange
            PerformanceMeter <PublicClass> performanceMeter = null;

            // Act
            using (performanceMeter = PerformanceMeter <PublicClass>
                                      .WatchingMethod(nameof(PublicClass.PublicVoidMethod))
                                      .WithSettingData
                                      .CallerFrom(_httpContextAccessor)
                                      .Start())
            {
                // Arrange
                var performanceInfo       = PerformanceMeter <PublicClass> .PerformanceInfo;
                var methodCurrentActivity = performanceInfo.CurrentActivity.Find(ca => ca.Method == performanceMeter.MethodInfo);
                var methodTotalActivity   = performanceInfo.TotalActivity.Find(ca => ca.Method == performanceMeter.MethodInfo);
                var methodCalls           = performanceInfo.MethodCalls.Find(ca => ca.Method == performanceMeter.MethodInfo);

                // Assert
                performanceInfo.ClassName.Should().EndWith(typeof(PublicClass).Name, "class name should be known");

                performanceInfo.MethodNames.Count.Should().Be(typeof(PublicClass)
                                                              .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
                                                              .Where(mi => !mi.IsSpecialName && mi.GetCustomAttribute <IgnoreMethodPerformanceAttribute>() == null)
                                                              .Count());

                methodCurrentActivity.Should().NotBeNull();
                methodCurrentActivity.CallsCount.Should().Be(1);

                methodTotalActivity.Should().NotBeNull();
                methodTotalActivity.CallsCount.Should().Be(0);

                methodCalls.Should().BeNull();
            }

            // Arrange
            var performanceInfoAfterDispose       = PerformanceMeter <PublicClass> .PerformanceInfo;
            var methodCurrentActivityAfterDispose = performanceInfoAfterDispose.CurrentActivity.Find(ca => ca.Method == performanceMeter.MethodInfo);
            var methodTotalActivityAfterDispose   = performanceInfoAfterDispose.TotalActivity.Find(ca => ca.Method == performanceMeter.MethodInfo);
            var methodCallsAfterDispose           = performanceInfoAfterDispose.MethodCalls.Find(ca => ca.Method == performanceMeter.MethodInfo);

            // Assert
            methodCurrentActivityAfterDispose.Should().NotBeNull();
            methodCurrentActivityAfterDispose.CallsCount.Should().Be(0);

            methodTotalActivityAfterDispose.Should().NotBeNull();
            methodTotalActivityAfterDispose.CallsCount.Should().Be(1);

            methodCallsAfterDispose.Should().NotBeNull();
            methodCallsAfterDispose.Method.Should().BeSameAs(performanceMeter.MethodInfo);
            methodCallsAfterDispose.MethodName.Should().Be(nameof(PublicClass.PublicVoidMethod));
            methodCallsAfterDispose.Elapsed.Should().BeGreaterThan(new TimeSpan());
            methodCallsAfterDispose.Caller.Should().Be(_httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString());
        }
コード例 #7
0
        public ActionResult <string> StartWatchingWithCallerName([FromBody] string value)
        {
            // the method’s performance info will be amended with the caller's name (if internal HttpContextAccessor is null)
            using var pm = PerformanceMeter <PerformanceMeterController>
                           .WatchingMethod()
                           .WithSettingData
                           .CallerSourceData()
                           .CallerFrom("Test caller")
                           .Start();

            pm.StopWatching(); // stop watching here (or you can use "pm.Dispose();")
            Thread.Sleep(2000);

            return(Ok(value));
        }
コード例 #8
0
        public ActionResult <string> WatchingMethodUsingDI(uint value)
        {
            // method performance info will reach with HttpContextAccessor (required for DI)
            using (PerformanceMeter <PerformanceMeterController>
                   .WatchingMethod(nameof(WatchingMethodUsingDI))
                   .WithSettingData
                   .CallerFrom(_httpContextAccessor)
                   .Start())
            {
                // adds step to PerformanceMeter using DI
                AddStepWithDI();

                return(Ok($"{value}"));
            }
        }
コード例 #9
0
 public ActionResult WatchingMethodWithExecutedCommand()
 {
     // custom "ExecutedCommand" will be executed after performance watching is completed
     using (PerformanceMeter <PerformanceMeterController>
            .WatchingMethod()
            .WithExecutingOnComplete
            .Command(new ExecutedCommand("bla-bla-bla"))
            .Action((pi) =>
     {
         Debug.WriteLine($"Class name: {pi.ClassName}");
     })
            .Start())
     {
         return(Ok());
     }
 }
コード例 #10
0
        public ActionResult <long> WatchingMethodStartWithCorrelationIdAndFakeServiceSteps()
        {
            // generate correlationId (for example)
            var correlationId = Guid.NewGuid();

            var parameterForMethod2 = "parameter";

            // start performance watching with correlationId and caller source data
            using (PerformanceMeter <PerformanceMeterController>
                   .WatchingMethod()
                   .WithSettingData
                   .CustomData("corellationId", correlationId)
                   .CallerSourceData()
                   .Start())
            {
                // add step with calling FakeService.FakeMethod2 with custom data (corellationId)
                using (PerformanceMeter <FakeService>
                       .WatchingMethod(nameof(FakeService.FakeMethod1))
                       .WithSettingData
                       .CustomData("corellationId", correlationId)
                       .CustomData("fake service method 1 step", 1)
                       .CallerSourceData()
                       .Start())
                {
                    FakeService.FakeMethod1();
                }

                // add step with calling FakeService.FakeMethod2 with custom data (corellationId and perameter for FakeMethod2)
                using (PerformanceMeter <FakeService>
                       .WatchingMethod(nameof(FakeService.FakeMethod2))
                       .WithSettingData
                       .CustomData("corellationId", correlationId)
                       .CustomData("fake service method 2 step", 2)
                       .CustomData("method parameter", parameterForMethod2)
                       .CallerSourceData()
                       .Start())
                {
                    FakeService.FakeMethod2(parameterForMethod2);
                }
            }

            return(Ok(PerformanceMeter <FakeService> .PerformanceInfo.MethodCalls.Where(mc => mc.MethodName.StartsWith("Fake")).Sum(mc => mc.Elapsed.TotalMilliseconds)));
        }
コード例 #11
0
        public void OnBeforeAction(HttpContext httpContext, ActionDescriptor actionDescriptor)
        {
            var controllerActionDescriptor = (ControllerActionDescriptor)actionDescriptor;

            if (!controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(WatchingWithDiagnosticSourceAttribute), false).Any() &&
                !controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(typeof(WatchingWithDiagnosticSourceAttribute), false).Any())
            {
                return;
            }

            if (controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(IgnoreMethodPerformanceAttribute), false).Any())
            {
                return;
            }

            var performanceMeterBuilder = PerformanceMeter <TClass>
                                          .WatchingMethod(controllerActionDescriptor.ActionName)
                                          .WithSettingData;

            // add custom data from attributes
            foreach (MethodCustomDataAttribute methodCustomData in controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(MethodCustomDataAttribute), false))
            {
                performanceMeterBuilder = performanceMeterBuilder.CustomData(methodCustomData.Key, methodCustomData.Value);
            }
            if (httpContext.Request.QueryString.HasValue)
            {
                performanceMeterBuilder = performanceMeterBuilder.CustomData("queryString", httpContext.Request.QueryString.Value);
            }
            if (httpContext.User.Identity.IsAuthenticated)
            {
                performanceMeterBuilder = performanceMeterBuilder.CustomData("userIdentityName", httpContext.User.Identity.Name);
            }

            // add caller from attributes
            performanceMeterBuilder = performanceMeterBuilder.CallerFrom(httpContext.Connection?.RemoteIpAddress?.ToString() ?? httpContext.Connection?.LocalIpAddress?.ToString());
            foreach (MethodCallerAttribute methodCaller in controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(MethodCallerAttribute), false))
            {
                performanceMeterBuilder = performanceMeterBuilder.CallerFrom(methodCaller.Caller);
            }

            httpContext.Items["PerformanceMeter"] = performanceMeterBuilder.Start();
        }
コード例 #12
0
        public void OnBeforeAction(HttpContext httpContext, ActionDescriptor actionDescriptor)
        {
            if (PerformanceMeterCommonMethods.ShouldWatching(httpContext.Request, Options))
            {
                if (actionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
                {
                    if (PerformanceMeterCommonMethods.CheckExcludedMethods(controllerActionDescriptor, Options))
                    {
                        return;
                    }

                    if (PerformanceMeterCommonMethods.CheckAnnotatedAttribute(controllerActionDescriptor, Options,
                                                                              typeof(WatchingWithDiagnosticSourceAttribute)))
                    {
                        return;
                    }

                    if (PerformanceMeterCommonMethods.CheckIgnoreMethodPerformanceAttribute(controllerActionDescriptor,
                                                                                            Options))
                    {
                        return;
                    }

                    var performanceMeterBuilder = PerformanceMeter <TClass>
                                                  .WatchingMethod(controllerActionDescriptor.ActionName)
                                                  .WithSettingData;

                    // add custom data from custom attributes
                    performanceMeterBuilder =
                        performanceMeterBuilder.AddCustomDataFromCustomAttributes(httpContext, controllerActionDescriptor,
                                                                                  Options);

                    httpContext.Items["PerformanceMeter"] = performanceMeterBuilder.Start();
                }
            }
        }