private static void ProcessMetrics <TTelemetry>( CollectionConfigurationAccumulator configurationAccumulatorLocal, IEnumerable <CalculatedMetric <TTelemetry> > metrics, TTelemetry telemetry, out CollectionConfigurationError[] filteringErrors, ref string projectionError) { filteringErrors = new CollectionConfigurationError[] { }; foreach (CalculatedMetric <TTelemetry> metric in metrics) { if (metric.CheckFilters(telemetry, out filteringErrors)) { // the telemetry document has passed the filters, count it in and project try { double projection = metric.Project(telemetry); configurationAccumulatorLocal.MetricAccumulators[metric.Id].AddValue(projection); } catch (Exception e) { // most likely the projection did not result in a value parsable by double.Parse() projectionError = e.ToString(); } } } }
private void UpdateConfiguration(CollectionConfigurationInfo configurationInfo) { // we only get here if Etag in the header is different from the current one, but we still want to check if Etag in the body is also different if (configurationInfo != null && !string.Equals(configurationInfo.ETag, this.currentConfigurationETag, StringComparison.Ordinal)) { QuickPulseEventSource.Log.CollectionConfigurationUpdating(this.currentConfigurationETag, configurationInfo.ETag, string.Empty); this.collectionConfigurationErrors.Clear(); CollectionConfigurationError[] errors = null; try { errors = this.onUpdatedConfiguration?.Invoke(configurationInfo); } catch (Exception e) { QuickPulseEventSource.Log.CollectionConfigurationUpdateFailed(this.currentConfigurationETag, configurationInfo.ETag, e.ToInvariantString(), string.Empty); this.collectionConfigurationErrors.Add( CollectionConfigurationError.CreateError( CollectionConfigurationErrorType.CollectionConfigurationFailureToCreateUnexpected, string.Format(CultureInfo.InvariantCulture, "Unexpected error applying configuration. ETag: {0}", configurationInfo.ETag ?? string.Empty), e, Tuple.Create("ETag", configurationInfo.ETag))); } if (errors != null) { this.collectionConfigurationErrors.AddRange(errors); } this.currentConfigurationETag = configurationInfo.ETag; } }
private void UpdatePerformanceCollector(IEnumerable <Tuple <string, string> > performanceCountersToCollect, out CollectionConfigurationError[] errors) { // all counters that need to be collected according to the new configuration - remove duplicates List <Tuple <string, string> > countersToCollect = performanceCountersToCollect.GroupBy(counter => counter.Item1, StringComparer.Ordinal) .Select(group => group.First()) .Concat( QuickPulseDefaults.DefaultCountersToCollect.Select(defaultCounter => Tuple.Create(defaultCounter.Value, defaultCounter.Value))) .ToList(); lock (this.performanceCollectorUpdateLock) { List <PerformanceCounterData> countersCurrentlyCollected = this.performanceCollector.PerformanceCounters.ToList(); IEnumerable <Tuple <string, string> > countersToRemove = countersCurrentlyCollected.Where( counter => !countersToCollect.Any(c => string.Equals(c.Item1, counter.ReportAs, StringComparison.Ordinal))) .Select(counter => Tuple.Create(counter.ReportAs, counter.OriginalString)); IEnumerable <Tuple <string, string> > countersToAdd = countersToCollect.Where( counter => !countersCurrentlyCollected.Any(c => string.Equals(c.ReportAs, counter.Item1, StringComparison.Ordinal))); // remove counters that should no longer be collected foreach (var counter in countersToRemove) { this.performanceCollector.RemoveCounter(counter.Item2, counter.Item1); } var errorsList = new List <CollectionConfigurationError>(); // add counters that should now be collected foreach (var counter in countersToAdd) { try { string error; this.performanceCollector.RegisterCounter(counter.Item2, counter.Item1, out error, true); if (!string.IsNullOrWhiteSpace(error)) { errorsList.Add( CollectionConfigurationError.CreateError( CollectionConfigurationErrorType.PerformanceCounterParsing, string.Format(CultureInfo.InvariantCulture, "Error parsing performance counter: '{0}'. {1}", counter, error), null, Tuple.Create("MetricId", counter.Item1))); QuickPulseEventSource.Log.CounterParsingFailedEvent(error, counter.Item2); continue; } QuickPulseEventSource.Log.CounterRegisteredEvent(counter.Item2); } catch (Exception e) { errorsList.Add( CollectionConfigurationError.CreateError( CollectionConfigurationErrorType.PerformanceCounterUnexpected, string.Format(CultureInfo.InvariantCulture, "Unexpected error processing counter '{0}': {1}", counter, e.Message), e, Tuple.Create("MetricId", counter.Item1))); QuickPulseEventSource.Log.CounterRegistrationFailedEvent(e.Message, counter.Item2); } } errors = errorsList.ToArray(); } }