Skip to content

feat(Audience Evaluation): Audience Logging #154

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

Merged
merged 12 commits into from
Mar 6, 2019

Conversation

oakbani
Copy link
Contributor

@oakbani oakbani commented Jan 8, 2019

Summary

This adds logging to audience evaluation.
For now, logging is limited to issues with user passed value and not the condition value (datafile).

Test plan

  • Updated Unit Tests in OptimizelyTest and DecisionServiceTest to assert only relevant logs. Position based logging had to be removed since isUserInExperiment is a static method and can not be mocked.
  • Added new tests for isUserInExperiment and CustomAttributeConditionEvaluator

Issues

  • OASIS-3854

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.2%) to 97.849% when pulling 49d4cdc on oakbani/logging-for-audience into c83981b on master.

2 similar comments
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.2%) to 97.849% when pulling 49d4cdc on oakbani/logging-for-audience into c83981b on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.2%) to 97.849% when pulling 49d4cdc on oakbani/logging-for-audience into c83981b on master.

@coveralls
Copy link

coveralls commented Jan 8, 2019

Coverage Status

Coverage increased (+0.2%) to 98.112% when pulling 9b9e3cc on oakbani/logging-for-audience into cc9dd78 on master.

@oakbani oakbani added the WIP Work in progress label Jan 25, 2019
# Conflicts:
#	src/Optimizely/DecisionService/DecisionService.php
#	src/Optimizely/Utils/CustomAttributeConditionEvaluator.php
#	src/Optimizely/Utils/Validator.php
#	tests/DecisionServiceTests/DecisionServiceTest.php
#	tests/OptimizelyTest.php
#	tests/UtilsTests/CustomAttributeConditionEvaluatorTest.php
#	tests/UtilsTests/ValidatorTest.php
todo: OptimizelyTest
@oakbani oakbani removed the WIP Work in progress label Jan 31, 2019
@rashidsp rashidsp added the WIP Work in progress label Feb 25, 2019
@rashidsp rashidsp removed the WIP Work in progress label Feb 26, 2019
Copy link
Contributor

@nchilada nchilada left a comment

Choose a reason for hiding this comment

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

Looking good! I've added some comments - a few edits for the log messages and log levels, and then a couple other questions that are probably safe to ignore.

@aliabbasrizvi can you review those questions on Monday?

const EVALUATING_AUDIENCE = "Starting to evaluate audience \"%s\" with conditions: %s.";
const INFINITE_ATTRIBUTE_VALUE = "Audience condition %s evaluated to UNKNOWN for user attribute \"%s\" is not in the range [-2^53, +2^53].";
const MISSING_ATTRIBUTE_VALUE = "Audience condition %s evaluated to UNKNOWN because no value was passed for user attribute \"%s\".";
const NULL_ATTRIBUTE_VALUE = "Audience condition \"%s\" evaluated to UNKNOWN because a null value was passed for user attribute \"%s\".";
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const NULL_ATTRIBUTE_VALUE = "Audience condition \"%s\" evaluated to UNKNOWN because a null value was passed for user attribute \"%s\".";
const NULL_ATTRIBUTE_VALUE = "Audience condition %s evaluated to UNKNOWN because a null value was passed for user attribute \"%s\".";

const NULL_ATTRIBUTE_VALUE = "Audience condition \"%s\" evaluated to UNKNOWN because a null value was passed for user attribute \"%s\".";
const UNEXPECTED_TYPE = "Audience condition %s evaluated to UNKNOWN because a value of type \"%s\" was passed for user attribute \"%s\".";

const UNKNOWN_CONDITION_TYPE = "Audience condition \"%s\" uses an unknown condition type. You may need to upgrade to anewer release of the Optimizely SDK.";
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const UNKNOWN_CONDITION_TYPE = "Audience condition \"%s\" uses an unknown condition type. You may need to upgrade to anewer release of the Optimizely SDK.";
const UNKNOWN_CONDITION_TYPE = "Audience condition %s uses an unknown condition type. You may need to upgrade to anewer release of the Optimizely SDK.";

const UNEXPECTED_TYPE = "Audience condition %s evaluated to UNKNOWN because a value of type \"%s\" was passed for user attribute \"%s\".";

const UNKNOWN_CONDITION_TYPE = "Audience condition \"%s\" uses an unknown condition type. You may need to upgrade to anewer release of the Optimizely SDK.";
const UNKNOWN_CONDITION_VALUE = "Audience condition \"%s\" has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK.";
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const UNKNOWN_CONDITION_VALUE = "Audience condition \"%s\" has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK.";
const UNKNOWN_CONDITION_VALUE = "Audience condition %s has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK.";


const UNKNOWN_CONDITION_TYPE = "Audience condition \"%s\" uses an unknown condition type. You may need to upgrade to anewer release of the Optimizely SDK.";
const UNKNOWN_CONDITION_VALUE = "Audience condition \"%s\" has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK.";
const UNKNOWN_MATCH_TYPE = "Audience condition \"%s\" uses an unknown match type. You may need to upgrade to a newer release of the Optimizely SDK.";
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const UNKNOWN_MATCH_TYPE = "Audience condition \"%s\" uses an unknown match type. You may need to upgrade to a newer release of the Optimizely SDK.";
const UNKNOWN_MATCH_TYPE = "Audience condition %s uses an unknown match type. You may need to upgrade to a newer release of the Optimizely SDK.";

const AUDIENCE_EVALUATION_RESULT_COMBINED = "Audiences for experiment \"%s\" collectively evaluated to %s.";
const EVALUATING_AUDIENCES_COMBINED = "Evaluating audiences for experiment \"%s\": %s.";
const EVALUATING_AUDIENCE = "Starting to evaluate audience \"%s\" with conditions: %s.";
const INFINITE_ATTRIBUTE_VALUE = "Audience condition %s evaluated to UNKNOWN for user attribute \"%s\" is not in the range [-2^53, +2^53].";
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const INFINITE_ATTRIBUTE_VALUE = "Audience condition %s evaluated to UNKNOWN for user attribute \"%s\" is not in the range [-2^53, +2^53].";
const INFINITE_ATTRIBUTE_VALUE = "Audience condition %s evaluated to UNKNOWN because the number value for user attribute \"%s\" is not in the range [-2^53, +2^53].";

*
* @return boolean Representing whether user meets audience conditions to be in experiment or not.
*/
public static function isUserInExperiment($config, $experiment, $userAttributes)
public static function isUserInExperiment($config, $experiment, $userAttributes, $logger)
Copy link
Contributor

Choose a reason for hiding this comment

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

Huh, I would have expected this function to be in DecisionService.php or AudienceSomethingSomething.php, but it's fine since this is pre-existing and doesn't really matter.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is ok to leave it here for now.

}

if ($userValue === null) {
$this->logger->log(Logger::WARNING, sprintf(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
$this->logger->log(Logger::WARNING, sprintf(
$this->logger->log(Logger::DEBUG, sprintf(

json_encode($audience->getConditionsList())
));

$conditionTreeEvaluator = new ConditionTreeEvaluator();
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be slightly more efficient to hoist this object instantiation out of the $evaluateAudience closure...I'm not sure how well PHP is able to do such optimizations.

But it probably doesn't matter since ConditionTreeEvaluator doesn't have a constructor or member variables, and because there probably won't be many audiences per experiment/feature.

));
return null;
} else {
$userValue = $this->userAttributes[$conditionName];
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: can we pull this out of the else block? That'd make it clearer that $userValue is always defined by the time we get to the $userValue === null check.

Copy link
Contributor

@nchilada nchilada left a comment

Choose a reason for hiding this comment

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

Looks good. Thanks for all the updates!

Copy link
Contributor

@aliabbasrizvi aliabbasrizvi left a comment

Choose a reason for hiding this comment

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

LGTM

@aliabbasrizvi aliabbasrizvi merged commit bdb4032 into master Mar 6, 2019
@aliabbasrizvi aliabbasrizvi deleted the oakbani/logging-for-audience branch March 6, 2019 09:46
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.

None yet

5 participants