如何注入 Application Insights 代码以监控所有方法的计时

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

我有一个 WCF 服务,我在其中使用 Application Insights SDK 以这种方式测量计时。

[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

如您所见,我在方法的开头启动了一个秒表,然后在方法的结尾将事件发送到 Application Insights。

为 Web 服务上的所有 10 个方法执行此操作没什么大不了的,我已经这样做了。

然而,这些方法调用其他 类 中的实用程序方法,找到瓶颈的唯一方法是测量每个方法。

你有什么建议?

请注意,trackEvent 有一个属性字段,有时我使用它,有时我只发送 null。

感谢

寻找 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 例如。

对于 WCF,您可以更轻松地做到这一点,因为内置了对调用拦截的支持,例如 Message Inspectors