-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(spanner): log client configuration at startup #17040
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -101,6 +101,7 @@ | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| EMULATOR_ENV_VAR = "SPANNER_EMULATOR_HOST" | ||||||||||||||||||||||
| SPANNER_DISABLE_BUILTIN_METRICS_ENV_VAR = "SPANNER_DISABLE_BUILTIN_METRICS" | ||||||||||||||||||||||
| LOG_CLIENT_OPTIONS_ENV_VAR = "GOOGLE_CLOUD_SPANNER_ENABLE_LOG_CLIENT_OPTIONS" | ||||||||||||||||||||||
| _EMULATOR_HOST_HTTP_SCHEME = ( | ||||||||||||||||||||||
| "%s contains a http scheme. When used with a scheme it may cause gRPC's " | ||||||||||||||||||||||
| "DNS resolver to endlessly attempt to resolve. %s is intended to be used " | ||||||||||||||||||||||
|
|
@@ -133,6 +134,10 @@ def _get_spanner_enable_builtin_metrics_env(): | |||||||||||||||||||||
| return os.getenv(SPANNER_DISABLE_BUILTIN_METRICS_ENV_VAR) != "true" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def _get_spanner_log_client_options_env(): | ||||||||||||||||||||||
| return os.getenv(LOG_CLIENT_OPTIONS_ENV_VAR, "false").lower() == "true" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def _initialize_metrics(project, credentials): | ||||||||||||||||||||||
| """ | ||||||||||||||||||||||
| Initializes the Spanner built-in metrics. | ||||||||||||||||||||||
|
|
@@ -364,6 +369,37 @@ def __init__( | |||||||||||||||||||||
| self._nth_client_id = Client.NTH_CLIENT.increment() | ||||||||||||||||||||||
| self._nth_request = AtomicCounter(0) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| self.host = "spanner.googleapis.com" | ||||||||||||||||||||||
| if self._emulator_host: | ||||||||||||||||||||||
| self.host = self._emulator_host | ||||||||||||||||||||||
| elif self._experimental_host: | ||||||||||||||||||||||
| self.host = self._experimental_host | ||||||||||||||||||||||
| elif self._client_options and self._client_options.api_endpoint: | ||||||||||||||||||||||
| self.host = self._client_options.api_endpoint | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if _get_spanner_log_client_options_env(): | ||||||||||||||||||||||
| self._log_spanner_options() | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def _log_spanner_options(self): | ||||||||||||||||||||||
| """Logs Spanner client options.""" | ||||||||||||||||||||||
| log.info( | ||||||||||||||||||||||
| "Spanner options: \n" | ||||||||||||||||||||||
| " Project ID: %s\n" | ||||||||||||||||||||||
| " Host: %s\n" | ||||||||||||||||||||||
| " Route to leader enabled: %s\n" | ||||||||||||||||||||||
| " Directed read options: %s\n" | ||||||||||||||||||||||
| " Default transaction options: %s\n" | ||||||||||||||||||||||
| " Observability options: %s\n" | ||||||||||||||||||||||
| " Built-in metrics enabled: %s", | ||||||||||||||||||||||
| self.project, | ||||||||||||||||||||||
| self.host, | ||||||||||||||||||||||
| self.route_to_leader_enabled, | ||||||||||||||||||||||
| self._directed_read_options, | ||||||||||||||||||||||
| self._default_transaction_options, | ||||||||||||||||||||||
| self._observability_options, | ||||||||||||||||||||||
|
Comment on lines
+395
to
+399
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer using public properties instead of private attributes (e.g.,
Suggested change
|
||||||||||||||||||||||
| _get_spanner_enable_builtin_metrics_env(), | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @property | ||||||||||||||||||||||
| def _next_nth_request(self): | ||||||||||||||||||||||
| return self._nth_request.increment() | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -32,13 +32,11 @@ | |||||||||||||||||||||||||||||
| import threading | ||||||||||||||||||||||||||||||
| import warnings | ||||||||||||||||||||||||||||||
| from typing import Optional | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import google.api_core.client_options | ||||||||||||||||||||||||||||||
| import grpc | ||||||||||||||||||||||||||||||
| from google.api_core.gapic_v1 import client_info | ||||||||||||||||||||||||||||||
| from google.auth.credentials import AnonymousCredentials | ||||||||||||||||||||||||||||||
| from google.cloud.client import ClientWithProject | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| from google.cloud.spanner_admin_database_v1 import ( | ||||||||||||||||||||||||||||||
| DatabaseAdminClient as DatabaseAdminClient, | ||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||
|
|
@@ -55,14 +53,14 @@ | |||||||||||||||||||||||||||||
| from google.cloud.spanner_admin_instance_v1.services.instance_admin.transports.grpc import ( | ||||||||||||||||||||||||||||||
| InstanceAdminGrpcTransport, | ||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||
| from google.cloud.spanner_v1.instance import Instance | ||||||||||||||||||||||||||||||
| from google.cloud.spanner_v1._helpers import ( | ||||||||||||||||||||||||||||||
| AtomicCounter, | ||||||||||||||||||||||||||||||
| _merge_query_options, | ||||||||||||||||||||||||||||||
| _metadata_with_prefix, | ||||||||||||||||||||||||||||||
| _validate_client_context, | ||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||
| from google.cloud.spanner_v1.gapic_version import __version__ | ||||||||||||||||||||||||||||||
| from google.cloud.spanner_v1.instance import Instance | ||||||||||||||||||||||||||||||
| from google.cloud.spanner_v1.metrics.constants import METRIC_EXPORT_INTERVAL_MS | ||||||||||||||||||||||||||||||
| from google.cloud.spanner_v1.metrics.metrics_exporter import ( | ||||||||||||||||||||||||||||||
| CloudMonitoringMetricsExporter, | ||||||||||||||||||||||||||||||
|
|
@@ -84,6 +82,7 @@ | |||||||||||||||||||||||||||||
| _CLIENT_INFO = client_info.ClientInfo(client_library_version=__version__) | ||||||||||||||||||||||||||||||
| EMULATOR_ENV_VAR = "SPANNER_EMULATOR_HOST" | ||||||||||||||||||||||||||||||
| SPANNER_DISABLE_BUILTIN_METRICS_ENV_VAR = "SPANNER_DISABLE_BUILTIN_METRICS" | ||||||||||||||||||||||||||||||
| LOG_CLIENT_OPTIONS_ENV_VAR = "GOOGLE_CLOUD_SPANNER_ENABLE_LOG_CLIENT_OPTIONS" | ||||||||||||||||||||||||||||||
| _EMULATOR_HOST_HTTP_SCHEME = ( | ||||||||||||||||||||||||||||||
| "%s contains a http scheme. When used with a scheme it may cause gRPC's DNS resolver to endlessly attempt to resolve. %s is intended to be used without a scheme: ex %s=localhost:8080." | ||||||||||||||||||||||||||||||
| % ((EMULATOR_ENV_VAR,) * 3) | ||||||||||||||||||||||||||||||
|
|
@@ -114,6 +113,10 @@ def _get_spanner_enable_builtin_metrics_env(): | |||||||||||||||||||||||||||||
| return os.getenv(SPANNER_DISABLE_BUILTIN_METRICS_ENV_VAR) != "true" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def _get_spanner_log_client_options_env(): | ||||||||||||||||||||||||||||||
| return os.getenv(LOG_CLIENT_OPTIONS_ENV_VAR, "false").lower() == "true" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def _initialize_metrics(project, credentials): | ||||||||||||||||||||||||||||||
| """Initializes the Spanner built-in metrics. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -226,8 +229,7 @@ class Client(ClientWithProject): | |||||||||||||||||||||||||||||
| the Spanner built-in metrics collection and exporting. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| :raises: :class:`ValueError <exceptions.ValueError>` if both ``read_only`` | ||||||||||||||||||||||||||||||
| and ``admin`` are :data:`True` | ||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||
| and ``admin`` are :data:`True`""" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| _instance_admin_api = None | ||||||||||||||||||||||||||||||
| _database_admin_api = None | ||||||||||||||||||||||||||||||
|
|
@@ -316,6 +318,28 @@ def __init__( | |||||||||||||||||||||||||||||
| self._default_transaction_options = default_transaction_options | ||||||||||||||||||||||||||||||
| self._nth_client_id = Client.NTH_CLIENT.increment() | ||||||||||||||||||||||||||||||
| self._nth_request = AtomicCounter(0) | ||||||||||||||||||||||||||||||
| self.host = "spanner.googleapis.com" | ||||||||||||||||||||||||||||||
| if self._emulator_host: | ||||||||||||||||||||||||||||||
| self.host = self._emulator_host | ||||||||||||||||||||||||||||||
| elif self._experimental_host: | ||||||||||||||||||||||||||||||
| self.host = self._experimental_host | ||||||||||||||||||||||||||||||
| elif self._client_options and self._client_options.api_endpoint: | ||||||||||||||||||||||||||||||
| self.host = self._client_options.api_endpoint | ||||||||||||||||||||||||||||||
|
Comment on lines
+321
to
+327
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The attribute
Suggested change
|
||||||||||||||||||||||||||||||
| if _get_spanner_log_client_options_env(): | ||||||||||||||||||||||||||||||
| self._log_spanner_options() | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def _log_spanner_options(self): | ||||||||||||||||||||||||||||||
| """Logs Spanner client options.""" | ||||||||||||||||||||||||||||||
| log.info( | ||||||||||||||||||||||||||||||
| "Spanner options: \n Project ID: %s\n Host: %s\n Route to leader enabled: %s\n Directed read options: %s\n Default transaction options: %s\n Observability options: %s\n Built-in metrics enabled: %s", | ||||||||||||||||||||||||||||||
| self.project, | ||||||||||||||||||||||||||||||
| self.host, | ||||||||||||||||||||||||||||||
| self.route_to_leader_enabled, | ||||||||||||||||||||||||||||||
| self._directed_read_options, | ||||||||||||||||||||||||||||||
| self._default_transaction_options, | ||||||||||||||||||||||||||||||
| self._observability_options, | ||||||||||||||||||||||||||||||
| _get_spanner_enable_builtin_metrics_env(), | ||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||
|
Comment on lines
+334
to
+342
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For better readability and consistency with the asynchronous client implementation, consider breaking the log format string into multiple lines. Additionally, prefer using public properties instead of private attributes (e.g., log.info(
"Spanner options: \n"
" Project ID: %s\n"
" Host: %s\n"
" Route to leader enabled: %s\n"
" Directed read options: %s\n"
" Default transaction options: %s\n"
" Observability options: %s\n"
" Built-in metrics enabled: %s",
self.project,
self._host,
self.route_to_leader_enabled,
self.directed_read_options,
self.default_transaction_options,
self.observability_options,
_get_spanner_enable_builtin_metrics_env(),
) |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||||||||
| def _next_nth_request(self): | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The attribute
hostis quite generic and might conflict with future changes in base classes or subclasses. Since it is primarily used for logging client options here, it should be prefixed with an underscore to indicate it is internal.