Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/PreAggMetrics.Master #735

Merged
merged 144 commits into from
Apr 2, 2018
Merged

Conversation

macrogreg
Copy link
Contributor

Hi folks,

This is the Merge PR for Metrics Pre-Aggregation. We have worked on the architecture and APIs previously.
E.g.: #643

The amount of code so substantial that making it fit the folder structure and other conventions may take a couple of iterations. I want to start early and obtain early feedback. I'll be reaching out to people directly for specific feedback questions.

Greg Paperin and others added 30 commits May 23, 2017 03:35
…trics project and first draft of a MultidimensionalCube implementation.
@macrogreg
Copy link
Contributor Author

@SergeyKanzhelev I have pushed a change that re-enables PublicApiAnalyzer and lists the APIs in the right files.

Copy link
Contributor

@SergeyKanzhelev SergeyKanzhelev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still very hard to review. Maybe you can make an effort and move extra project separately and merge Metric -> MetricV1 as separate PR. This will make reviews meaningful

@@ -140,6 +140,7 @@ public void TrackMetricSendsSpecifiedAggregatedMetricTelemetry()
var sentTelemetry = new List<ITelemetry>();
var client = this.InitializeTelemetryClient(sentTelemetry);

#pragma warning disable CS0618 // Type or member is obsolete
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discouraging doesn't mean you need to deprecate it. You can make it non editor browseable. I was OK obsoleting it when we discussed introducing new TrackAggregaterMetric API. Since we still have a VALID scenario when one will want to use API - we should not mark it as obsolete.

@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not OK. Either code follows all practices and builds in a single build or should be moved out of repository

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my reply there

/// <param name="value">Value to be checked.</param>
/// <param name="name">Name of the parameter being checked.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateNotNull(object value, string name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


namespace Microsoft.ApplicationInsights.Metrics.Extensibility
{
/// <summary />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then move the project out please

}
}

#pragma warning disable SA1401 // Fields must be private
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So why not properties? Compiler will optimize everything out

}

/// <summary>
/// Groups constants used by metric aggregates produced by aggregators that are configured by metric configurations represented through
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but why?

@macrogreg
Copy link
Contributor Author

Hi @Dmitry-Matveev & @SergeyKanzhelev ,

I have critically evaluated the new API surface.
A one of the features offered by the library is to allow customers to plug in their own aggregator into the system and have it magically take effect.
For example I plan to ship a separate optional nuget (the aforementioned Metrics.Extensions) package that uses this feature to provide Accumulation and Distinct Count aggregators.

However, if we hold off on releasing this feature in the first beta, we can significantly reduce the size of the public API surface.

We can manage the size of the public change by doing this. However, I would like to re-enable the respective APIs in a future beta.
If you are OK with this plan, I will make change the corresponding APIs from public to internal for this beta release.

Are you OK with this plan?

@macrogreg
Copy link
Contributor Author

macrogreg commented Mar 29, 2018

I have pushed a change that reduces the public surface significantly, as discussed in my previous comments. Please note that there is still a significant number of lines in the PublicAPI.Unshipped.txt files, but a lot of them are overloads of the same methods.

I gave the remaining public APIs a quick scan (it was quick, the below list may have some errors, but the order-of-magnitude point is valid). I removed overloads and counted the actual new APIs. Results:

  • Approx 10 new statics.
  • Approx 100 new methods.
  • Approx 10 overloads of standard objects APIs (Equals(..) etc).
  • Approx 30 constants.

All in all, not that much :)

static Microsoft.ApplicationInsights.MetricConfigurationsExtensions.Measurement(this Microsoft.ApplicationInsights.MetricConfigurations metricConfigPresets) -> Microsoft.ApplicationInsights.Metrics.MetricConfigurationForMeasurement
static Microsoft.ApplicationInsights.MetricConfigurationsExtensions.SetDefaultForMeasurement(this Microsoft.ApplicationInsights.MetricConfigurations metricConfigPresets, Microsoft.ApplicationInsights.Metrics.MetricConfigurationForMeasurement defaultConfigurationForMeasurement) -> void
static Microsoft.ApplicationInsights.Metrics.Extensibility.MetricConfigurationExtensions.Constants(this Microsoft.ApplicationInsights.Metrics.MetricConfigurationForMeasurement measurementConfig) -> Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants
static Microsoft.ApplicationInsights.Metrics.Extensibility.MetricExtensions.GetConfiguration(this Microsoft.ApplicationInsights.Metric metric) -> Microsoft.ApplicationInsights.Metrics.MetricConfiguration
static Microsoft.ApplicationInsights.Metrics.Extensibility.MetricSeriesExtensions.GetConfiguration(this Microsoft.ApplicationInsights.Metrics.MetricSeries metricSeries) -> Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration
static Microsoft.ApplicationInsights.Metrics.Extensibility.TelemetryClientExtensions.GetMetricManager(this Microsoft.ApplicationInsights.TelemetryClient telemetryClient, Microsoft.ApplicationInsights.MetricAggregationScope aggregationScope) -> Microsoft.ApplicationInsights.Metrics.MetricManager
static Microsoft.ApplicationInsights.Metrics.MetricIdentifier.DefaultMetricNamespace.get -> string
static Microsoft.ApplicationInsights.Metrics.TelemetryConfigurationExtensions.GetMetricManager(this Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration telemetryPipeline) -> Microsoft.ApplicationInsights.Metrics.MetricManager
static readonly Microsoft.ApplicationInsights.MetricConfigurations.Common -> Microsoft.ApplicationInsights.MetricConfigurations

Microsoft.ApplicationInsights.Metric
Microsoft.ApplicationInsights.Metric.GetAllSeries() -> System.Collections.Generic.IReadOnlyList<System.Collections.Generic.KeyValuePair<string[], Microsoft.ApplicationInsights.Metrics.MetricSeries>>
Microsoft.ApplicationInsights.Metric.GetDimensionValues(int dimensionNumber) -> System.Collections.Generic.IReadOnlyCollection<string>
Microsoft.ApplicationInsights.Metric.Identifier.get -> Microsoft.ApplicationInsights.Metrics.MetricIdentifier
Microsoft.ApplicationInsights.Metric.SeriesCount.get -> int
Microsoft.ApplicationInsights.Metric.TrackValue(double metricValue) -> void
Microsoft.ApplicationInsights.Metric.TryGetDataSeries(out Microsoft.ApplicationInsights.Metrics.MetricSeries series) -> bool
Microsoft.ApplicationInsights.Metric.TryTrackValue(double metricValue, string dimension1Value) -> bool
Microsoft.ApplicationInsights.MetricAggregationScope
Microsoft.ApplicationInsights.MetricAggregationScope.TelemetryClient = 1 -> Microsoft.ApplicationInsights.MetricAggregationScope
Microsoft.ApplicationInsights.MetricAggregationScope.TelemetryConfiguration = 0 -> Microsoft.ApplicationInsights.MetricAggregationScope
Microsoft.ApplicationInsights.MetricConfigurations
Microsoft.ApplicationInsights.MetricConfigurationsExtensions
Microsoft.ApplicationInsights.MetricDimensionNames
Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator.CompleteAggregation(System.DateTimeOffset periodEnd) -> Microsoft.ApplicationInsights.Metrics.MetricAggregate
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator.CreateAggregateUnsafe(System.DateTimeOffset periodEnd) -> Microsoft.ApplicationInsights.Metrics.MetricAggregate
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator.DataSeries.get -> Microsoft.ApplicationInsights.Metrics.MetricSeries
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator.Reset(System.DateTimeOffset periodStart) -> void
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator.TrackValue(double metricValue) -> void
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator.TryRecycle() -> bool
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricTelemetryPipeline
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricTelemetryPipeline.FlushAsync(System.Threading.CancellationToken cancelToken) -> System.Threading.Tasks.Task
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricTelemetryPipeline.TrackAsync(Microsoft.ApplicationInsights.Metrics.MetricAggregate metricAggregate, System.Threading.CancellationToken cancelToken) -> System.Threading.Tasks.Task
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricValueFilter
Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricValueFilter.WillConsume(Microsoft.ApplicationInsights.Metrics.MetricSeries dataSeries, double metricValue) -> bool
Microsoft.ApplicationInsights.Metrics.Extensibility.MetricAggregationCycleKind
Microsoft.ApplicationInsights.Metrics.Extensibility.MetricConfigurationExtensions
Microsoft.ApplicationInsights.Metrics.Extensibility.MetricExtensions
Microsoft.ApplicationInsights.Metrics.Extensibility.MetricSeriesExtensions
Microsoft.ApplicationInsights.Metrics.Extensibility.TelemetryClientExtensions
Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration
Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration.CreateNewAggregator(Microsoft.ApplicationInsights.Metrics.MetricSeries dataSeries, Microsoft.ApplicationInsights.Metrics.Extensibility.MetricAggregationCycleKind aggregationCycleKind) -> Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator
Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration.RequiresPersistentAggregation.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricAggregate
Microsoft.ApplicationInsights.Metrics.MetricAggregate.AggregationKindMoniker.get -> string
Microsoft.ApplicationInsights.Metrics.MetricAggregate.AggregationPeriodDuration.get -> System.TimeSpan
Microsoft.ApplicationInsights.Metrics.MetricAggregate.AggregationPeriodStart.get -> System.DateTimeOffset
Microsoft.ApplicationInsights.Metrics.MetricAggregate.Data.get -> System.Collections.Generic.IDictionary<string, object>
Microsoft.ApplicationInsights.Metrics.MetricAggregate.Dimensions.get -> System.Collections.Generic.IDictionary<string, string>
Microsoft.ApplicationInsights.Metrics.MetricAggregate.GetDataValue<T>(string dataKey, T defaultValue) -> T
Microsoft.ApplicationInsights.Metrics.MetricAggregate.MetricAggregate(string metricNamespace, string metricId, string aggregationKindMoniker) -> void
Microsoft.ApplicationInsights.Metrics.MetricAggregate.MetricId.get -> string
Microsoft.ApplicationInsights.Metrics.MetricAggregate.MetricNamespace.get -> string
Microsoft.ApplicationInsights.Metrics.MetricConfiguration
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.MetricConfiguration(int seriesCountLimit, int valuesPerDimensionLimit, Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration seriesConfig) -> void
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.SeriesConfig.get -> Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.SeriesCountLimit.get -> int
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ValuesPerDimensionLimit.get -> int
Microsoft.ApplicationInsights.Metrics.MetricConfigurationForMeasurement
Microsoft.ApplicationInsights.Metrics.MetricConfigurationForMeasurement.MetricConfigurationForMeasurement(int seriesCountLimit, int valuesPerDimensionLimit, Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement seriesConfig) -> void
Microsoft.ApplicationInsights.Metrics.MetricIdentifier
Microsoft.ApplicationInsights.Metrics.MetricIdentifier.DimensionsCount.get -> int
Microsoft.ApplicationInsights.Metrics.MetricIdentifier.Equals(Microsoft.ApplicationInsights.Metrics.MetricIdentifier otherMetricIdentifier) -> bool
Microsoft.ApplicationInsights.Metrics.MetricIdentifier.GetDimensionName(int dimensionNumber) -> string
Microsoft.ApplicationInsights.Metrics.MetricIdentifier.GetDimensionNames() -> System.Collections.Generic.IEnumerable<string>
Microsoft.ApplicationInsights.Metrics.MetricIdentifier.MetricId.get -> string
Microsoft.ApplicationInsights.Metrics.MetricIdentifier.MetricIdentifier(string metricId) -> void
Microsoft.ApplicationInsights.Metrics.MetricIdentifier.MetricNamespace.get -> string
Microsoft.ApplicationInsights.Metrics.MetricManager
Microsoft.ApplicationInsights.Metrics.MetricManager.CreateNewSeries(Microsoft.ApplicationInsights.Metrics.MetricIdentifier metricIdentifier, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>> dimensionNamesAndValues, Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration config) -> Microsoft.ApplicationInsights.Metrics.MetricSeries
Microsoft.ApplicationInsights.Metrics.MetricManager.Flush() -> void
Microsoft.ApplicationInsights.Metrics.MetricManager.MetricManager(Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricTelemetryPipeline telemetryPipeline) -> void
Microsoft.ApplicationInsights.Metrics.MetricManager.Metrics.get -> Microsoft.ApplicationInsights.Metrics.MetricsCollection
Microsoft.ApplicationInsights.Metrics.MetricSeries
Microsoft.ApplicationInsights.Metrics.MetricSeries.DimensionNamesAndValues.get -> System.Collections.Generic.IReadOnlyDictionary<string, string>
Microsoft.ApplicationInsights.Metrics.MetricSeries.MetricIdentifier.get -> Microsoft.ApplicationInsights.Metrics.MetricIdentifier
Microsoft.ApplicationInsights.Metrics.MetricSeries.TrackValue(double metricValue) -> void
Microsoft.ApplicationInsights.Metrics.MetricsCollection
Microsoft.ApplicationInsights.Metrics.MetricsCollection.Clear() -> void
Microsoft.ApplicationInsights.Metrics.MetricsCollection.Contains(Microsoft.ApplicationInsights.Metric metric) -> bool
Microsoft.ApplicationInsights.Metrics.MetricsCollection.CopyTo(Microsoft.ApplicationInsights.Metric[] array, int arrayIndex) -> void
Microsoft.ApplicationInsights.Metrics.MetricsCollection.Count.get -> int
Microsoft.ApplicationInsights.Metrics.MetricsCollection.GetEnumerator() -> System.Collections.Generic.IEnumerator<Microsoft.ApplicationInsights.Metric>
Microsoft.ApplicationInsights.Metrics.MetricsCollection.GetOrCreate(Microsoft.ApplicationInsights.Metrics.MetricIdentifier metricIdentifier, Microsoft.ApplicationInsights.Metrics.MetricConfiguration metricConfiguration) -> Microsoft.ApplicationInsights.Metric
Microsoft.ApplicationInsights.Metrics.MetricsCollection.IsReadOnly.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricsCollection.Remove(Microsoft.ApplicationInsights.Metric metric) -> bool
Microsoft.ApplicationInsights.Metrics.TelemetryConfigurationExtensions
Microsoft.ApplicationInsights.TelemetryClient.GetMetric(Microsoft.ApplicationInsights.Metrics.MetricIdentifier metricIdentifier) -> Microsoft.ApplicationInsights.Metric
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.CreateNewAggregator(Microsoft.ApplicationInsights.Metrics.MetricSeries dataSeries, Microsoft.ApplicationInsights.Metrics.Extensibility.MetricAggregationCycleKind aggregationCycleKind) -> Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricSeriesAggregator
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Equals(Microsoft.ApplicationInsights.Metrics.IMetricSeriesConfiguration other) -> bool
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Equals(Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement other) -> bool
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.MetricSeriesConfigurationForMeasurement(bool restrictToUInt32Values) -> void
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.RequiresPersistentAggregation.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.RestrictToUInt32Values.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.AggregateKindDataKeys.get -> Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.DataKeysConstants
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.AggregateKindMoniker.get -> string
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants.AggregateKindDataKeys
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.DataKeysConstants
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.DataKeysConstants.Count.get -> string
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.DataKeysConstants.Max.get -> string
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.DataKeysConstants.Min.get -> string
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.DataKeysConstants.StdDev.get -> string
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.DataKeysConstants.Sum.get -> string
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants
Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants.AggregateKindDataKeys

override Microsoft.ApplicationInsights.Metrics.MetricConfiguration.Equals(object obj) -> bool
override Microsoft.ApplicationInsights.Metrics.MetricConfiguration.GetHashCode() -> int
override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.Equals(object otherObj) -> bool
override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.GetHashCode() -> int
override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.ToString() -> string
override Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Equals(object obj) -> bool
override Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.GetHashCode() -> int

const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Cloud.RoleInstance = "TelemetryContext.Cloud.RoleInstance" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Cloud.RoleName = "TelemetryContext.Cloud.RoleName" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Component.Version = "TelemetryContext.Component.Version" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.Id = "TelemetryContext.Device.Id" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.Language = "TelemetryContext.Device.Language" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.Model = "TelemetryContext.Device.Model" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.NetworkType = "TelemetryContext.Device.NetworkType" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.OemName = "TelemetryContext.Device.OemName" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.OperatingSystem = "TelemetryContext.Device.OperatingSystem" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.ScreenResolution = "TelemetryContext.Device.ScreenResolution" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.Type = "TelemetryContext.Device.Type" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.InstrumentationKey = "TelemetryContext.InstrumentationKey" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Location.Ip = "TelemetryContext.Location.Ip" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Operation.CorrelationVector = "TelemetryContext.Operation.CorrelationVector" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Operation.Id = "TelemetryContext.Operation.Id" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Operation.Name = "TelemetryContext.Operation.Name" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Operation.ParentId = "TelemetryContext.Operation.ParentId" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Operation.SyntheticSource = "TelemetryContext.Operation.SyntheticSource" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Session.Id = "TelemetryContext.Session.Id" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Session.IsFirst = "TelemetryContext.Session.IsFirst" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.User.AccountId = "TelemetryContext.User.AccountId" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.User.AuthenticatedUserId = "TelemetryContext.User.AuthenticatedUserId" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.User.Id = "TelemetryContext.User.Id" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.User.UserAgent = "TelemetryContext.User.UserAgent" -> string
const Microsoft.ApplicationInsights.Metrics.MetricIdentifier.MaxDimensionsCount = 10 -> int
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants.AggregateKindDataKeys.Count = "Count" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants.AggregateKindDataKeys.Max = "Max" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants.AggregateKindDataKeys.Min = "Min" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants.AggregateKindDataKeys.StdDev = "StdDev" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants.AggregateKindDataKeys.Sum = "Sum" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.AggregateKindConstants.Constants.AggregateKindMoniker = "Microsoft.Azure.Measurement" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants.AggregateKindDataKeys.Count = "Count" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants.AggregateKindDataKeys.Max = "Max" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants.AggregateKindDataKeys.Min = "Min" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants.AggregateKindDataKeys.StdDev = "StdDev" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants.AggregateKindDataKeys.Sum = "Sum" -> string
const Microsoft.ApplicationInsights.Metrics.MetricSeriesConfigurationForMeasurement.Constants.AggregateKindMoniker = "Microsoft.Azure.Measurement" -> string
 

Heads-up: @SergeyKanzhelev @Dmitry-Matveev

Copy link
Member

@Dmitry-Matveev Dmitry-Matveev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please coordinate with Sergey on TrackMetric() API. There are still concerns about it being obsolete with this PR.

@macrogreg
Copy link
Contributor Author

Thank you, @Dmitry-Matveev , for the review.

Please coordinate with Sergey on TrackMetric() API. There are still concerns about it being obsolete with this PR.

@SergeyKanzhelev : You have asked some questions to which I all replied. Here is a link to that conversation for your convenience:
https://github.com/Microsoft/ApplicationInsights-dotnet/pull/735/files/1f151e21907f4408a8eb783fc0c1a05553fff20e#diff-a4553125b36a87ff02a1256a752265fc

Do you have any follow-up questions?

Thanks!

Copy link
Contributor

@SergeyKanzhelev SergeyKanzhelev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed public API judging by API file only

Microsoft.ApplicationInsights.Metric
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

historically we keep namespace Microsoft.ApplicationInsights clean. So developer has only option in intelliSense after typing Microsoft.ApplicaitonInsights to create a TelemetryClient. I remember we looked at implementation and only thing in root namespace was change in TelemetryClient. Is my recollection incorrect?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course I may not have the right historical perspective.
However, this is not quite correct:

I remember we looked at implementation and only thing in root namespace was change in TelemetryClient.

The public API service is identical to what we reviewed at the end of 2017 (barring the types that we made internal this week as a follow up to @Dmitry-Matveev 's feedback). At the time, I made a set of examples available, which are now also in the Core repo:

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/feature/PreAggMetrics.Master/Test/Microsoft.ApplicationInsights.Test/Shared/Metrics/MetricsExamples.cs

In that set of examples, you can find use case that get progressively more advanced. The goal was to enable the use cases from example 1 to be discovered via Intellisense without the need for additional namespace imports. In order to achieve that, the base namespace includes all types that may appear as parameters to the metric related TelemetryClient methods.

Please let me know if this answers your question.
If you require adjustments to these APIs, please request precisely the changes you would like to see so that I can make them.
Thank you.

Microsoft.ApplicationInsights.Metric.TryGetDataSeries(out Microsoft.ApplicationInsights.Metrics.MetricSeries series, bool createIfNotExists, params string[] dimensionValues) -> bool
Microsoft.ApplicationInsights.Metric.TryGetDataSeries(out Microsoft.ApplicationInsights.Metrics.MetricSeries series, string dimension1Value) -> bool
Microsoft.ApplicationInsights.Metric.TryGetDataSeries(out Microsoft.ApplicationInsights.Metrics.MetricSeries series, string dimension1Value, string dimension2Value) -> bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need Try alternative? Why not limit it to unconditional method? What customer will do when it returned false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this question.
The Try-pattern is employed here in-line with the Framework Design Guidelines, because the method for tracking a value may fail even if the user specifies valid parameters under non-trivial conditions:

A key goal of the metric APIs is to ensure that a service cannot fail due to mistakes in tracing and telemetry collection (nothing is absolute, so we strive for "unlikely to fail"). This includes preventing memory starvation due to unintentional combinatorial explosion in the number if time series.
For that a MetricConfiguration has options for SeriesCountLimit and ValuesPerDimensionLimit. If these limits are reached, but a TryTrackValue(..) call would result in the creation of a new time series, the call will return false and the value will not be tracked.

There are different approaches for handling dimension capping, so rather than prescribing the customer a specific approach, we make it easy to detect this case and to react to the circumstance. Please let me know if you would like me to discuss some of these approaches.

Notably, we do not offer exception-throwing TrackValue(..) equivalents to all TryTrackValue(..) methods. This is because appropriate usage of such TrackValue(..) methods would require them to always be used in a try-catch block. This is not appropriate for tracing and telemetry collection APIs, which should be easy to incorporate in existing code and must not break existing code.

Please let me know if this answers your question.
If you require adjustments to these APIs, please request precisely the changes you would like to see so that I can make them.
Thank you.

Microsoft.ApplicationInsights.Metrics.MetricManager.MetricManager(Microsoft.ApplicationInsights.Metrics.Extensibility.IMetricTelemetryPipeline telemetryPipeline) -> void
Microsoft.ApplicationInsights.Metrics.MetricManager.Metrics.get -> Microsoft.ApplicationInsights.Metrics.MetricsCollection
Microsoft.ApplicationInsights.Metrics.MetricSeries
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to expose it? I haven't looked at it yet, but curious. I understand there is a Metric that you get via GetMetric, aggregator that you can configure for customization. What else do we need?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize, but I am not sure what you mean by "it" in your question "do we need to expose it?".

The GitHub review tool more than 1 API to which this may refer. I will address your question to the best of my ability. Please let me know if you referred to a different API.

  • The read-only Metrics property of the Microsoft.ApplicationInsights.Metrics.MetricManager class:

This provides access to all metrics in the manager's scope. A key use case is to allow users to manage existing metrics. For instance, consider an long-running application that manages containers with a limited life-time and tracks metrics about those containers. When a container life-time has finished, the business system can be sure that no further metrics about this container will be sent. However, the telemetry subsystem does not have this information. The Metrics collection allows a user to release no longer needed metrics and free up the corresponding memory.

  • The Microsoft.ApplicationInsights.Metrics.MetricSeries class:

One of the primary requirements for the metrics APIs is to allow tracking 1000s of metric values per second with a small performance overhead. This requires the ability to obtain a handle to a specific metric series and to cache a reference to it so that it can be used to track values without the need for further look-ups. The MetricSeries class provides APIs for doing this without the need for any look-ups or object allocations.

This technique is discussed in detail in the samples 2 and 2a:
https://github.com/Microsoft/ApplicationInsights-dotnet/blob/feature/PreAggMetrics.Master/Test/Microsoft.ApplicationInsights.Test/Shared/Metrics/MetricsExamples.cs

Please let me know if this answers your question.
If you require adjustments to these APIs, please request precisely the changes you would like to see so that I can make them.
Thank you.

const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Cloud.RoleName = "TelemetryContext.Cloud.RoleName" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Component.Version = "TelemetryContext.Component.Version" -> string
const Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext.Device.Id = "TelemetryContext.Device.Id" -> string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need all these constants exposed publicly? Especially I concerned for the deprecated properties like device ID and screen resolution

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this question.
The usage, the reason and the background for the constants in MetricDimensionNames are described in detail in the doc comments for that class, as well as in the samples 2 and 5:

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/feature/PreAggMetrics.Master/Test/Microsoft.ApplicationInsights.Test/Shared/Metrics/MetricsExamples.cs

We have also previously discussed this, albeit briefly.

Please let me re-iterate some key background points to put the aforementioned resources in context:

A key feedback point for MetricManager v1 was that it did not allow to specify TelemetryContext properties. For example, if other kinds of telemetry are associated with a specific session or a specific operation name, they use the corresponding properties within the TelemetryContext to convey that information. However, metric aggregates produced by MetricManager v1 did allow access to the TelemetryContext, and such information needed to be stored as a normal dimensions. The inability to overcome this inconsistency was named as a release blocker by the SDK team at that time.

Exposing TelemetryContext for metric series remains impractical because series represent aggregation scopes and require immutable identities that are fast to compare. So, to provide a solution for the described problem, we use well-defined dimension names. Dimensions with such names are treated as normal dimensions during pre-aggregation, but when the resulting aggregates are serialized for transport, the values of such dimensions are stored within the corresponding fields of the TelemetryContext.

Please let me know if this answers your question.
If you require adjustments to these APIs, please request precisely the changes you would like to see so that I can make them. Especially, if certain fields do no longer belong into the TelemetryContext and should be treated as normal dimensions, we should remove them from the constants list.
Thank you.

static Microsoft.ApplicationInsights.Metrics.MetricIdentifier.DefaultMetricNamespace.set -> void
static Microsoft.ApplicationInsights.Metrics.TelemetryConfigurationExtensions.GetMetricManager(this Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration telemetryPipeline) -> Microsoft.ApplicationInsights.Metrics.MetricManager
static readonly Microsoft.ApplicationInsights.MetricConfigurations.Common -> Microsoft.ApplicationInsights.MetricConfigurations
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The review tool shows 3 APIs with return types and parameters including 5 types. Could you please specify what you refer to and what changes, if any, you require?

override Microsoft.ApplicationInsights.Metrics.MetricConfiguration.Equals(object obj) -> bool
override Microsoft.ApplicationInsights.Metrics.MetricConfiguration.GetHashCode() -> int
override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.Equals(object otherObj) -> bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Judging by name MetricIdentifier sounds like too low level of a detail

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please help me understand your question? Do you have concerns with the name "MetricIdentifier"? Do you have concerns with the usage of the type MetricIdentifier? Something else? The level of detail is to low for what specifically? What detail exactly do you refer to?

In order to provide as much context as possible, let me please describe the purpose and the usage of the MetricIdentifier class.

A metric is a grouping of one or more metric data series. Besides the actual data (aka the metric series) such a group has 2 attributes:

i) The metric configuration. It is a set of settings that define the behavior of the group and the contained data. For example, it specifies how values are aggregated, how many series are allowed in the group and so on. Metrics with the same configuration may contain different data, but they will exhibit the same behavior. You can think of this as loosely corresponding to a "class type" for a metric.

ii) The metric identifier. It is a set of settings that define the identity of the group so that it can be differentiated from any other groups (aka from other metrics). The identifier includes the metric name, the metric namespace, as well as the number and the names of the metric dimensions. An identifier uniquely identifies a metric within the respective scope. You can think of this as loosely corresponding to a "class instance id" of a metric.

Please let me know if this answers your question.
If you require adjustments to these APIs, please request precisely the changes you would like to see so that I can make them.
Thank you.

static Microsoft.ApplicationInsights.Metrics.TelemetryConfigurationExtensions.GetMetricManager(this Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration telemetryPipeline) -> Microsoft.ApplicationInsights.Metrics.MetricManager
static readonly Microsoft.ApplicationInsights.MetricConfigurations.Common -> Microsoft.ApplicationInsights.MetricConfigurations
virtual Microsoft.ApplicationInsights.Metrics.MetricConfiguration.Equals(Microsoft.ApplicationInsights.Metrics.MetricConfiguration other) -> bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MetricConfiguration namespace looks empty - only two methods?

Copy link
Contributor Author

@macrogreg macrogreg Apr 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what you mean by this comment. Please let me make some educated guesses about what you mean and try to provide as much information as possible.

MetricConfiguration namespace looks empty - only two methods?

Please let me provide additional details here.
MetricConfigurations represents an easily discoverable (via Intellisense) point for pre-defined metric configurations:

The common TelemetryClient.GetMetric(..) method has several overloads expecting a parameter of type MetricConfiguration. When attempting to type this term, the user discovers the static instance MetricConfigurations.Common (in the same namespace). We use extension methods to define common metric configurations:
In this version, the base SDK defines MetricConfigurations.Common.Measurement().
The Metrics.Extensions package is planned to add:

  • MetricConfigurations.Common.Accumulator()
  • MetricConfigurations.Common.Gauge()
  • MetricConfigurations.Common.NaiveDistinctCount()

You have seen the complete ready and tested code for those additional configurations and you requested that we move it to a different repo. It is currently available in the SDK Labs Repo.
Users may also add their own common configurations via the same extension method mechanism.

Please let me know if this answers your question.
If you require adjustments to these APIs, please request precisely the changes you would like to see so that I can make them.
Thank you.

@SergeyKanzhelev SergeyKanzhelev dismissed their stale review April 2, 2018 17:58

alex klimov asked to unblock

@macrogreg macrogreg merged commit a4a7131 into develop Apr 2, 2018
TimothyMothra pushed a commit that referenced this pull request Oct 25, 2019
Support W3C incoming headers in opt-in mode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants