Skip to content

Commit

Permalink
FFM-11022 Fix Debug Logging performance (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
erdirowlands committed Apr 3, 2024
1 parent 3db3ae4 commit 2a5f94d
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 184 deletions.
32 changes: 10 additions & 22 deletions Connected Services/HarnessOpenAPIService/HarnessOpenAPIS.cs
Expand Up @@ -4,8 +4,6 @@
// </auto-generated>
//----------------------

using Microsoft.Extensions.Logging;

#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
Expand Down Expand Up @@ -65,9 +63,9 @@ public string BaseUrl
/// <param name="cluster">Unique identifier for the cluster for the account</param>
/// <returns>OK</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollection<FeatureConfig>> ClientEnvFeatureConfigsGetAsync(string environmentUUID, string cluster, ILogger logger)
public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollection<FeatureConfig>> ClientEnvFeatureConfigsGetAsync(string environmentUUID, string cluster)
{
return ClientEnvFeatureConfigsGetAsync(environmentUUID, cluster, System.Threading.CancellationToken.None, logger);
return ClientEnvFeatureConfigsGetAsync(environmentUUID, cluster, System.Threading.CancellationToken.None);
}

/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
Expand All @@ -81,7 +79,7 @@ public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollectio
/// <param name="cluster">Unique identifier for the cluster for the account</param>
/// <returns>OK</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<FeatureConfig>> ClientEnvFeatureConfigsGetAsync(string environmentUUID, string cluster, System.Threading.CancellationToken cancellationToken, ILogger logger)
public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<FeatureConfig>> ClientEnvFeatureConfigsGetAsync(string environmentUUID, string cluster, System.Threading.CancellationToken cancellationToken)
{
if (environmentUUID == null)
throw new System.ArgumentNullException("environmentUUID");
Expand Down Expand Up @@ -127,18 +125,13 @@ public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICol
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var rawResponseData = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
// Log the raw JSON response data
logger.LogInformation("Raw FlagJSON response data: {RawResponseData}", rawResponseData);

var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<FeatureConfig>>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
}
return objectResponse_.Object;
}

else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
Expand Down Expand Up @@ -167,7 +160,7 @@ public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICol
/// <param name="cluster">Unique identifier for the cluster for the account</param>
/// <returns>OK</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual System.Threading.Tasks.Task<FeatureConfig> ClientEnvFeatureConfigsGetAsync(string identifier, string environmentUUID, string cluster, ILogger logger)
public virtual System.Threading.Tasks.Task<FeatureConfig> ClientEnvFeatureConfigsGetAsync(string identifier, string environmentUUID, string cluster)
{
return ClientEnvFeatureConfigsGetAsync(identifier, environmentUUID, cluster, System.Threading.CancellationToken.None);
}
Expand Down Expand Up @@ -268,9 +261,9 @@ public virtual async System.Threading.Tasks.Task<FeatureConfig> ClientEnvFeature
/// <param name="cluster">Unique identifier for the cluster for the account</param>
/// <returns>OK</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Segment>> ClientEnvTargetSegmentsGetAsync(string environmentUUID, string cluster, ILogger logger)
public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Segment>> ClientEnvTargetSegmentsGetAsync(string environmentUUID, string cluster)
{
return ClientEnvTargetSegmentsGetAsync(environmentUUID, cluster, System.Threading.CancellationToken.None, logger);
return ClientEnvTargetSegmentsGetAsync(environmentUUID, cluster, System.Threading.CancellationToken.None);
}

/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
Expand All @@ -284,7 +277,7 @@ public virtual System.Threading.Tasks.Task<System.Collections.Generic.ICollectio
/// <param name="cluster">Unique identifier for the cluster for the account</param>
/// <returns>OK</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Segment>> ClientEnvTargetSegmentsGetAsync(string environmentUUID, string cluster, System.Threading.CancellationToken cancellationToken, ILogger logger)
public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<Segment>> ClientEnvTargetSegmentsGetAsync(string environmentUUID, string cluster, System.Threading.CancellationToken cancellationToken)
{
if (environmentUUID == null)
throw new System.ArgumentNullException("environmentUUID");
Expand Down Expand Up @@ -330,11 +323,6 @@ public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICol
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
var rawResponseData = await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
// Log the raw JSON response data
logger.LogInformation("Raw GroupSON response data: {RawResponseData}", rawResponseData);


var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<Segment>>(response_, headers_, cancellationToken).ConfigureAwait(false);
if (objectResponse_.Object == null)
{
Expand Down Expand Up @@ -413,9 +401,9 @@ public virtual async System.Threading.Tasks.Task<System.Collections.Generic.ICol
/// <param name="cluster">Unique identifier for the cluster for the account</param>
/// <returns>OK</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual System.Threading.Tasks.Task<Segment> ClientEnvTargetSegmentsGetAsync(string identifier, string environmentUUID, string cluster, ILogger logger)
public virtual System.Threading.Tasks.Task<Segment> ClientEnvTargetSegmentsGetAsync(string identifier, string environmentUUID, string cluster)
{
return ClientEnvTargetSegmentsGetAsync(identifier, environmentUUID, cluster, System.Threading.CancellationToken.None, logger);
return ClientEnvTargetSegmentsGetAsync(identifier, environmentUUID, cluster, System.Threading.CancellationToken.None);
}

/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
Expand All @@ -430,7 +418,7 @@ public virtual System.Threading.Tasks.Task<Segment> ClientEnvTargetSegmentsGetAs
/// <param name="cluster">Unique identifier for the cluster for the account</param>
/// <returns>OK</returns>
/// <exception cref="ApiException">A server side error occurred.</exception>
public virtual async System.Threading.Tasks.Task<Segment> ClientEnvTargetSegmentsGetAsync(string identifier, string environmentUUID, string cluster, System.Threading.CancellationToken cancellationToken, ILogger logger)
public virtual async System.Threading.Tasks.Task<Segment> ClientEnvTargetSegmentsGetAsync(string identifier, string environmentUUID, string cluster, System.Threading.CancellationToken cancellationToken)
{
if (identifier == null)
throw new System.ArgumentNullException("identifier");
Expand Down
66 changes: 34 additions & 32 deletions client/api/Evaluator.cs
Expand Up @@ -173,27 +173,28 @@ private bool CheckPreRequisite(FeatureConfig parentFeatureConfig, Target target)
private Variation Evaluate(FeatureConfig featureConfig, Target target)
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug("Evaluating: Flag({Flag}) Target({Target})",
ToStringHelper.FeatureConfigToString(featureConfig), target.ToString());

logger.LogDebug("Evaluating: Flag({@FeatureFlag}) Target({@Target})", new { FeatureFlag = featureConfig}, new { Target = target});


if (featureConfig.State == FeatureState.Off)
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug("Flag is off: Flag({Flag})", ToStringHelper.FeatureConfigToString(featureConfig));
logger.LogDebug("Flag is off: Flag({@Flag})", new { FeatureFlag = featureConfig});
return GetVariation(featureConfig.Variations, featureConfig.OffVariation);
}

// Check for specific targeting match
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug(
"Evaluating specific targeting: Flag({Flag})",
ToStringHelper.FeatureConfigToString(featureConfig));
"Evaluating specific targeting: Flag({@Flag})",
new { FeatureFlag = featureConfig});
var specificTargetingVariation =
EvaluateVariationMap(target, featureConfig.VariationToTargetMap, featureConfig.Feature);
if (specificTargetingVariation != null)
{
logger.LogDebug("Specific targeting matched: Flag({Flag}) Target({Target})",
ToStringHelper.FeatureConfigToString(featureConfig), target.ToString());
logger.LogDebug("Specific targeting matched: Flag({@Flag}) Target({@Target})",
new { FeatureFlag = featureConfig}, new { Target = target});
return GetVariation(featureConfig.Variations, specificTargetingVariation);
}

Expand All @@ -205,13 +206,13 @@ private Variation Evaluate(FeatureConfig featureConfig, Target target)
var defaultVariation = featureConfig.DefaultServe.Variation;
if (defaultVariation == null)
{
logger.LogWarning("Default serve variation not found: Flag({Flag})",
ToStringHelper.FeatureConfigToString(featureConfig));
logger.LogWarning("Default serve variation not found: Flag({@Flag})",
new { Flag = featureConfig});
return null;
}

logger.LogDebug("Default on rule matched: Target({Target}) Flag({Flag})",
target.ToString(), ToStringHelper.FeatureConfigToString(featureConfig));
logger.LogDebug("Default on rule matched: Target({@Target}) Flag({@Flag})",
new { Target = target}, new { Flag = featureConfig});
return GetVariation(featureConfig.Variations, defaultVariation);
}

Expand Down Expand Up @@ -256,8 +257,8 @@ private string EvaluateRules(FeatureConfig featureConfig, Target target)
// Invalid state: Log if Clauses are null
if (servingRule.Clauses == null)
{
logger.LogWarning("Clauses are null for servingRule {RuleId} in FeatureConfig {FeatureConfigId}",
servingRule.RuleId, ToStringHelper.FeatureConfigToString(featureConfig));
logger.LogWarning("Clauses are null for servingRule {RuleId} in FeatureConfig {@FeatureConfigId}",
servingRule.RuleId, new { Flag = featureConfig});
return null;
}

Expand All @@ -267,8 +268,8 @@ private string EvaluateRules(FeatureConfig featureConfig, Target target)
// Invalid state: Log if Serve is null
if (servingRule.Serve == null)
{
logger.LogWarning("Serve is null for rule ID {Rule} in FeatureConfig {FeatureConfig}",
servingRule.RuleId, ToStringHelper.FeatureConfigToString(featureConfig));
logger.LogWarning("Serve is null for rule ID {Rule} in FeatureConfig {@FeatureConfig}",
servingRule.RuleId, new { Flag = featureConfig});
return null;
}

Expand All @@ -277,8 +278,9 @@ private string EvaluateRules(FeatureConfig featureConfig, Target target)
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug(
"Percentage rollout applies to group rule, evaluating distribution: Target({Target}) Flag({Flag})",
target.ToString(), ToStringHelper.FeatureConfigToString(featureConfig));
"Percentage rollout applies to group rule, evaluating distribution: Target({@Target}) Flag({@Flag})",
new { Target = target}, new { Flag = featureConfig});


var distributionProcessor = new DistributionProcessor(servingRule.Serve, loggerFactory);
return distributionProcessor.loadKeyName(target);
Expand All @@ -287,8 +289,9 @@ private string EvaluateRules(FeatureConfig featureConfig, Target target)
// Invalid state: Log if the variation is null
if (servingRule.Serve.Variation == null)
{
logger.LogWarning("Serve.Variation is null for a rule in FeatureConfig {FeatureConfig}",
ToStringHelper.FeatureConfigToString(featureConfig));
logger.LogWarning("Serve.Variation is null for a rule in Flag({@FeatureConfig})",
new { Flag = featureConfig});

return null;
}

Expand All @@ -297,9 +300,8 @@ private string EvaluateRules(FeatureConfig featureConfig, Target target)

// Log if no applicable rule was found
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug("No applicable rule found for Target({Target}) Flag({FeatureConfig})",
target.ToString(), ToStringHelper.FeatureConfigToString(featureConfig));

logger.LogDebug("No applicable rule found for Target({@Target}) Flag({@FeatureConfig})",
new { Target = target}, new { Flag = featureConfig});
return null;
}

Expand All @@ -312,24 +314,24 @@ private bool IsTargetIncludedOrExcludedInSegment(List<string> segmentList, Targe
throw new InvalidCacheStateException(
$"Segment with identifier {segmentIdentifier} could not be found in the cache despite belonging to the flag.");

logger.LogDebug("Evaluating group rule: Group({Segment} Target({Target}))",
ToStringHelper.SegmentToString(segment), target.ToString());
logger.LogDebug("Evaluating group rule: Group({@Segment} Target({@Target}))",
new { Segment = segment}, new { Target = target});

// check exclude list
if (segment.Excluded != null && segment.Excluded.Any(t => t.Identifier.Equals(target.Identifier)))
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug("Group excluded rule matched: Target({TargetName}) Group({SegmentName})",
target.ToString(), ToStringHelper.SegmentToString(segment));
logger.LogDebug("Group excluded rule matched: Target({@TargetName}) Group({@SegmentName})",
new { Target = target}, new { Segment = segment});
return false;
}

// check include list
if (segment.Included != null && segment.Included.Any(t => t.Identifier.Equals(target.Identifier)))
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug("Group included rule matched: Target({TargetName}) Group({SegmentName})",
target.ToString(), ToStringHelper.SegmentToString(segment));
logger.LogDebug("Group included rule matched: Target({@TargetName}) Group({@SegmentName})",
new { Target = target}, new { Segment = segment});

return true;
}
Expand All @@ -338,8 +340,8 @@ private bool IsTargetIncludedOrExcludedInSegment(List<string> segmentList, Targe
if (segment.Rules == null)
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug("No group rules found in group: Group({SegmentName})",
ToStringHelper.SegmentToString(segment));
logger.LogDebug("No group rules found in group: Group({@SegmentName})",
new { Segment = segment});
return false;
}

Expand All @@ -348,8 +350,8 @@ private bool IsTargetIncludedOrExcludedInSegment(List<string> segmentList, Targe
{
if (logger.IsEnabled(LogLevel.Debug))
logger.LogDebug(
"Group condition rule matched: Condition({Condition}) Target({TargetName}) Group({SegmentName})",
ToStringHelper.ClauseToString(firstSuccess), target.ToString(), ToStringHelper.SegmentToString(segment));
"Group condition rule matched: Condition({@Condition}) Target({@TargetName}) Group({@SegmentName})",
new { Condition = firstSuccess}, new { Target = target}, new { Segment = segment});
return true;
}
}
Expand Down

0 comments on commit 2a5f94d

Please sign in to comment.