diff --git a/GrowthBook/Api/FeatureRefreshWorker.cs b/GrowthBook/Api/FeatureRefreshWorker.cs index 72808c2..da339a2 100644 --- a/GrowthBook/Api/FeatureRefreshWorker.cs +++ b/GrowthBook/Api/FeatureRefreshWorker.cs @@ -49,8 +49,8 @@ public FeatureRefreshWorker(ILogger logger, IHttpClientFac _featuresApiEndpoint = $"{trimmedHostEndpoint}/api/features/{config.ClientKey}"; _serverSentEventsApiEndpoint = $"{trimmedHostEndpoint}/sub/{config.ClientKey}"; - _logger.LogDebug($"Features GrowthBook API endpoint: '{_featuresApiEndpoint}'"); - _logger.LogDebug($"Features GrowthBook API endpoint (Server Sent Events): '{_featuresApiEndpoint}'"); + _logger.LogDebug("Features GrowthBook API endpoint: \'{FeaturesApiEndpoint}\'", _featuresApiEndpoint); + _logger.LogDebug("Features GrowthBook API endpoint (Server Sent Events): \'{FeaturesApiEndpoint}\'", _featuresApiEndpoint); } public void Cancel() @@ -61,7 +61,7 @@ public void Cancel() public async Task> RefreshCacheFromApi(CancellationToken? cancellationToken = null) { - _logger.LogInformation($"Making an HTTP request to the default Features API endpoint '{_featuresApiEndpoint}'"); + _logger.LogInformation("Making an HTTP request to the default Features API endpoint \'{FeaturesApiEndpoint}\'", _featuresApiEndpoint); var httpClient = _httpClientFactory.CreateClient(ConfiguredClients.DefaultApiClient); @@ -120,8 +120,8 @@ private Task ListenForServerSentEvents() { try { - _logger.LogInformation($"Making an HTTP request to server sent events endpoint '{_serverSentEventsApiEndpoint}'"); - + _logger.LogInformation("Making an HTTP request to server sent events endpoint \'{ServerSentEventsApiEndpoint}\'", _serverSentEventsApiEndpoint); + var httpClient = _httpClientFactory.CreateClient(ConfiguredClients.ServerSentEventsApiClient); await httpClient.UpdateWithFeaturesStreamFrom(_serverSentEventsApiEndpoint, _logger, _config, _serverSentEventsListenerCancellation.Token, async features => @@ -133,11 +133,11 @@ await httpClient.UpdateWithFeaturesStreamFrom(_serverSentEventsApiEndpoint, _log } catch(HttpRequestException ex) { - _logger.LogError(ex, $"Encountered an HTTP exception during request to server sent events endpoint '{_serverSentEventsApiEndpoint}'"); + _logger.LogError(ex, "Encountered an HTTP exception during request to server sent events endpoint \'{ServerSentEventsApiEndpoint}\'", _serverSentEventsApiEndpoint); } catch(Exception ex) { - _logger.LogError(ex, $"Encountered an unhandled exception during request to server sent events endpoint '{_serverSentEventsApiEndpoint}'"); + _logger.LogError(ex, "Encountered an unhandled exception during request to server sent events endpoint \'{ServerSentEventsApiEndpoint}\'", _serverSentEventsApiEndpoint); } } @@ -151,16 +151,16 @@ private IDictionary GetFeaturesFrom(string json) if (featuresResponse.EncryptedFeatures.IsNullOrWhitespace()) { - _logger.LogInformation($"API response JSON contained no encrypted features, returning '{featuresResponse.FeatureCount}' unencrypted features"); + _logger.LogInformation("API response JSON contained no encrypted features, returning \'{FeaturesResponseFeatureCount}\' unencrypted features", featuresResponse.FeatureCount); return featuresResponse.Features; } _logger.LogInformation("API response JSON contained encrypted features, decrypting them now"); - _logger.LogDebug($"Attempting to decrypt features with the provided decryption key '{_config.DecryptionKey}'"); + _logger.LogDebug("Attempting to decrypt features with the provided decryption key \'{ConfigDecryptionKey}\'", _config.DecryptionKey); var decryptedFeaturesJson = featuresResponse.EncryptedFeatures.DecryptWith(_config.DecryptionKey); - _logger.LogDebug($"Completed attempt to decrypt features which resulted in plaintext value of '{decryptedFeaturesJson}'"); + _logger.LogDebug("Completed attempt to decrypt features which resulted in plaintext value of \'{DecryptedFeaturesJson}\'", decryptedFeaturesJson); var jsonObject = JObject.Parse(decryptedFeaturesJson); diff --git a/GrowthBook/Api/FeatureRepository.cs b/GrowthBook/Api/FeatureRepository.cs index 4c236b5..e7b76f4 100644 --- a/GrowthBook/Api/FeatureRepository.cs +++ b/GrowthBook/Api/FeatureRepository.cs @@ -42,7 +42,7 @@ public async Task> GetFeatures(GrowthBookRetrievalO if (_cache.IsCacheExpired || options?.ForceRefresh == true) { _logger.LogInformation("Cache has expired or option to force refresh was set, refreshing the cache from the API"); - _logger.LogDebug($"Cache expired: '{_cache.IsCacheExpired}' and option to force refresh: '{options?.ForceRefresh}'"); + _logger.LogDebug("Cache expired: \'{CacheIsCacheExpired}\' and option to force refresh: \'{OptionsForceRefresh}\'", _cache.IsCacheExpired, options?.ForceRefresh); var refreshTask = _backgroundRefreshWorker.RefreshCacheFromApi(cancellationToken); @@ -54,7 +54,7 @@ public async Task> GetFeatures(GrowthBookRetrievalO if (_cache.FeatureCount == 0 || options?.WaitForCompletion == true) { _logger.LogInformation("Either cache currently has no features or the option to wait for completion was set, waiting for cache to refresh"); - _logger.LogDebug($"Feature count: '{_cache.FeatureCount}' and option to wait for completion: '{options?.WaitForCompletion}'"); + _logger.LogDebug("Feature count: \'{CacheFeatureCount}\' and option to wait for completion: \'{OptionsWaitForCompletion}\'", _cache.FeatureCount, options?.WaitForCompletion); return await refreshTask; } diff --git a/GrowthBook/GrowthBook.cs b/GrowthBook/GrowthBook.cs index e4bf7a4..482c483 100644 --- a/GrowthBook/GrowthBook.cs +++ b/GrowthBook/GrowthBook.cs @@ -335,7 +335,7 @@ private void TryAssignExperimentResult(Experiment experiment, ExperimentResult r } private ExperimentResult RunExperiment(Experiment experiment, string featureId) - { + { // 1. Abort if there aren't enough variations present. if (experiment.Variations.IsNull() || experiment.Variations.Count < 2) @@ -387,7 +387,7 @@ private ExperimentResult RunExperiment(Experiment experiment, string featureId) if (hashValue.IsNullOrWhitespace()) { - _logger.LogDebug($"Aborting experiment, unable to locate a value for the experiment hash attribute '{experiment.HashAttribute}'"); + _logger.LogDebug("Aborting experiment, unable to locate a value for the experiment hash attribute \'{ExperimentHashAttribute}\'", experiment.HashAttribute); return GetExperimentResult(experiment, featureId: featureId); } @@ -399,11 +399,11 @@ private ExperimentResult RunExperiment(Experiment experiment, string featureId) { _logger.LogDebug("Aborting experiment, filters have been applied and matched this run"); return GetExperimentResult(experiment, featureId: featureId); - } + } } else if (experiment.Namespace != null && !ExperimentUtilities.InNamespace(hashValue, experiment.Namespace)) { - _logger.LogDebug($"Aborting experiment, not within the specified namespace '{experiment.Namespace}'"); + _logger.LogDebug("Aborting experiment, not within the specified namespace \'{ExperimentNamespace}\'", experiment.Namespace); return GetExperimentResult(experiment, featureId: featureId); } @@ -448,7 +448,7 @@ private ExperimentResult RunExperiment(Experiment experiment, string featureId) // 12. Run the experiment and track the result if we haven't seen this one before. - _logger.LogInformation($"Participation in experiment with key '{experiment.Key}' is allowed, running the experiment"); + _logger.LogInformation("Participation in experiment with key \'{ExperimentKey}\' is allowed, running the experiment", experiment.Key); var result = GetExperimentResult(experiment, assigned, true, featureId, variationHash); TryToTrack(experiment, result); @@ -475,7 +475,7 @@ private bool IsFilteredOut(IEnumerable filters) if (hashValue.IsNullOrWhitespace()) { - _logger.LogDebug($"Attributes are missing a filter's hash attribute of '{filter.Attribute}', marking as filtered out"); + _logger.LogDebug("Attributes are missing a filter\'s hash attribute of \'{FilterAttribute}\', marking as filtered out", filter.Attribute); return true; } @@ -485,7 +485,7 @@ private bool IsFilteredOut(IEnumerable filters) if (!isInAnyRange) { - _logger.LogDebug($"This run is not in any range associated with a filter, marking as filtered out"); + _logger.LogDebug("This run is not in any range associated with a filter, marking as filtered out"); return true; } } @@ -505,7 +505,7 @@ private bool IsIncludedInRollout(string seed, string hashAttribute = null, Bucke if (hashValue is null) { - _logger.LogDebug($"Attributes do not have a value for hash attribute '{hashAttribute}', marking as excluded from rollout"); + _logger.LogDebug("Attributes do not have a value for hash attribute \'{HashAttribute}\', marking as excluded from rollout", hashAttribute); return false; } @@ -588,7 +588,7 @@ private void TryToTrack(Experiment experiment, ExperimentResult result) } catch (Exception ex) { - _logger.LogError(ex, $"Encountered unhandled exception during tracking callback for experiment with combined key '{key}'"); + _logger.LogError(ex, "Encountered unhandled exception during tracking callback for experiment with combined key \'{Key}\'", key); } } } diff --git a/GrowthBook/Providers/ConditionEvaluationProvider.cs b/GrowthBook/Providers/ConditionEvaluationProvider.cs index 4f222ea..f4af7d0 100644 --- a/GrowthBook/Providers/ConditionEvaluationProvider.cs +++ b/GrowthBook/Providers/ConditionEvaluationProvider.cs @@ -20,7 +20,7 @@ internal sealed class ConditionEvaluationProvider : IConditionEvaluationProvider public bool EvalCondition(JToken attributes, JObject condition) { _logger.LogInformation("Beginning to evaluate attributes based on the provided JSON condition"); - _logger.LogDebug($"Attribute evaluation is based on the JSON condition '{condition}'"); + _logger.LogDebug("Attribute evaluation is based on the JSON condition \'{Condition}\'", condition); if (condition.ContainsKey("$or")) { @@ -108,7 +108,7 @@ private bool EvalAnd(JToken attributes, JArray conditions) /// True if the condition value matches the attribute value. private bool EvalConditionValue(JToken conditionValue, JToken attributeValue) { - _logger.LogDebug($"Evaluating condition value '{conditionValue}'"); + _logger.LogDebug("Evaluating condition value \'{ConditionValue}\'", conditionValue); if (conditionValue.Type == JTokenType.Object) { @@ -143,7 +143,7 @@ private bool ElemMatch(JObject condition, JToken attributeValue) { if (attributeValue?.Type != JTokenType.Array) { - _logger.LogDebug($"Unable to match array elements with a non-array type of '{attributeValue.Type}'"); + _logger.LogDebug("Unable to match array elements with a non-array type of '{AttributeValueType}'", attributeValue.Type); return false; } @@ -162,7 +162,7 @@ private bool ElemMatch(JObject condition, JToken attributeValue) return false; } - + /// /// A switch that handles all the possible operators. /// @@ -172,7 +172,7 @@ private bool ElemMatch(JObject condition, JToken attributeValue) /// private bool EvalOperatorCondition(string op, JToken attributeValue, JToken conditionValue) { - _logger.LogDebug($"Evaluating operator condition '{op}'"); + _logger.LogDebug("Evaluating operator condition \'{Op}\'", op); if (op == "$eq") { @@ -311,7 +311,7 @@ private bool EvalOperatorCondition(string op, JToken attributeValue, JToken cond return CompareVersions(attributeValue, conditionValue, x => x >= 0); } - _logger.LogWarning($"Unable to handle unsupported operator condition '{op}', failing the condition"); + _logger.LogWarning("Unable to handle unsupported operator condition \'{Op}\', failing the condition", op); return false; }