feat: Add OpenTelemetry environment variable and options configuration helpers.#17524
feat: Add OpenTelemetry environment variable and options configuration helpers.#17524chalmerlowe wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces observability environment variable and client options resolution helpers under a new observability module, including the is_signal_enabled function and corresponding unit tests. Feedback is provided to improve the resolution of client options by avoiding direct __dict__ access (which fails for classes using __slots__ or properties) in favor of getattr, and replacing rstrip('s') with a safer suffix removal method to prevent unintended character stripping.
| options_dict = ( | ||
| client_options | ||
| if isinstance(client_options, dict) | ||
| else getattr(client_options, "__dict__", {}) | ||
| ) | ||
| option_key = f"enable_{signal_type.lower()}" | ||
| provider_key = f"{signal_type.rstrip('s').lower()}_provider" | ||
|
|
||
| if options_dict.get(option_key) is not None: | ||
| return bool(options_dict.get(option_key)) | ||
| if options_dict.get(provider_key) is not None: | ||
| return True |
There was a problem hiding this comment.
There are two areas of improvement in how client options and signal types are resolved:
- Direct Attribute Access via
getattr: Accessing__dict__directly is an implementation detail that bypasses properties (defined with@property) and fails for classes using__slots__. Usinggetattr(client_options, ...)is the standard, robust way to retrieve attributes from arbitrary objects in Python. - Avoid
rstripfor Suffix Removal:rstrip('s')is a common Python gotcha. It removes all trailing occurrences of the character's'(e.g., 'address' becomes 'addre'). Using slicing orremovesuffixis safer.
option_key = f"enable_{signal_type.lower()}"
sig_lower = signal_type.lower()
sig_singular = sig_lower[:-1] if sig_lower.endswith("s") else sig_lower
provider_key = f"{sig_singular}_provider"
if isinstance(client_options, dict):
val = client_options.get(option_key)
provider = client_options.get(provider_key)
else:
val = getattr(client_options, option_key, None)
provider = getattr(client_options, provider_key, None)
if val is not None:
return bool(val)
if provider is not None:
return True| if isinstance(client_options, dict) | ||
| else getattr(client_options, "__dict__", {}) | ||
| ) | ||
| option_key = f"enable_{signal_type.lower()}" |
There was a problem hiding this comment.
NOTE TO SELF: remove references to option_key throughout.
This PR introduces a foundational configuration layer for integrating OpenTelemetry (OTel) observability into Google Cloud Python client libraries. It establishes the
google.api_core.observabilitymodule, which is responsible for resolving telemetry configuration settings in a standardized, hierarchical manner.Intent & Motivation
To provide a consistent observability experience across all Google Cloud clients and languages, we are standardizing how telemetry signals (traces, metrics, logs) are enabled or disabled. This module parses and resolves configuration from multiple sources, falling back gracefully, so that users can control telemetry globally or on a per-service basis.
Changes Included
is_signal_enabledfunction in the newobservabilitypackage to resolve telemetry enablement settings based on a strict precedence hierarchy:client_optionsconfiguration.GOOGLE_CLOUD_PYTHON_TRANSLATE_TRACES_ENABLED).EXPERIMENTALprefixes within the environment variable definitions to support early-stage adoption and rollout phases safely.pytestfor all precedence rules and environmental scenarios.