From e456e0fbfc1731fb31aa65629bc574e12f3eccc5 Mon Sep 17 00:00:00 2001 From: Shuto Otaki Date: Fri, 23 Jan 2026 11:44:10 +0900 Subject: [PATCH] wip: add test for missing instance_id in SpannerMetricsTracerFactory --- google/cloud/spanner_v1/client.py | 1 + .../spanner_v1/metrics/metrics_exporter.py | 9 +++ test_instance_id_bug.py | 61 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 test_instance_id_bug.py diff --git a/google/cloud/spanner_v1/client.py b/google/cloud/spanner_v1/client.py index 5f72905616..dbc33214dc 100644 --- a/google/cloud/spanner_v1/client.py +++ b/google/cloud/spanner_v1/client.py @@ -23,6 +23,7 @@ * a :class:`~google.cloud.spanner_v1.instance.Instance` owns a :class:`~google.cloud.spanner_v1.database.Database` """ + import grpc import os import logging diff --git a/google/cloud/spanner_v1/metrics/metrics_exporter.py b/google/cloud/spanner_v1/metrics/metrics_exporter.py index 68da08b400..2c1a5a234f 100644 --- a/google/cloud/spanner_v1/metrics/metrics_exporter.py +++ b/google/cloud/spanner_v1/metrics/metrics_exporter.py @@ -143,6 +143,15 @@ def _batch_write(self, series: List["TimeSeries"], timeout_millis: float) -> Non :param series: ProtoBuf TimeSeries :return: """ + # DEBUG: Log TimeSeries labels before sending to Cloud Monitoring + logger.warning("=== DEBUG: TimeSeries labels ===") + for ts in series: + logger.warning(f" metric.type: {ts.metric.type}") + logger.warning(f" metric.labels: {dict(ts.metric.labels)}") + logger.warning(f" resource.type: {ts.resource.type}") + logger.warning(f" resource.labels: {dict(ts.resource.labels)}") + logger.warning("=== END DEBUG ===") + write_ind = 0 timeout = timeout_millis / MILLIS_PER_SECOND while write_ind < len(series): diff --git a/test_instance_id_bug.py b/test_instance_id_bug.py new file mode 100644 index 0000000000..30dd45d040 --- /dev/null +++ b/test_instance_id_bug.py @@ -0,0 +1,61 @@ +""" +instance_id 欠落バグの再現テスト + +このスクリプトは、SpannerMetricsTracerFactory が初期化された後、 +instance_id が client_attributes に含まれていないことを確認します。 +""" + +from google.cloud.spanner_v1.metrics.spanner_metrics_tracer_factory import ( + SpannerMetricsTracerFactory, +) +from google.cloud.spanner_v1.metrics.constants import MONITORED_RES_LABEL_KEY_INSTANCE + + +def test_instance_id_missing(): + """instance_id が設定されていないことを確認するテスト""" + + # シングルトンをリセット(テスト用) + SpannerMetricsTracerFactory._metrics_tracer_factory = None + + # ファクトリを初期化 + factory = SpannerMetricsTracerFactory(enabled=True) + + print("=== SpannerMetricsTracerFactory の client_attributes ===") + print(f"client_attributes: {factory.client_attributes}") + print() + + # instance_id が含まれているかチェック + has_instance_id = MONITORED_RES_LABEL_KEY_INSTANCE in factory.client_attributes + print( + f"instance_id キー ({MONITORED_RES_LABEL_KEY_INSTANCE}): {'✅ 存在' if has_instance_id else '❌ 欠落'}" + ) + + if has_instance_id: + print(f" 値: {factory.client_attributes[MONITORED_RES_LABEL_KEY_INSTANCE]}") + + print() + + # MetricsTracer を作成して確認 + tracer = factory.create_metrics_tracer() + if tracer: + print("=== MetricsTracer の client_attributes ===") + print(f"client_attributes: {tracer.client_attributes}") + + has_instance_id_in_tracer = ( + MONITORED_RES_LABEL_KEY_INSTANCE in tracer.client_attributes + ) + print(f"instance_id キー: {'✅ 存在' if has_instance_id_in_tracer else '❌ 欠落'}") + else: + print("MetricsTracer: None (OpenTelemetry 未インストール)") + + print() + print("=== 結論 ===") + if not has_instance_id: + print("❌ バグ確認: instance_id が設定されていません") + print(" -> Cloud Monitoring へのエクスポート時に InvalidArgument エラーが発生します") + else: + print("✅ instance_id は正しく設定されています") + + +if __name__ == "__main__": + test_instance_id_missing()