Skip to content

Commit 4d7cf6b

Browse files
Gerald W. LesterGerald W. Lester
Gerald W. Lester
authored and
Gerald W. Lester
committed
Add logger to class inits.
1 parent 68e2c8e commit 4d7cf6b

File tree

3 files changed

+37
-32
lines changed

3 files changed

+37
-32
lines changed

aws_lambda_powertools/utilities/feature_flags/appconfig.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
from .base import StoreProvider
1111
from .exceptions import ConfigurationStoreError, StoreClientError
1212

13-
logger = logging.getLogger(__name__)
14-
1513
TRANSFORM_TYPE = "json"
1614

1715

@@ -25,6 +23,7 @@ def __init__(
2523
sdk_config: Optional[Config] = None,
2624
envelope: Optional[str] = "",
2725
jmespath_options: Optional[Dict] = None,
26+
logger=None,
2827
):
2928
"""This class fetches JSON schemas from AWS AppConfig
3029
@@ -46,6 +45,10 @@ def __init__(
4645
Alternative JMESPath options to be included when filtering expr
4746
"""
4847
super().__init__()
48+
if logger == None:
49+
self.logger = logging.getLogger(__name__)
50+
else:
51+
self.logger = logger
4952
self.environment = environment
5053
self.application = application
5154
self.name = name

aws_lambda_powertools/utilities/feature_flags/feature_flags.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
from .base import StoreProvider
66
from .exceptions import ConfigurationStoreError
77

8-
logger = logging.getLogger(__name__)
9-
108

119
class FeatureFlags:
12-
def __init__(self, store: StoreProvider):
10+
def __init__(self, store: StoreProvider, logger=None):
1311
"""Evaluates whether feature flags should be enabled based on a given context.
1412
1513
It uses the provided store to fetch feature flag rules before evaluating them.
@@ -37,9 +35,12 @@ def __init__(self, store: StoreProvider):
3735
Store to use to fetch feature flag schema configuration.
3836
"""
3937
self._store = store
38+
if logger == None:
39+
self.logger = logging.getLogger(__name__)
40+
else:
41+
self.logger = logger
4042

41-
@staticmethod
42-
def _match_by_action(action: str, condition_value: Any, context_value: Any) -> bool:
43+
def _match_by_action(self, action: str, condition_value: Any, context_value: Any) -> bool:
4344
if not context_value:
4445
return False
4546
mapping_by_action = {
@@ -54,7 +55,7 @@ def _match_by_action(action: str, condition_value: Any, context_value: Any) -> b
5455
func = mapping_by_action.get(action, lambda a, b: False)
5556
return func(context_value, condition_value)
5657
except Exception as exc:
57-
logger.debug(f"caught exception while matching action: action={action}, exception={str(exc)}")
58+
self.loggerdebug(f"caught exception while matching action: action={action}, exception={str(exc)}")
5859
return False
5960

6061
def _evaluate_conditions(
@@ -65,7 +66,7 @@ def _evaluate_conditions(
6566
conditions = cast(List[Dict], rule.get(schema.CONDITIONS_KEY))
6667

6768
if not conditions:
68-
logger.debug(
69+
self.loggerdebug(
6970
f"rule did not match, no conditions to match, rule_name={rule_name}, rule_value={rule_match_value}, "
7071
f"name={feature_name} "
7172
)
@@ -77,13 +78,13 @@ def _evaluate_conditions(
7778
cond_value = condition.get(schema.CONDITION_VALUE)
7879

7980
if not self._match_by_action(action=cond_action, condition_value=cond_value, context_value=context_value):
80-
logger.debug(
81+
self.loggerdebug(
8182
f"rule did not match action, rule_name={rule_name}, rule_value={rule_match_value}, "
8283
f"name={feature_name}, context_value={str(context_value)} "
8384
)
8485
return False # context doesn't match condition
8586

86-
logger.debug(f"rule matched, rule_name={rule_name}, rule_value={rule_match_value}, name={feature_name}")
87+
self.loggerdebug(f"rule matched, rule_name={rule_name}, rule_value={rule_match_value}, name={feature_name}")
8788
return True
8889

8990
def _evaluate_rules(
@@ -94,12 +95,12 @@ def _evaluate_rules(
9495
rule_match_value = rule.get(schema.RULE_MATCH_VALUE)
9596

9697
# Context might contain PII data; do not log its value
97-
logger.debug(f"Evaluating rule matching, rule={rule_name}, feature={feature_name}, default={feat_default}")
98+
self.loggerdebug(f"Evaluating rule matching, rule={rule_name}, feature={feature_name}, default={feat_default}")
9899
if self._evaluate_conditions(rule_name=rule_name, feature_name=feature_name, rule=rule, context=context):
99100
return bool(rule_match_value)
100101

101102
# no rule matched, return default value of feature
102-
logger.debug(f"no rule matched, returning feature default, default={feat_default}, name={feature_name}")
103+
self.loggerdebug(f"no rule matched, returning feature default, default={feat_default}, name={feature_name}")
103104
return feat_default
104105
return False
105106

@@ -146,7 +147,7 @@ def get_configuration(self) -> Union[Dict[str, Dict], Dict]:
146147
```
147148
"""
148149
# parse result conf as JSON, keep in cache for max age defined in store
149-
logger.debug(f"Fetching schema from registered store, store={self._store}")
150+
self.loggerdebug(f"Fetching schema from registered store, store={self._store}")
150151
config = self._store.get_configuration()
151152
validator = schema.SchemaValidator(schema=config)
152153
validator.validate()
@@ -190,21 +191,21 @@ def evaluate(self, *, name: str, context: Optional[Dict[str, Any]] = None, defau
190191
try:
191192
features = self.get_configuration()
192193
except ConfigurationStoreError as err:
193-
logger.debug(f"Failed to fetch feature flags from store, returning default provided, reason={err}")
194+
self.loggerdebug(f"Failed to fetch feature flags from store, returning default provided, reason={err}")
194195
return default
195196

196197
feature = features.get(name)
197198
if feature is None:
198-
logger.debug(f"Feature not found; returning default provided, name={name}, default={default}")
199+
self.loggerdebug(f"Feature not found; returning default provided, name={name}, default={default}")
199200
return default
200201

201202
rules = feature.get(schema.RULES_KEY)
202203
feat_default = feature.get(schema.FEATURE_DEFAULT_VAL_KEY)
203204
if not rules:
204-
logger.debug(f"no rules found, returning feature default, name={name}, default={feat_default}")
205+
self.loggerdebug(f"no rules found, returning feature default, name={name}, default={feat_default}")
205206
return bool(feat_default)
206207

207-
logger.debug(f"looking for rule match, name={name}, default={feat_default}")
208+
self.loggerdebug(f"looking for rule match, name={name}, default={feat_default}")
208209
return self._evaluate_rules(feature_name=name, context=context, feat_default=bool(feat_default), rules=rules)
209210

210211
def get_enabled_features(self, *, context: Optional[Dict[str, Any]] = None) -> List[str]:
@@ -241,20 +242,20 @@ def get_enabled_features(self, *, context: Optional[Dict[str, Any]] = None) -> L
241242
try:
242243
features: Dict[str, Any] = self.get_configuration()
243244
except ConfigurationStoreError as err:
244-
logger.debug(f"Failed to fetch feature flags from store, returning empty list, reason={err}")
245+
self.loggerdebug(f"Failed to fetch feature flags from store, returning empty list, reason={err}")
245246
return features_enabled
246247

247-
logger.debug("Evaluating all features")
248+
self.loggerdebug("Evaluating all features")
248249
for name, feature in features.items():
249250
rules = feature.get(schema.RULES_KEY, {})
250251
feature_default_value = feature.get(schema.FEATURE_DEFAULT_VAL_KEY)
251252
if feature_default_value and not rules:
252-
logger.debug(f"feature is enabled by default and has no defined rules, name={name}")
253+
self.loggerdebug(f"feature is enabled by default and has no defined rules, name={name}")
253254
features_enabled.append(name)
254255
elif self._evaluate_rules(
255256
feature_name=name, context=context, feat_default=feature_default_value, rules=rules
256257
):
257-
logger.debug(f"feature's calculated value is True, name={name}")
258+
self.loggerdebug(f"feature's calculated value is True, name={name}")
258259
features_enabled.append(name)
259260

260261
return features_enabled

aws_lambda_powertools/utilities/feature_flags/schema.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
from .base import BaseValidator
66
from .exceptions import SchemaValidationError
77

8-
logger = logging.getLogger(__name__)
9-
108
RULES_KEY = "rules"
119
FEATURE_DEFAULT_VAL_KEY = "default"
1210
CONDITIONS_KEY = "conditions"
@@ -105,11 +103,15 @@ class SchemaValidator(BaseValidator):
105103
```
106104
"""
107105

108-
def __init__(self, schema: Dict[str, Any]):
106+
def __init__(self, schema: Dict[str, Any], logger=None):
109107
self.schema = schema
108+
if logger == None:
109+
self.logger = logging.getLogger(__name__)
110+
else:
111+
self.logger = logger
110112

111113
def validate(self) -> None:
112-
logger.debug("Validating schema")
114+
self.loggerdebug("Validating schema")
113115
if not isinstance(self.schema, dict):
114116
raise SchemaValidationError(f"Features must be a dictionary, schema={str(self.schema)}")
115117

@@ -125,7 +127,7 @@ def __init__(self, schema: Dict):
125127

126128
def validate(self):
127129
for name, feature in self.schema.items():
128-
logger.debug(f"Attempting to validate feature '{name}'")
130+
self.loggerdebug(f"Attempting to validate feature '{name}'")
129131
self.validate_feature(name, feature)
130132
rules = RulesValidator(feature=feature)
131133
rules.validate()
@@ -150,14 +152,14 @@ def __init__(self, feature: Dict[str, Any]):
150152

151153
def validate(self):
152154
if not self.rules:
153-
logger.debug("Rules are empty, ignoring validation")
155+
self.loggerdebug("Rules are empty, ignoring validation")
154156
return
155157

156158
if not isinstance(self.rules, dict):
157159
raise SchemaValidationError(f"Feature rules must be a dictionary, feature={self.feature_name}")
158160

159161
for rule_name, rule in self.rules.items():
160-
logger.debug(f"Attempting to validate rule '{rule_name}'")
162+
self.loggerdebug(f"Attempting to validate rule '{rule_name}'")
161163
self.validate_rule(rule=rule, rule_name=rule_name, feature_name=self.feature_name)
162164
conditions = ConditionsValidator(rule=rule, rule_name=rule_name)
163165
conditions.validate()
@@ -194,13 +196,12 @@ def validate(self):
194196
for condition in self.conditions:
195197
self.validate_condition(rule_name=self.rule_name, condition=condition)
196198

197-
@staticmethod
198-
def validate_condition(rule_name: str, condition: Dict[str, str]) -> None:
199+
def validate_condition(self,rule_name: str, condition: Dict[str, str]) -> None:
199200
if not condition or not isinstance(condition, dict):
200201
raise SchemaValidationError(f"Feature rule condition must be a dictionary, rule={rule_name}")
201202

202203
# Condition can contain PII data; do not log condition value
203-
logger.debug(f"Attempting to validate condition for '{rule_name}'")
204+
self.loggerdebug(f"Attempting to validate condition for '{rule_name}'")
204205
ConditionsValidator.validate_condition_action(condition=condition, rule_name=rule_name)
205206
ConditionsValidator.validate_condition_key(condition=condition, rule_name=rule_name)
206207
ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name)

0 commit comments

Comments
 (0)