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

Enable dim cap to Metrics API #1245

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointCon
Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Snapshot.get -> System.Uri
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.get -> string
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.set -> void
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointCon
Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Snapshot.get -> System.Uri
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.get -> string
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.set -> void
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointCon
Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Snapshot.get -> System.Uri
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.get -> string
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.set -> void
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointCon
Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Snapshot.get -> System.Uri
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.get -> string
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.ConnectionString.set -> void
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.EndpointContainer.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.get -> bool
Microsoft.ApplicationInsights.Metrics.MetricConfiguration.ApplyDimensionCapping.set -> void
1 change: 1 addition & 0 deletions src/Microsoft.ApplicationInsights/Metric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ internal Metric(MetricManager metricManager, MetricIdentifier metricIdentifier,
this.metricSeries = new MultidimensionalCube2<MetricSeries>(
totalPointsCountLimit: configuration.SeriesCountLimit - 1,
pointsFactory: this.CreateNewMetricSeries,
useDimensionCap: configuration.ApplyDimensionCapping,
dimensionValuesCountLimits: dimensionValuesCountLimits);

this.zeroDimSeriesList = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ internal class MultidimensionalCube2<TPoint>
private readonly Func<string[], TPoint> pointsFactory;

private int totalPointsCount;
private bool useDimensionCap;

public MultidimensionalCube2(Func<string[], TPoint> pointsFactory, params int[] dimensionValuesCountLimits)
: this(Int32.MaxValue, pointsFactory, dimensionValuesCountLimits)
Expand Down Expand Up @@ -83,6 +84,19 @@ public MultidimensionalCube2(int totalPointsCountLimit, Func<string[], TPoint> p
}
}

public MultidimensionalCube2(int totalPointsCountLimit, Func<string[], TPoint> pointsFactory, bool useDimensionCap, params int[] dimensionValuesCountLimits)
: this(totalPointsCountLimit, pointsFactory, dimensionValuesCountLimits)
{
this.useDimensionCap = useDimensionCap;
if (this.useDimensionCap)
{
for (int d = 0; d < this.dimensionValuesCountLimits.Length; d++)
{
this.dimensionValuesCountLimits[d] = this.dimensionValuesCountLimits[d] + 1;
}
}
}

public int DimensionsCount
{
get { return this.dimensionValuesCountLimits.Length; }
Expand Down Expand Up @@ -150,17 +164,36 @@ public MultidimensionalPointResult<TPoint> TryGetOrCreatePoint(params string[] c
return result;
}

this.pointCreationLock.Wait();
try
{
MultidimensionalPointResult<TPoint> result = this.TryCreatePoint(coordinates, pointMoniker);
return result;
}
finally
var res = this.LockAndCreatePoint(coordinates, pointMoniker);
if (this.useDimensionCap)
{
this.pointCreationLock.Release();
while (res.ResultCode == MultidimensionalPointResultCodes.Failure_SubdimensionsCountLimitReached)
{
int failedIndex = res.FailureCoordinateIndex;
coordinates[failedIndex] = "DIMENSION_CAPPED";

// retry
pointMoniker = this.GetPointMoniker(coordinates);
hasPoint = this.points.TryGetValue(pointMoniker, out point);
if (hasPoint)
{
var result = new MultidimensionalPointResult<TPoint>(MultidimensionalPointResultCodes.Success_ExistingPointRetrieved, point);
return result;
}

if (this.totalPointsCount >= this.totalPointsCountLimit)
{
var result = new MultidimensionalPointResult<TPoint>(MultidimensionalPointResultCodes.Failure_TotalPointsCountLimitReached, -1);
return result;
}

// retry with Other
res = this.LockAndCreatePoint(coordinates, pointMoniker, useReservedDimensionValue: true);
}
}
}

return res;
}

public Task<MultidimensionalPointResult<TPoint>> TryGetOrCreatePointAsync(params string[] coordinates)
{
Expand Down Expand Up @@ -258,7 +291,21 @@ private static string BuildPointMoniker(string[] coordinates)
return builder.ToString();
}

private MultidimensionalPointResult<TPoint> TryCreatePoint(string[] coordinates, string pointMoniker)
private MultidimensionalPointResult<TPoint> LockAndCreatePoint(string[] coordinates, string pointMoniker, bool useReservedDimensionValue = false)
{
this.pointCreationLock.Wait();
try
{
MultidimensionalPointResult<TPoint> result = this.TryCreatePoint(coordinates, pointMoniker, useReservedDimensionValue: useReservedDimensionValue);
return result;
}
finally
{
this.pointCreationLock.Release();
}
}

private MultidimensionalPointResult<TPoint> TryCreatePoint(string[] coordinates, string pointMoniker, bool useReservedDimensionValue = false)
{
#pragma warning disable SA1509 // Opening braces must not be preceded by blank line

Expand Down Expand Up @@ -293,7 +340,18 @@ private MultidimensionalPointResult<TPoint> TryCreatePoint(string[] coordinates,
HashSet<string> dimVals = this.dimensionValues[i];
string coordinateVal = coordinates[i];

if ((dimVals.Count >= this.dimensionValuesCountLimits[i]) && (false == dimVals.Contains(coordinateVal)))
int dimValueCap;
if (this.useDimensionCap)
{
// We do DimensionCap. Do not use the reserved value unless asked to do.
dimValueCap = useReservedDimensionValue ? this.dimensionValuesCountLimits[i] : this.dimensionValuesCountLimits[i] - 1;
}
else
{
dimValueCap = this.dimensionValuesCountLimits[i];
}

if ((dimVals.Count >= dimValueCap) && (false == dimVals.Contains(coordinateVal)))
{
reachedValsLimitDim = i;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ public MetricConfiguration(
/// that would normally result in new series will return <c>false</c>.</summary>
public int SeriesCountLimit { get; }

/// <summary>Gets or sets a value indicating whether dimension capping should be applied, when any indiviual dimension
/// exceeds its limit. If this flag is set, calls to <c>TrackValue(..)</c>, <c>TryGetDataSeries(..)</c> and similar
/// that would normally return false when cap is hit will return true, and the actual value of dimension will be replaced
/// by a constant <c>DIMENSION_CAPPED</c>.
/// The metric will continue to track the value, however, users should be beware that any metric filtering or
/// splitting involving a dimension which has the value DIMENSION_CAPPED, should be ignored.
/// </summary>
public bool ApplyDimensionCapping { get; set; }

/// <summary>Gets the configuration for how each series of this metric should be aggregated.</summary>
public IMetricSeriesConfiguration SeriesConfig { get; }

Expand Down