From ccbff2c5e46f69274230fc5ddc3cfb90a283d013 Mon Sep 17 00:00:00 2001 From: Federico Bond Date: Fri, 26 Jan 2024 23:52:33 -0300 Subject: [PATCH] feat: improve logging setup (#261) Signed-off-by: Federico Bond --- README.md | 2 +- openfeature/client.py | 14 +++++++++++++- openfeature/hook/hook_support.py | 4 +++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 935454d2..48736d38 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ client.get_boolean_flag("my-flag", False, flag_evaluation_options=options) ### Logging -Logging customization is not yet available in the Python SDK. +The OpenFeature SDK logs to the `openfeature` logger using the `logging` package from the Python Standard Library. ### Named clients diff --git a/openfeature/client.py b/openfeature/client.py index 9b842272..4c8d8abe 100644 --- a/openfeature/client.py +++ b/openfeature/client.py @@ -27,6 +27,8 @@ from openfeature.provider.no_op_provider import NoOpProvider from openfeature.provider.provider import AbstractProvider +logger = logging.getLogger("openfeature") + GetDetailCallable = typing.Union[ typing.Callable[ [str, bool, typing.Optional[EvaluationContext]], FlagResolutionDetails[bool] @@ -313,6 +315,12 @@ def evaluate_flag_details( return flag_evaluation except OpenFeatureError as err: + logger.exception( + "Error %s while evaluating flag with key: '%s'", + err.error_code, + flag_key, + ) + error_hooks(flag_type, hook_context, err, reversed_merged_hooks, hook_hints) return FlagEvaluationDetails( @@ -325,6 +333,10 @@ def evaluate_flag_details( # Catch any type of exception here since the user can provide any exception # in the error hooks except Exception as err: # pragma: no cover + logger.exception( + "Unable to correctly evaluate flag with key: '%s'", flag_key + ) + error_hooks(flag_type, hook_context, err, reversed_merged_hooks, hook_hints) error_message = getattr(err, "error_message", str(err)) @@ -363,7 +375,7 @@ def _create_provider_evaluation( ) if not self.provider: - logging.info("No provider configured, using no-op provider.") + logger.info("No provider configured, using no-op provider.") self.provider = NoOpProvider() get_details_callables: typing.Mapping[FlagType, GetDetailCallable] = { diff --git a/openfeature/hook/hook_support.py b/openfeature/hook/hook_support.py index 1e530e6a..9bbfd492 100644 --- a/openfeature/hook/hook_support.py +++ b/openfeature/hook/hook_support.py @@ -6,6 +6,8 @@ from openfeature.flag_evaluation import FlagEvaluationDetails, FlagType from openfeature.hook import Hook, HookContext, HookType +logger = logging.getLogger("openfeature") + def error_hooks( flag_type: FlagType, @@ -128,5 +130,5 @@ def _execute_hook_checked( getattr(hook, hook_method.value)(**kwargs), ) except Exception: # pragma: no cover - logging.error(f"Exception when running {hook_method.value} hooks") + logger.exception(f"Exception when running {hook_method.value} hooks") return None