|
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 |
@@ -99,11 +101,50 @@ def _get_spanner_optimizer_statistics_package(): |
99 | 101 |
|
100 | 102 | log = logging.getLogger(__name__) |
101 | 103 |
|
| 104 | +_metrics_monitor_initialized = False |
| 105 | +_metrics_monitor_lock = threading.Lock() |
| 106 | + |
102 | 107 |
|
103 | 108 | def _get_spanner_enable_builtin_metrics_env(): |
104 | 109 | return os.getenv(SPANNER_DISABLE_BUILTIN_METRICS_ENV_VAR) != "true" |
105 | 110 |
|
106 | 111 |
|
| 112 | +def _initialize_metrics(project, credentials): |
| 113 | + """ |
| 114 | + Initializes the Spanner built-in metrics. |
| 115 | +
|
| 116 | + This function sets up the OpenTelemetry MeterProvider and the SpannerMetricsTracerFactory. |
| 117 | + It uses a lock to ensure that initialization happens only once. |
| 118 | + """ |
| 119 | + global _metrics_monitor_initialized |
| 120 | + if not _metrics_monitor_initialized: |
| 121 | + with _metrics_monitor_lock: |
| 122 | + if not _metrics_monitor_initialized: |
| 123 | + meter_provider = metrics.NoOpMeterProvider() |
| 124 | + try: |
| 125 | + if not _get_spanner_emulator_host(): |
| 126 | + meter_provider = MeterProvider( |
| 127 | + metric_readers=[ |
| 128 | + PeriodicExportingMetricReader( |
| 129 | + CloudMonitoringMetricsExporter( |
| 130 | + project_id=project, |
| 131 | + credentials=credentials, |
| 132 | + ), |
| 133 | + export_interval_millis=METRIC_EXPORT_INTERVAL_MS, |
| 134 | + ), |
| 135 | + ] |
| 136 | + ) |
| 137 | + metrics.set_meter_provider(meter_provider) |
| 138 | + SpannerMetricsTracerFactory() |
| 139 | + _metrics_monitor_initialized = True |
| 140 | + except Exception as e: |
| 141 | + # log is already defined at module level |
| 142 | + log.warning( |
| 143 | + "Failed to initialize Spanner built-in metrics. Error: %s", |
| 144 | + e, |
| 145 | + ) |
| 146 | + |
| 147 | + |
107 | 148 | class Client(ClientWithProject): |
108 | 149 | """Client for interacting with Cloud Spanner API. |
109 | 150 |
|
@@ -251,31 +292,12 @@ def __init__( |
251 | 292 | "http://" in self._emulator_host or "https://" in self._emulator_host |
252 | 293 | ): |
253 | 294 | warnings.warn(_EMULATOR_HOST_HTTP_SCHEME) |
254 | | - # Check flag to enable Spanner builtin metrics |
255 | 295 | if ( |
256 | 296 | _get_spanner_enable_builtin_metrics_env() |
257 | 297 | and not disable_builtin_metrics |
258 | 298 | and HAS_GOOGLE_CLOUD_MONITORING_INSTALLED |
259 | 299 | ): |
260 | | - meter_provider = metrics.NoOpMeterProvider() |
261 | | - try: |
262 | | - if not _get_spanner_emulator_host(): |
263 | | - meter_provider = MeterProvider( |
264 | | - metric_readers=[ |
265 | | - PeriodicExportingMetricReader( |
266 | | - CloudMonitoringMetricsExporter( |
267 | | - project_id=project, credentials=credentials |
268 | | - ), |
269 | | - export_interval_millis=METRIC_EXPORT_INTERVAL_MS, |
270 | | - ), |
271 | | - ] |
272 | | - ) |
273 | | - metrics.set_meter_provider(meter_provider) |
274 | | - SpannerMetricsTracerFactory() |
275 | | - except Exception as e: |
276 | | - log.warning( |
277 | | - "Failed to initialize Spanner built-in metrics. Error: %s", e |
278 | | - ) |
| 300 | + _initialize_metrics(project, credentials) |
279 | 301 | else: |
280 | 302 | SpannerMetricsTracerFactory(enabled=False) |
281 | 303 |
|
|
0 commit comments