예제 #1
0
        private void AssignmentWidgetInfo()
        {
            if (WidgetModelEntity == null)
            {
                DateTypeId  = (int)DateTypeEnum.CurrentPeriod;
                DataTypeId  = (int)BenchmarkTypeEnum.AllProgram;
                DisplayType = DisplayTypeList.FirstOrDefault();
            }
            else
            {
                WidgetTitle = WidgetModelEntity.Title;
                DateTypeId  = WidgetModelEntity.DateTypeId;

                #region 设置指标

                _metricString = WidgetModelEntity.Metrics;
                var metricsx = WidgetModelEntity.Metrics.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var metricx in metricsx)
                {
                    var selectedMetricx = MetricsCache.Find(m => m.EnName == metricx && m.SystemTypeId == WidgetModelEntity.SystemTypeId);
                    if (selectedMetricx != null)
                    {
                        _selectedMetrics.Add(selectedMetricx);
                    }
                }

                foreach (var metricItems in MetricItemsSource)
                {
                    foreach (var metric in metricItems.Items)
                    {
                        if (metricsx.Contains(metric.EnName))
                        {
                            metric.IsChecked = true;
                        }
                    }
                }

                #endregion

                #region 设置显示类型

                //SetDisplayType();
                var displayType = DisplayTypeList.FirstOrDefault(d => d.Type == WidgetModelEntity.DisplayType && d.TypeIndex == WidgetModelEntity.DisplayTypeIndex);
                DisplayType = displayType;

                #endregion
            }
        }
예제 #2
0
        private static Metric GetOrCreateMetric(
            TelemetryClient telemetryClient,
            MetricAggregationScope aggregationScope,
            string metricId,
            string dimension1Name,
            string dimension2Name,
            IMetricConfiguration metricConfiguration)
        {
            Util.ValidateNotNull(telemetryClient, nameof(telemetryClient));

            MetricManager metricManager = telemetryClient.GetMetricManager(aggregationScope);
            MetricsCache  cache         = metricManager.GetOrCreateExtensionState(MetricsCache.CreateNewInstance);

            if (cache == null)
            {
                throw new InvalidOperationException($"telemetryConfiguration.GetMetricManager().GetOrCreateExtensionState(..) unexpectedly returned null."
                                                    + $" This indicates that multiple extensions attempt to use"
                                                    + $" the \"Cache\" extension point of the {nameof(MetricManager)} in a conflicting manner.");
            }

            Metric metric = cache.GetOrCreateMetric(metricId, dimension1Name, dimension2Name, metricConfiguration);

            return(metric);
        }
        /// <summary>
        /// Initializes the privates and activates them atomically.
        /// </summary>
        /// <param name="maxDependencyTypesToDiscoverCount">Max number of Dependency Types to discover.</param>
        private void ReinitializeMetrics(int maxDependencyTypesToDiscoverCount)
        {
            MetricManager thisMetricManager = this.metricManager;

            if (thisMetricManager == null)
            {
                MetricsCache newMetrics = new MetricsCache();
                newMetrics.MaxDependencyTypesToDiscover = maxDependencyTypesToDiscoverCount;
                this.metrics = newMetrics;
                return;
            }

            if (maxDependencyTypesToDiscoverCount == 0)
            {
                MetricsCache newMetrics = new MetricsCache();

                newMetrics.Default = new SucceessAndFailureMetrics(
                    thisMetricManager.CreateMetric(
                        MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                        new Dictionary <string, string>()
                {
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.TrueString,                      // SUCCESS metric
                    [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                }),
                    thisMetricManager.CreateMetric(
                        MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                        new Dictionary <string, string>()
                {
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.FalseString,                     // FAILURE metric
                    [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                }));

                newMetrics.Unknown = null;
                newMetrics.ByType  = null;
                newMetrics.MaxDependencyTypesToDiscover   = maxDependencyTypesToDiscoverCount;
                newMetrics.TypeDiscoveryLock              = null;
                newMetrics.DependencyTypesDiscoveredCount = 0;

                this.metrics = newMetrics;
            }
            else
            {
                MetricsCache newMetrics = new MetricsCache();

                newMetrics.Default = new SucceessAndFailureMetrics(
                    thisMetricManager.CreateMetric(
                        MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                        new Dictionary <string, string>()
                {
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.TrueString,                      // SUCCESS metric
                    [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.TypeName] = MetricTerms.Autocollection.DependencyCall.TypeNames.Other,
                }),
                    thisMetricManager.CreateMetric(
                        MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                        new Dictionary <string, string>()
                {
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.FalseString,                     // FAILURE metric
                    [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.TypeName] = MetricTerms.Autocollection.DependencyCall.TypeNames.Other,
                }));

                newMetrics.Unknown = new SucceessAndFailureMetrics(
                    thisMetricManager.CreateMetric(
                        MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                        new Dictionary <string, string>()
                {
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.TrueString,                      // SUCCESS metric
                    [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.TypeName] = MetricTerms.Autocollection.DependencyCall.TypeNames.Unknown,
                }),
                    thisMetricManager.CreateMetric(
                        MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                        new Dictionary <string, string>()
                {
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.FalseString,                     // FAILURE metric
                    [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                    [MetricTerms.Autocollection.DependencyCall.PropertyNames.TypeName] = MetricTerms.Autocollection.DependencyCall.TypeNames.Unknown,
                }));

                newMetrics.ByType = new ConcurrentDictionary <string, SucceessAndFailureMetrics>();
                newMetrics.MaxDependencyTypesToDiscover   = maxDependencyTypesToDiscoverCount;
                newMetrics.TypeDiscoveryLock              = new object();
                newMetrics.DependencyTypesDiscoveredCount = 0;

                this.metrics = newMetrics;
            }
        }
        /// <summary>
        /// Extracts appropriate data points for auto-collected, pre-aggregated metrics from a single <c>DependencyTelemetry</c> item.
        /// </summary>
        /// <param name="fromItem">The telemetry item from which to extract the metric data points.</param>
        /// <param name="isItemProcessed">Whether of not the specified item was processed (aka not ignored) by this extractor.</param>
        public void ExtractMetrics(ITelemetry fromItem, out bool isItemProcessed)
        {
            //// If this item is not a DependencyTelemetry, we will not process it:
            DependencyTelemetry dependencyCall = fromItem as DependencyTelemetry;

            if (dependencyCall == null)
            {
                isItemProcessed = false;
                return;
            }

            MetricManager thisMetricManager = this.metricManager;
            MetricsCache  thisMetrics       = this.metrics;

            //// If there is no MetricManager, then this extractor has not been properly initialized yet:
            if (thisMetricManager == null)
            {
                //// This will be caught and properly logged by the base class:
                throw new InvalidOperationException("Cannot execute ExtractMetrics because this metrics extractor has not been initialized (no metrics manager).");
            }

            //// Get dependency call success status:
            bool dependencyFailed = (dependencyCall.Success != null) && (dependencyCall.Success == false);

            //// Now we need to determine which data series to use:
            Metric metricToTrack = null;

            if (thisMetrics.MaxDependencyTypesToDiscover == 0)
            {
                //// If auto-discovering dependency types is disabled, just pick series based on success status:
                metricToTrack = dependencyFailed
                                    ? thisMetrics.Default.Failure
                                    : thisMetrics.Default.Success;
            }
            else
            {
                //// Pick series based on dependency type (and success status):
                string dependencyType = dependencyCall.Type;

                if (dependencyType == null || dependencyType.Equals(string.Empty, StringComparison.OrdinalIgnoreCase))
                {
                    //// If dependency type is not set, we use "Unknown":
                    metricToTrack = dependencyFailed
                                        ? thisMetrics.Unknown.Failure
                                        : thisMetrics.Unknown.Success;
                }
                else
                {
                    //// See if we have already discovered the current dependency type:
                    SucceessAndFailureMetrics typeMetrics;
                    bool previouslyDiscovered = thisMetrics.ByType.TryGetValue(dependencyType, out typeMetrics);

                    if (previouslyDiscovered)
                    {
                        metricToTrack = dependencyFailed
                                    ? typeMetrics.Failure
                                    : typeMetrics.Success;
                    }
                    else
                    {
                        //// We have not seen the current dependency type yet:

                        if (thisMetrics.ByType.Count >= thisMetrics.MaxDependencyTypesToDiscover)
                        {
                            //// If the limit of types to discover is already reached, just use "Other":
                            metricToTrack = dependencyFailed
                                    ? thisMetrics.Default.Failure
                                    : thisMetrics.Default.Success;
                        }
                        else
                        {
                            //// So we have not yet reached the limit.
                            //// We will need to take a lock to make sure that the number of discovered types is used correctly as a limit.
                            //// Note: this is a very rare case. It is expected to occur only MaxDependencyTypesToDiscover times.
                            //// In case of very high contention, this may happen a little more often,
                            //// but will no longer happen once the MaxDependencyTypesToDiscover limit is reached.

                            const string TypeDiscoveryLimitReachedMessage = "Cannot discover more dependency types because the MaxDependencyTypesToDiscover limit"
                                                                            + " is reached. This is a control-flow exception that should not propagate outside "
                                                                            + "the metric extraction logic.";

                            try
                            {
                                typeMetrics = thisMetrics.ByType.GetOrAdd(
                                    dependencyType,
                                    (depType) =>
                                {
                                    lock (thisMetrics.TypeDiscoveryLock)
                                    {
                                        if (thisMetrics.DependencyTypesDiscoveredCount >= thisMetrics.MaxDependencyTypesToDiscover)
                                        {
                                            throw new InvalidOperationException(TypeDiscoveryLimitReachedMessage);
                                        }

                                        thisMetrics.DependencyTypesDiscoveredCount++;

                                        return(new SucceessAndFailureMetrics(
                                                   thisMetricManager.CreateMetric(
                                                       MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                                                       new Dictionary <string, string>()
                                        {
                                            [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.TrueString,                      // SUCCESS metric
                                            [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                                            [MetricTerms.Autocollection.DependencyCall.PropertyNames.TypeName] = depType,
                                        }),
                                                   thisMetricManager.CreateMetric(
                                                       MetricTerms.Autocollection.Metric.DependencyCallDuration.Name,
                                                       new Dictionary <string, string>()
                                        {
                                            [MetricTerms.Autocollection.DependencyCall.PropertyNames.Success] = Boolean.FalseString,                     // FAILURE metric
                                            [MetricTerms.Autocollection.MetricId.Moniker.Key] = MetricTerms.Autocollection.Metric.DependencyCallDuration.Id,
                                            [MetricTerms.Autocollection.DependencyCall.PropertyNames.TypeName] = depType,
                                        })));
                                    }
                                });
                            }
                            catch (InvalidOperationException ex)
                            {
                                if (!ex.Message.Equals(TypeDiscoveryLimitReachedMessage, StringComparison.Ordinal))
                                {
#if NET40
                                    throw;
#else
                                    ExceptionDispatchInfo.Capture(ex).Throw();
#endif
                                }

                                //// Limit was reached concurrently. We will use "Other" after all:
                                metricToTrack = dependencyFailed
                                    ? thisMetrics.Default.Failure
                                    : thisMetrics.Default.Success;
                            }

                            //// Use the newly created metric for this newly discovered dependency type:
                            metricToTrack = dependencyFailed
                                    ? typeMetrics.Failure
                                    : typeMetrics.Success;
                        }
                    }   // else OF if (previouslyDiscovered)
                }
            }

            //// Now that we selected the right metric, track the value:
            isItemProcessed = true;
            metricToTrack.Track(dependencyCall.Duration.TotalMilliseconds);
        }