How to inject Application Insights code to monitor timing in all methods

不打扰是莪最后的温柔 提交于 2019-12-25 08:49:51

问题


I have a WCF Service where I measure timings with Application Insights SDK in this way.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    [BasicHttpBindingServiceMetadataExchangeEndpoint]
    public class DMSWebService : IDMSWebService
    {
        public static readonly string LoggingPrefix = "DMSWebService";
        private TelemetryClient telemetry;

        //Defines if Application Insights must be enabled or not
        public Boolean EnableApplicationInsights { get; set; }

        //Application Insights Instrumentation Key
        public string ApplicationInsightsMonitoringKey { get; set; }

        //Constructor to get the property bag values only once.
        public DMSWebService()
        {
            InitializeApplicationInsights();
            telemetry= new TelemetryClient {InstrumentationKey = ApplicationInsightsMonitoringKey};
        }

        //Method to initialize ApplicationInsightSettings
        private void InitializeApplicationInsights()
        {
            bool enableApplicationInsights = false;
            using (var billingSite = BillingManagement.GetBillingSite())
            {
                enableApplicationInsights = Convert.ToBoolean(billingSite.WebApplication.GetProperty(Constants.WebApplicationSettings.EnableApplicationInsights));
                if(enableApplicationInsights) ApplicationInsightsMonitoringKey = billingSite.WebApplication.GetProperty(Constants.WebApplicationSettings.ApplicationInsightsKey);
            }

            EnableApplicationInsights = enableApplicationInsights;
        }
        #region Billing

        #region Archiving

        // GET
        public DMSServiceResult ArchiveBillCycle(string listItemId)
        {
            var stopwatch = System.Diagnostics.Stopwatch.StartNew();

            using (var withDMSServiceResult = new WithDMSServiceResult(LoggingPrefix, "ArchiveBillCycle"))
            {
                try
                {
                    withDMSServiceResult.InputParameters["listItemId"] = listItemId;

                    var listItemIdAsInt = Convert.ToInt32(listItemId);

                    using (var billingSite = BillingManagement.GetBillingSite())
                    {
                        // HACK: Necessary to disable form digest validation, which we don't need.
                        using (var continueWithoutSPContext = new ContinueWithoutSPContext())
                        {
                            withDMSServiceResult.RequestSucceeded = BillingRepository.ArchiveBillCycle(billingSite.RootWeb, listItemIdAsInt);
                        }
                    }
                }
                catch (Exception ex)
                {
                    telemetry.TrackException(ex);
                    withDMSServiceResult.HandleError(ex);
                }

                stopwatch.Stop();
                var metrics = new Dictionary <string, double>{{"processingTime", stopwatch.Elapsed.TotalMilliseconds}};
                // Set up some properties:
                var properties = new Dictionary <string, string>{{"listItemId", withDMSServiceResult.InputParameters["listItemId"]}};
                if(EnableApplicationInsights) telemetry.TrackEvent("ArchiveBillCycle", properties, metrics);

                return withDMSServiceResult.Result;
            }
        }

        #endregion

As you can see I start a StopWatch in the beginning of the method, and then I send the event to Application Insights at the end of the method.

Doing this for all the 10 methods on the web service is not a big deal, I already did it.

However these methods call utilities methods in other classes, and the only way to find the bottleneck is to measure each of the methods.

What would be your suggestion?

Please note that the trackEvent has a properties field, which sometimes I use it, sometimes i Just send null.

Thx


回答1:


Look for an AOP (Aspect Oriented Programming) framework like PostSharp (paid) or use something like Aspectize or Castle DynamicProxy. There frameworks enables you to write some custom logic once and apply them at runtime or compile time to all specified methods. See this post for an example.

For WCF you can do it easier as there is built in support for call interception using for example Message Inspectors.



来源:https://stackoverflow.com/questions/46236321/how-to-inject-application-insights-code-to-monitor-timing-in-all-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!