@@ -27,6 +27,7 @@ var ERROR_MESSAGES = enums.ERROR_MESSAGES;
2727var LOG_LEVEL = enums . LOG_LEVEL ;
2828var LOG_MESSAGES = enums . LOG_MESSAGES ;
2929var DECISION_SOURCES = enums . DECISION_SOURCES ;
30+ var AUDIENCE_EVALUATION_TYPES = enums . AUDIENCE_EVALUATION_TYPES ;
3031
3132/**
3233 * Optimizely's decision service that determines which variation of an experiment the user will be allocated to.
@@ -90,17 +91,39 @@ DecisionService.prototype.getVariation = function(configObj, experimentKey, user
9091 }
9192
9293 // Perform regular targeting and bucketing
93- if ( ! this . __checkIfUserIsInAudience ( configObj , experimentKey , userId , attributes ) ) {
94+ if ( ! this . __checkIfUserIsInAudience ( configObj , experimentKey , AUDIENCE_EVALUATION_TYPES . EXPERIMENT , userId , attributes , '' ) ) {
95+ var userDoesNotMeetConditionsLogMessage = sprintf (
96+ LOG_MESSAGES . USER_NOT_IN_EXPERIMENT ,
97+ MODULE_NAME ,
98+ userId ,
99+ experimentKey
100+ ) ;
101+ this . logger . log ( LOG_LEVEL . INFO , userDoesNotMeetConditionsLogMessage ) ;
94102 return null ;
95103 }
96104
97105 var bucketerParams = this . __buildBucketerParams ( configObj , experimentKey , bucketingId , userId ) ;
98106 var variationId = bucketer . bucket ( bucketerParams ) ;
99107 variation = configObj . variationIdMap [ variationId ] ;
100108 if ( ! variation ) {
109+ var userHasNoVariationLogMessage = sprintf (
110+ LOG_MESSAGES . USER_HAS_NO_VARIATION ,
111+ MODULE_NAME ,
112+ userId ,
113+ experimentKey
114+ ) ;
115+ this . logger . log ( LOG_LEVEL . DEBUG , userHasNoVariationLogMessage ) ;
101116 return null ;
102117 }
103118
119+ var userInVariationLogMessage = sprintf (
120+ LOG_MESSAGES . USER_HAS_VARIATION ,
121+ MODULE_NAME ,
122+ userId ,
123+ variation . key ,
124+ experimentKey
125+ ) ;
126+ this . logger . log ( LOG_LEVEL . INFO , userInVariationLogMessage ) ;
104127 // persist bucketing
105128 this . __saveUserProfile ( experiment , variation , userId , experimentBucketMap ) ;
106129
@@ -171,21 +194,24 @@ DecisionService.prototype.__getWhitelistedVariation = function(experiment, userI
171194
172195/**
173196 * Checks whether the user is included in experiment audience
174- * @param {Object } configObj The parsed project configuration object
175- * @param {string } experimentKey Key of experiment being validated
176- * @param {string } userId ID of user
177- * @param {Object } attributes Optional parameter for user's attributes
197+ * @param {Object } configObj The parsed project configuration object
198+ * @param {string } experimentKey Key of experiment being validated
199+ * @param {string } evaluationAttribute String representing experiment key or rule
200+ * @param {string } userId ID of user
201+ * @param {Object } attributes Optional parameter for user's attributes
202+ * @param {string } loggingKey String representing experiment key or rollout rule. To be used in log messages only.
178203 * @return {boolean } True if user meets audience conditions
179204 */
180- DecisionService . prototype . __checkIfUserIsInAudience = function ( configObj , experimentKey , userId , attributes ) {
205+ DecisionService . prototype . __checkIfUserIsInAudience = function ( configObj , experimentKey , evaluationAttribute , userId , attributes , loggingKey ) {
181206 var experimentAudienceConditions = projectConfig . getExperimentAudienceConditions ( configObj , experimentKey ) ;
182207 var audiencesById = projectConfig . getAudiencesById ( configObj ) ;
183208 this . logger . log (
184209 LOG_LEVEL . DEBUG ,
185210 sprintf (
186211 LOG_MESSAGES . EVALUATING_AUDIENCES_COMBINED ,
187212 MODULE_NAME ,
188- experimentKey ,
213+ evaluationAttribute ,
214+ loggingKey || experimentKey ,
189215 JSON . stringify ( experimentAudienceConditions )
190216 )
191217 ) ;
@@ -195,23 +221,13 @@ DecisionService.prototype.__checkIfUserIsInAudience = function(configObj, experi
195221 sprintf (
196222 LOG_MESSAGES . AUDIENCE_EVALUATION_RESULT_COMBINED ,
197223 MODULE_NAME ,
198- experimentKey ,
224+ evaluationAttribute ,
225+ loggingKey || experimentKey ,
199226 result . toString ( ) . toUpperCase ( )
200227 )
201228 ) ;
202229
203- if ( ! result ) {
204- var userDoesNotMeetConditionsLogMessage = sprintf (
205- LOG_MESSAGES . USER_NOT_IN_EXPERIMENT ,
206- MODULE_NAME ,
207- userId ,
208- experimentKey
209- ) ;
210- this . logger . log ( LOG_LEVEL . INFO , userDoesNotMeetConditionsLogMessage ) ;
211- return false ;
212- }
213-
214- return true ;
230+ return result ;
215231} ;
216232
217233/**
@@ -335,25 +351,9 @@ DecisionService.prototype.__saveUserProfile = function(experiment, variation, us
335351DecisionService . prototype . getVariationForFeature = function ( configObj , feature , userId , attributes ) {
336352 var experimentDecision = this . _getVariationForFeatureExperiment ( configObj , feature , userId , attributes ) ;
337353 if ( experimentDecision . variation !== null ) {
338- this . logger . log (
339- LOG_LEVEL . DEBUG ,
340- sprintf (
341- LOG_MESSAGES . USER_IN_FEATURE_EXPERIMENT ,
342- MODULE_NAME ,
343- userId ,
344- experimentDecision . variation . key ,
345- experimentDecision . experiment . key ,
346- feature . key
347- )
348- ) ;
349354 return experimentDecision ;
350355 }
351356
352- this . logger . log (
353- LOG_LEVEL . DEBUG ,
354- sprintf ( LOG_MESSAGES . USER_NOT_IN_FEATURE_EXPERIMENT , MODULE_NAME , userId , feature . key )
355- ) ;
356-
357357 var rolloutDecision = this . _getVariationForRollout ( configObj , feature , userId , attributes ) ;
358358 if ( rolloutDecision . variation !== null ) {
359359 this . logger . log ( LOG_LEVEL . DEBUG , sprintf ( LOG_MESSAGES . USER_IN_ROLLOUT , MODULE_NAME , userId , feature . key ) ) ;
@@ -456,50 +456,56 @@ DecisionService.prototype._getVariationForRollout = function(configObj, feature,
456456 // "everyone else", which will be evaluated separately outside this loop
457457 var endIndex = rollout . experiments . length - 1 ;
458458 var index ;
459- var experiment ;
459+ var rolloutRule ;
460460 var bucketerParams ;
461461 var variationId ;
462462 var variation ;
463+ var loggingKey ;
463464 for ( index = 0 ; index < endIndex ; index ++ ) {
464- experiment = configObj . experimentKeyMap [ rollout . experiments [ index ] . key ] ;
465+ rolloutRule = configObj . experimentKeyMap [ rollout . experiments [ index ] . key ] ;
466+ loggingKey = index + 1 ;
465467
466- if ( ! this . __checkIfUserIsInAudience ( configObj , experiment . key , userId , attributes ) ) {
468+ if ( ! this . __checkIfUserIsInAudience ( configObj , rolloutRule . key , AUDIENCE_EVALUATION_TYPES . RULE , userId , attributes , loggingKey ) ) {
467469 this . logger . log (
468470 LOG_LEVEL . DEBUG ,
469- sprintf ( LOG_MESSAGES . USER_DOESNT_MEET_CONDITIONS_FOR_TARGETING_RULE , MODULE_NAME , userId , index + 1 )
471+ sprintf ( LOG_MESSAGES . USER_DOESNT_MEET_CONDITIONS_FOR_TARGETING_RULE , MODULE_NAME , userId , loggingKey )
470472 ) ;
471473 continue ;
472474 }
473475
474476 this . logger . log (
475477 LOG_LEVEL . DEBUG ,
476- sprintf ( LOG_MESSAGES . USER_MEETS_CONDITIONS_FOR_TARGETING_RULE , MODULE_NAME , userId , index + 1 )
478+ sprintf ( LOG_MESSAGES . USER_MEETS_CONDITIONS_FOR_TARGETING_RULE , MODULE_NAME , userId , loggingKey )
477479 ) ;
478- bucketerParams = this . __buildBucketerParams ( configObj , experiment . key , bucketingId , userId ) ;
480+ bucketerParams = this . __buildBucketerParams ( configObj , rolloutRule . key , bucketingId , userId ) ;
479481 variationId = bucketer . bucket ( bucketerParams ) ;
480482 variation = configObj . variationIdMap [ variationId ] ;
481483 if ( variation ) {
482484 this . logger . log (
483485 LOG_LEVEL . DEBUG ,
484- sprintf ( LOG_MESSAGES . USER_BUCKETED_INTO_TARGETING_RULE , MODULE_NAME , userId , index + 1 )
486+ sprintf ( LOG_MESSAGES . USER_BUCKETED_INTO_TARGETING_RULE , MODULE_NAME , userId , loggingKey )
485487 ) ;
486488 return {
487- experiment : experiment ,
489+ experiment : rolloutRule ,
488490 variation : variation ,
489491 decisionSource : DECISION_SOURCES . ROLLOUT ,
490492 } ;
491493 } else {
492494 this . logger . log (
493495 LOG_LEVEL . DEBUG ,
494- sprintf ( LOG_MESSAGES . USER_NOT_BUCKETED_INTO_TARGETING_RULE , MODULE_NAME , userId , index + 1 )
496+ sprintf ( LOG_MESSAGES . USER_NOT_BUCKETED_INTO_TARGETING_RULE , MODULE_NAME , userId , loggingKey )
495497 ) ;
496498 break ;
497499 }
498500 }
499501
500- var everyoneElseExperiment = configObj . experimentKeyMap [ rollout . experiments [ endIndex ] . key ] ;
501- if ( this . __checkIfUserIsInAudience ( configObj , everyoneElseExperiment . key , userId , attributes ) ) {
502- bucketerParams = this . __buildBucketerParams ( configObj , everyoneElseExperiment . key , bucketingId , userId ) ;
502+ var everyoneElseRule = configObj . experimentKeyMap [ rollout . experiments [ endIndex ] . key ] ;
503+ if ( this . __checkIfUserIsInAudience ( configObj , everyoneElseRule . key , AUDIENCE_EVALUATION_TYPES . RULE , userId , attributes , 'Everyone Else' ) ) {
504+ this . logger . log (
505+ LOG_LEVEL . DEBUG ,
506+ sprintf ( LOG_MESSAGES . USER_MEETS_CONDITIONS_FOR_TARGETING_RULE , MODULE_NAME , userId , 'Everyone Else' )
507+ ) ;
508+ bucketerParams = this . __buildBucketerParams ( configObj , everyoneElseRule . key , bucketingId , userId ) ;
503509 variationId = bucketer . bucket ( bucketerParams ) ;
504510 variation = configObj . variationIdMap [ variationId ] ;
505511 if ( variation ) {
@@ -508,7 +514,7 @@ DecisionService.prototype._getVariationForRollout = function(configObj, feature,
508514 sprintf ( LOG_MESSAGES . USER_BUCKETED_INTO_EVERYONE_TARGETING_RULE , MODULE_NAME , userId )
509515 ) ;
510516 return {
511- experiment : everyoneElseExperiment ,
517+ experiment : everyoneElseRule ,
512518 variation : variation ,
513519 decisionSource : DECISION_SOURCES . ROLLOUT ,
514520 } ;
0 commit comments