private void CreatePerformanceCounters(out CollectionConfigurationError[] errors)
        {
            var errorList = new List <CollectionConfigurationError>();

            CalculatedMetricInfo[] performanceCounterMetrics =
                (this.info.Metrics ?? new CalculatedMetricInfo[0]).Where(metric => metric.TelemetryType == TelemetryType.PerformanceCounter)
                .ToArray();

            this.performanceCounters.AddRange(
                performanceCounterMetrics.GroupBy(metric => metric.Id, StringComparer.Ordinal)
                .Select(group => group.First())
                .Select(pc => Tuple.Create(pc.Id, pc.Projection)));

            IEnumerable <string> duplicateMetricIds =
                performanceCounterMetrics.GroupBy(pc => pc.Id, StringComparer.Ordinal).Where(group => group.Count() > 1).Select(group => group.Key);

            foreach (var duplicateMetricId in duplicateMetricIds)
            {
                errorList.Add(
                    CollectionConfigurationError.CreateError(
                        CollectionConfigurationErrorType.PerformanceCounterDuplicateIds,
                        string.Format(CultureInfo.InvariantCulture, "Duplicate performance counter id '{0}'", duplicateMetricId),
                        null,
                        Tuple.Create("MetricId", duplicateMetricId)));
            }

            errors = errorList.ToArray();
        }
        private static void AddMetric <TTelemetry>(
            CalculatedMetricInfo metricInfo,
            List <CalculatedMetric <TTelemetry> > metrics,
            out CollectionConfigurationError[] errors)
        {
            errors = new CollectionConfigurationError[] { };

            try
            {
                metrics.Add(new CalculatedMetric <TTelemetry>(metricInfo, out errors));
            }
            catch (Exception e)
            {
                // error creating the metric
                errors =
                    errors.Concat(
                        new[]
                {
                    CollectionConfigurationError.CreateError(
                        CollectionConfigurationErrorType.MetricFailureToCreate,
                        string.Format(CultureInfo.InvariantCulture, "Failed to create metric {0}.", metricInfo),
                        e,
                        Tuple.Create("MetricId", metricInfo.Id))
                }).ToArray();
            }
        }
        public bool CheckFilters(TTelemetry document, out CollectionConfigurationError[] errors)
        {
            if (this.filterGroups.Count < 1)
            {
                errors = new CollectionConfigurationError[0];
                return(true);
            }

            var errorList = new List <CollectionConfigurationError>(this.filterGroups.Count);

            // iterate over OR-connected groups
            foreach (FilterConjunctionGroup <TTelemetry> conjunctionFilterGroup in this.filterGroups)
            {
                CollectionConfigurationError[] groupErrors;
                bool groupPassed = conjunctionFilterGroup.CheckFilters(document, out groupErrors);

                errorList.AddRange(groupErrors);

                if (groupPassed)
                {
                    // one group has passed, we don't care about others
                    errors = errorList.ToArray();
                    return(true);
                }
            }

            errors = errorList.ToArray();
            return(false);
        }
        private void CreateFilters(out CollectionConfigurationError[] errors)
        {
            var errorList = new List <CollectionConfigurationError>();

            foreach (FilterConjunctionGroupInfo filterConjunctionGroupInfo in this.info.FilterGroups ?? new FilterConjunctionGroupInfo[0])
            {
                CollectionConfigurationError[] groupErrors = null;
                try
                {
                    var conjunctionFilterGroup = new FilterConjunctionGroup <TTelemetry>(filterConjunctionGroupInfo, out groupErrors);
                    this.filterGroups.Add(conjunctionFilterGroup);
                }
                catch (Exception e)
                {
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.MetricFailureToCreateFilterUnexpected,
                            string.Format(CultureInfo.InvariantCulture, "Failed to create a filter group {0}.", filterConjunctionGroupInfo),
                            e,
                            Tuple.Create("MetricId", this.info.Id)));
                }

                if (groupErrors != null)
                {
                    foreach (var error in groupErrors)
                    {
                        error.Data["MetricId"] = this.info.Id;
                    }

                    errorList.AddRange(groupErrors);
                }
            }

            errors = errorList.ToArray();
        }
Exemple #5
0
        private void CreateFilters(out CollectionConfigurationError[] errors)
        {
            var errorList = new List <CollectionConfigurationError>();

            foreach (FilterInfo filterInfo in this.info.Filters)
            {
                try
                {
                    var filter = new Filter <TTelemetry>(filterInfo);
                    this.filters.Add(filter);
                }
                catch (Exception e)
                {
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.FilterFailureToCreateUnexpected,
                            string.Format(CultureInfo.InvariantCulture, "Failed to create a filter {0}.", filterInfo),
                            e,
                            Tuple.Create("FilterFieldName", filterInfo.FieldName),
                            Tuple.Create("FilterPredicate", filterInfo.Predicate.ToString()),
                            Tuple.Create("FilterComparand", filterInfo.Comparand)));
                }
            }

            errors = errorList.ToArray();
        }
Exemple #6
0
        private void CreateFilters(out CollectionConfigurationError[] errors)
        {
            var errorList = new List <CollectionConfigurationError>();

            foreach (DocumentFilterConjunctionGroupInfo documentFilterConjunctionGroupInfo in this.info.DocumentFilterGroups ?? new DocumentFilterConjunctionGroupInfo[0])
            {
                try
                {
                    CollectionConfigurationError[] groupErrors;
                    switch (documentFilterConjunctionGroupInfo.TelemetryType)
                    {
                    case TelemetryType.Request:
                        this.requestFilterGroups.Add(new FilterConjunctionGroup <RequestTelemetry>(documentFilterConjunctionGroupInfo.Filters, out groupErrors));
                        break;

                    case TelemetryType.Dependency:
                        this.dependencyFilterGroups.Add(new FilterConjunctionGroup <DependencyTelemetry>(documentFilterConjunctionGroupInfo.Filters, out groupErrors));
                        break;

                    case TelemetryType.Exception:
                        this.exceptionFilterGroups.Add(new FilterConjunctionGroup <ExceptionTelemetry>(documentFilterConjunctionGroupInfo.Filters, out groupErrors));
                        break;

                    case TelemetryType.Event:
                        this.eventFilterGroups.Add(new FilterConjunctionGroup <EventTelemetry>(documentFilterConjunctionGroupInfo.Filters, out groupErrors));
                        break;

                    case TelemetryType.Trace:
                        this.traceFilterGroups.Add(new FilterConjunctionGroup <TraceTelemetry>(documentFilterConjunctionGroupInfo.Filters, out groupErrors));
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(string.Format(CultureInfo.InvariantCulture, "Unsupported TelemetryType: '{0}'", documentFilterConjunctionGroupInfo.TelemetryType));
                    }

                    errorList.AddRange(groupErrors);
                }
                catch (Exception e)
                {
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.DocumentStreamFailureToCreateFilterUnexpected,
                            string.Format(CultureInfo.InvariantCulture, "Failed to create a document stream filter {0}.", documentFilterConjunctionGroupInfo),
                            e,
                            Tuple.Create("DocumentStreamId", this.info.Id)));
                }
            }

            errors = errorList.ToArray();
        }
Exemple #7
0
        private static bool CheckFilters <TTelemetry>(
            List <FilterConjunctionGroup <TTelemetry> > filterGroups,
            Func <FilterConjunctionGroup <TTelemetry>, List <CollectionConfigurationError>, bool> checkFilters,
            out CollectionConfigurationError[] errors)
        {
            errors = new CollectionConfigurationError[0];
            var  errorList = new List <CollectionConfigurationError>();
            bool leastOneConjunctionGroupPassed = false;

            if (filterGroups.Count == 0)
            {
                // no filters for the telemetry type - filter out, we're not interested
                return(false);
            }

            // iterate over filter groups (filters within each group are evaluated as AND, the groups are evaluated as OR)
            foreach (FilterConjunctionGroup <TTelemetry> conjunctionFilterGroup in filterGroups)
            {
                bool conjunctionGroupPassed;
                try
                {
                    conjunctionGroupPassed = checkFilters(conjunctionFilterGroup, errorList);
                }
                catch (Exception)
                {
                    // the filters have failed to run (possibly incompatible field value in telemetry), consider the telemetry item filtered out by this conjunction group
                    ////!!!
                    ////errorList.Add(
                    ////    CollectionConfigurationError.CreateError(
                    ////        CollectionConfigurationErrorType.DocumentStreamFilterFailureToRun,
                    ////        string.Format(CultureInfo.InvariantCulture, "Document stream filter failed to run"),
                    ////        e));
                    conjunctionGroupPassed = false;
                }

                if (conjunctionGroupPassed)
                {
                    // no need to check remaining groups, one OR-connected group has passed
                    leastOneConjunctionGroupPassed = true;
                    break;
                }
            }

            errors = errorList.ToArray();

            return(leastOneConjunctionGroupPassed);
        }
        private void CreateTelemetryMetrics(CollectionConfigurationInfo info, out CollectionConfigurationError[] errors)
        {
            var errorList = new List <CollectionConfigurationError>();
            var metricIds = new HashSet <string>();

            foreach (CalculatedMetricInfo metricInfo in info.Metrics ?? new CalculatedMetricInfo[0])
            {
                if (metricIds.Contains(metricInfo.Id))
                {
                    // there must not be metrics with duplicate ids
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.MetricDuplicateIds,
                            string.Format(CultureInfo.InvariantCulture, "Metric with a duplicate id ignored: {0}", metricInfo.Id),
                            null,
                            Tuple.Create("MetricId", metricInfo.Id)));

                    continue;
                }

                CollectionConfigurationError[] localErrors = null;
                switch (metricInfo.TelemetryType)
                {
                case TelemetryType.Request:
                    CollectionConfiguration.AddMetric(metricInfo, this.requestTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.Dependency:
                    CollectionConfiguration.AddMetric(metricInfo, this.dependencyTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.Exception:
                    CollectionConfiguration.AddMetric(metricInfo, this.exceptionTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.Event:
                    CollectionConfiguration.AddMetric(metricInfo, this.eventTelemetryMetrics, out localErrors);
                    break;

                case TelemetryType.PerformanceCounter:
                    // no need to create a wrapper, we rely on the underlying CollectionConfigurationInfo to provide data about performance counters
                    // move on to the next metric
                    continue;

                case TelemetryType.Trace:
                    CollectionConfiguration.AddMetric(metricInfo, this.traceTelemetryMetrics, out localErrors);
                    break;

                default:
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.MetricTelemetryTypeUnsupported,
                            string.Format(CultureInfo.InvariantCulture, "TelemetryType is not supported: {0}", metricInfo.TelemetryType),
                            null,
                            Tuple.Create("MetricId", metricInfo.Id),
                            Tuple.Create("TelemetryType", metricInfo.TelemetryType.ToString())));
                    break;
                }

                errorList.AddRange(localErrors ?? new CollectionConfigurationError[0]);

                metricIds.Add(metricInfo.Id);
            }

            errors = errorList.ToArray();
        }
        private void CreateDocumentStreams(
            out CollectionConfigurationError[] errors,
            Clock timeProvider,
            IEnumerable <DocumentStream> previousDocumentStreams)
        {
            var errorList         = new List <CollectionConfigurationError>();
            var documentStreamIds = new HashSet <string>();

            // quota might be changing concurrently on the collection thread, but we don't need the exact value at any given time
            // we will try to carry over the last known values to this new configuration
            Dictionary <string, Tuple <float, float, float, float, float> > previousQuotasByStreamId =
                previousDocumentStreams.ToDictionary(
                    documentStream => documentStream.Id,
                    documentStream =>
                    Tuple.Create(
                        documentStream.RequestQuotaTracker.CurrentQuota,
                        documentStream.DependencyQuotaTracker.CurrentQuota,
                        documentStream.ExceptionQuotaTracker.CurrentQuota,
                        documentStream.EventQuotaTracker.CurrentQuota,
                        documentStream.TraceQuotaTracker.CurrentQuota));

            foreach (DocumentStreamInfo documentStreamInfo in this.info.DocumentStreams ?? new DocumentStreamInfo[0])
            {
                if (documentStreamIds.Contains(documentStreamInfo.Id))
                {
                    // there must not be streams with duplicate ids
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.DocumentStreamDuplicateIds,
                            string.Format(CultureInfo.InvariantCulture, "Document stream with a duplicate id ignored: {0}", documentStreamInfo.Id),
                            null,
                            Tuple.Create("DocumentStreamId", documentStreamInfo.Id)));

                    continue;
                }

                CollectionConfigurationError[] localErrors = null;
                try
                {
                    Tuple <float, float, float, float, float> initialQuotas;
                    previousQuotasByStreamId.TryGetValue(documentStreamInfo.Id, out initialQuotas);

                    var documentStream = new DocumentStream(
                        documentStreamInfo,
                        out localErrors,
                        timeProvider,
                        initialRequestQuota: initialQuotas?.Item1,
                        initialDependencyQuota: initialQuotas?.Item2,
                        initialExceptionQuota: initialQuotas?.Item3,
                        initialEventQuota: initialQuotas?.Item4,
                        initialTraceQuota: initialQuotas?.Item5);

                    documentStreamIds.Add(documentStreamInfo.Id);
                    this.documentStreams.Add(documentStream);
                }
                catch (Exception e)
                {
                    errorList.Add(
                        CollectionConfigurationError.CreateError(
                            CollectionConfigurationErrorType.DocumentStreamFailureToCreate,
                            string.Format(CultureInfo.InvariantCulture, "Failed to create document stream {0}", documentStreamInfo),
                            e,
                            Tuple.Create("DocumentStreamId", documentStreamInfo.Id)));
                }

                if (localErrors != null)
                {
                    foreach (var error in localErrors)
                    {
                        error.Data["DocumentStreamId"] = documentStreamInfo.Id;
                    }

                    errorList.AddRange(localErrors);
                }
            }

            errors = errorList.ToArray();
        }