Skip to content

Conversation

@yasirfolio3
Copy link
Contributor

@yasirfolio3 yasirfolio3 commented Jul 14, 2020

Summary

  • Added and updated missing audience evaluation logs.

Testplan

  • All unit tests and FSC must pass.

Performance

There was no significant hit observed.

Master with default log level: 8.5s
Master with debug log level: 47.5s

PR changes with default loglevel: 8.5s
PR changes with debug log level: 48s

Used this code to measure performance.

	logging.SetLogLevel(logging.LogLevelDebug)
	optimizelyFactory := &client.OptimizelyFactory{SDKKey: ""}
	datafile, err := ioutil.ReadFile(filepath.Clean(path.Join(os.Getenv("DATAFILES_DIR"), "100_entities.json")))
	if err != nil {
		log.Fatal(err)
	}
	optimizelyFactory.Datafile = datafile
	client, err := optimizelyFactory.Client()
	start := time.Now()
	count := 5000
	for i := 0; i < count; i++ {
		client.GetEnabledFeatures(entities.UserContext{ID: "", Attributes: map[string]interface{}{}})
	}
	elapsed := time.Since(start)
	log.Printf("took %s", elapsed)

Issues

https://optimizely.atlassian.net/browse/OASIS-6816

@@ -1,45 +0,0 @@
/****************************************************************************
Copy link
Contributor

Choose a reason for hiding this comment

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

Why deleted this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this file wasn't being used anywhere throughout the sdk and was throwing syntax errors due to the changes made in this PR.

if condition.Type != customAttributeType {
return false, fmt.Errorf(`unable to evaluator condition of type "%s"`, condition.Type)

c.logger.Warning(fmt.Sprintf(string(logging.UnknownConditionType), condition.StringRepresentation))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why string is needed? string(logging.UnknownConditionType)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since UnknownConditionType is of custom type, we must convert it to string before formatting.

case exactMatchType:
matcher = matchers.ExactMatcher{
Condition: condition,
Logger: c.logger,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why logger not passed in existsMatchType

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No logs were required inside exists.

Copy link
Contributor

@msohailhussain msohailhussain left a comment

Choose a reason for hiding this comment

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

first pass

Logger: c.logger,
}
default:
c.logger.Warning(fmt.Sprintf(string(logging.UnknownMatchType), condition.StringRepresentation))
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use format specifier.

}

return false, fmt.Errorf("audience condition %s evaluated to NULL because the condition value type is not supported", m.Condition.Name)
return matchGtOrLt(user, m.Condition, m.Logger, false)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we didn't only add log here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

since both gt and lt matchers were very similar, linter was throwing lines are duplicate error.

}

// GetAttribute returns the value for the specified attribute name in the attributes map. Returns error if not found.
func (u UserContext) GetAttribute(attrName string) (interface{}, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why added this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

for InvalidAttributeValueType log, we required the raw attribute value to log its original type.

@@ -0,0 +1,60 @@
/****************************************************************************
* Copyright 2019-2020, Optimizely, Inc. and contributors *
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it started in 2019?

package logging

// LogMessage defines string type for log messages
type LogMessage string
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure if this is the right location to add log messages. Let's discuss offline.

if condition.Type != customAttributeType {
return false, fmt.Errorf(`unable to evaluator condition of type "%s"`, condition.Type)

c.logger.Warning(fmt.Sprintf(string(logging.UnknownConditionType), condition.StringRepresentation))
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't really need two Strings. Just pass the same in fmt.Errorf

Copy link
Contributor

Choose a reason for hiding this comment

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

I will confirm and let you know.


if !user.CheckAttributeExists(m.Condition.Name) {
m.Logger.Debug(fmt.Sprintf(logging.NullUserAttribute.String(), m.Condition.StringRepresentation, m.Condition.Name))
return false, fmt.Errorf(`no attribute named "%s"`, m.Condition.Name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we don't return same logging message?

@msohailhussain msohailhussain marked this pull request as ready for review July 15, 2020 22:49
@msohailhussain msohailhussain requested a review from a team as a code owner July 15, 2020 22:49
@msohailhussain msohailhussain changed the title refact(audience-logs): Added and refactored audience evaluation logs. (WIP) refact(audience-logs): Added and refactored audience evaluation logs. Jul 15, 2020
Copy link
Contributor

@mikecdavis mikecdavis left a comment

Choose a reason for hiding this comment

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

LGTM, one nit on the matchGtOrLt refactor.

return matchGtOrLt(condition, user, logger, true)
}

func matchGtOrLt(condition entities.Condition, user entities.UserContext, logger logging.OptimizelyLogProducer, gtMatch bool) (bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit, but If we make this a pure comparator and return (int, bool) e.g. -1, 0, 1, then we can drop the gtMatch bool which is a bit awkward. Then consumers would look like:

func GtMatcher(condition entities.Condition, user entities.UserContext, logger logging.OptimizelyLogProducer) (bool, error) {
	res, err := compare(condition, user, logger)
	if err := nil {
		return false, err
	}
	return res > 0, nil
}

func LtMatcher(condition entities.Condition, user entities.UserContext, logger logging.OptimizelyLogProducer) (bool, error) {
	res, err := compare(condition, user, logger)
	if err := nil {
		return false, err
	}
	return res < 0, nil
}

This would match the logic in the semver PR here

Copy link
Contributor

@msohailhussain msohailhussain left a comment

Choose a reason for hiding this comment

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

lgtm

@mikeproeng37 mikeproeng37 merged commit 6974ef4 into master Aug 21, 2020
@mikeproeng37 mikeproeng37 deleted the yasir/fix-audienceeval-logs branch August 21, 2020 17:17
@yasirfolio3 yasirfolio3 restored the yasir/fix-audienceeval-logs branch August 24, 2020 07:23
@yasirfolio3 yasirfolio3 deleted the yasir/fix-audienceeval-logs branch August 24, 2020 08:08
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.

6 participants