|
23 | 23 | * a :class:`~google.cloud.spanner_v1.instance.Instance` owns a |
24 | 24 | :class:`~google.cloud.spanner_v1.database.Database` |
25 | 25 | """ |
| 26 | + |
26 | 27 | import grpc |
27 | 28 | import os |
28 | 29 | import logging |
29 | 30 | import warnings |
| 31 | +import threading |
30 | 32 |
|
31 | 33 | from google.api_core.gapic_v1 import client_info |
32 | 34 | from google.auth.credentials import AnonymousCredentials |
@@ -100,11 +102,50 @@ def _get_spanner_optimizer_statistics_package(): |
100 | 102 |
|
101 | 103 | log = logging.getLogger(__name__) |
102 | 104 |
|
| 105 | +_metrics_monitor_initialized = False |
| 106 | +_metrics_monitor_lock = threading.Lock() |
| 107 | + |
103 | 108 |
|
104 | 109 | def _get_spanner_enable_builtin_metrics_env(): |
105 | 110 | return os.getenv(SPANNER_DISABLE_BUILTIN_METRICS_ENV_VAR) != "true" |
106 | 111 |
|
107 | 112 |
|
| 113 | +def _initialize_metrics(project, credentials): |
| 114 | + """ |
| 115 | + Initializes the Spanner built-in metrics. |
| 116 | +
|
| 117 | + This function sets up the OpenTelemetry MeterProvider and the SpannerMetricsTracerFactory. |
| 118 | + It uses a lock to ensure that initialization happens only once. |
| 119 | + """ |
| 120 | + global _metrics_monitor_initialized |
| 121 | + if not _metrics_monitor_initialized: |
| 122 | + with _metrics_monitor_lock: |
| 123 | + if not _metrics_monitor_initialized: |
| 124 | + meter_provider = metrics.NoOpMeterProvider() |
| 125 | + try: |
| 126 | + if not _get_spanner_emulator_host(): |
| 127 | + meter_provider = MeterProvider( |
| 128 | + metric_readers=[ |
| 129 | + PeriodicExportingMetricReader( |
| 130 | + CloudMonitoringMetricsExporter( |
| 131 | + project_id=project, |
| 132 | + credentials=credentials, |
| 133 | + ), |
| 134 | + export_interval_millis=METRIC_EXPORT_INTERVAL_MS, |
| 135 | + ), |
| 136 | + ] |
| 137 | + ) |
| 138 | + metrics.set_meter_provider(meter_provider) |
| 139 | + SpannerMetricsTracerFactory() |
| 140 | + _metrics_monitor_initialized = True |
| 141 | + except Exception as e: |
| 142 | + # log is already defined at module level |
| 143 | + log.warning( |
| 144 | + "Failed to initialize Spanner built-in metrics. Error: %s", |
| 145 | + e, |
| 146 | + ) |
| 147 | + |
| 148 | + |
108 | 149 | class Client(ClientWithProject): |
109 | 150 | """Client for interacting with Cloud Spanner API. |
110 | 151 |
|
@@ -264,31 +305,12 @@ def __init__( |
264 | 305 | "http://" in self._emulator_host or "https://" in self._emulator_host |
265 | 306 | ): |
266 | 307 | warnings.warn(_EMULATOR_HOST_HTTP_SCHEME) |
267 | | - # Check flag to enable Spanner builtin metrics |
268 | 308 | if ( |
269 | 309 | _get_spanner_enable_builtin_metrics_env() |
270 | 310 | and not disable_builtin_metrics |
271 | 311 | and HAS_GOOGLE_CLOUD_MONITORING_INSTALLED |
272 | 312 | ): |
273 | | - meter_provider = metrics.NoOpMeterProvider() |
274 | | - try: |
275 | | - if not _get_spanner_emulator_host(): |
276 | | - meter_provider = MeterProvider( |
277 | | - metric_readers=[ |
278 | | - PeriodicExportingMetricReader( |
279 | | - CloudMonitoringMetricsExporter( |
280 | | - project_id=project, credentials=credentials |
281 | | - ), |
282 | | - export_interval_millis=METRIC_EXPORT_INTERVAL_MS, |
283 | | - ), |
284 | | - ] |
285 | | - ) |
286 | | - metrics.set_meter_provider(meter_provider) |
287 | | - SpannerMetricsTracerFactory() |
288 | | - except Exception as e: |
289 | | - log.warning( |
290 | | - "Failed to initialize Spanner built-in metrics. Error: %s", e |
291 | | - ) |
| 313 | + _initialize_metrics(project, credentials) |
292 | 314 | else: |
293 | 315 | SpannerMetricsTracerFactory(enabled=False) |
294 | 316 |
|
|
0 commit comments