Strumentazione delle librerie client Python di Google Cloud

Questa guida mostra come configurare e utilizzare il tracciamento distribuito di OpenTelemetry nelle librerie client Python di Google Cloud .

Panoramica

Google Cloud Le librerie client Python forniscono il tracciamento distribuito OpenTelemetry integrato. Questa strumentazione offre una visibilità approfondita sulle operazioni del client, sulle chiamate RPC, sul comportamento dei nuovi tentativi, sulla latenza di rete e sulle risposte del servizio senza richiedere il monkey patching manuale.

Caratteristiche principali:

  • Indipendente dal backend: genera span OpenTelemetry standard. Puoi esportare le tracce direttamente in Cloud Trace, in un raccoglitore OpenTelemetry on-premise o in piattaforme di osservabilità di terze parti.
  • Attivazione: il tracciamento distribuito è disattivato per impostazione predefinita per evitare l'overhead di runtime per le applicazioni che non richiedono la telemetria.
  • Propagazione del contesto: gli intervalli si associano automaticamente al contesto della traccia OpenTelemetry attivo utilizzando il contextvars integrato di Python, correlando le chiamate client con le richieste HTTP/gRPC in entrata.

Come funziona il tracciamento (gerarchia degli intervalli)

Se abilitate, le librerie client Python Google Cloud emettono un'architettura di span gerarchica a due livelli che separa chiaramente l'esecuzione dei metodi rivolti agli utenti dai tentativi di connessione sottostanti:

[Logical Client Method Span] (Parent: covers full method duration, retries, and backoff)
 │
 ├── [Network Attempt Span #1] (Child: First wire call; e.g. transient 503 UNAVAILABLE)
 └── [Network Attempt Span #2] (Child: Retry wire call; succeeds 200 OK)

1. Intervalli dei metodi client logici (principali)

  • Ambito: incapsula l'intero ciclo di vita della chiamata al metodo della libreria client, dalla chiamata al completamento.
  • Durata: copre tutti i tentativi di ripetizione, le pause di backoff esponenziale e le policy di timeout.
  • Identità: prende il nome dal metodo RPC completo (ad esempio, google.cloud.secretmanager.v1.SecretManagerService/GetSecretVersion).
  • Attributi: acquisisce i metadati RPC logici, il servizio di destinazione e il risultato finale di alto livello.

2. Network Attempt Spans (Child)

  • Ambito: create come intervalli secondari dell'intervallo del metodo logico, che rappresentano singoli tentativi di rete fisica HTTP/REST o gRPC.
  • Ciclo di vita: viene generato un nuovo intervallo per ogni tentativo di rete. Se un'operazione ha esito positivo al primo tentativo, viene registrato esattamente un intervallo secondario. Se un'operazione rileva errori temporanei e riprova, ogni tentativo viene registrato come un intervallo secondario indipendente con i propri tempi e stato.
  • Attributi: acquisisce i codici di stato di basso livello, l'indirizzo del server di destinazione e i dettagli del trasporto.

Prerequisiti e installazione

Google Cloud Il tracciamento della libreria client Python si basa sui pacchetti Python OpenTelemetry standard.

1. Installa pacchetti

  • Strumentazione della libreria client e del trasporto gRPC:

    • opentelemetry-api viene installato automaticamente con google-api-core per supportare gli intervalli dei metodi logici e gli intervalli di trasporto HTTP/REST (rest).
    • Per registrare anche gli intervalli di trasporto gRPC di basso livello, installa la libreria client insieme a google-api-core[tracing] (che installa opentelemetry-instrumentation-grpc):
    pip install google-cloud-secret-manager "google-api-core[tracing]"
    
  • SDK OpenTelemetry (per app autonome ed esempi di codice):

    • Le librerie client non richiedono opentelemetry-sdk se il tuo ambiente fornisce già un TracerProvider.
    • Tuttavia, per configurare un TracerProvider ed esportare gli intervalli nel tuo codice (inclusi gli esempi in questa pagina), installa opentelemetry-sdk:
    pip install opentelemetry-sdk
    

Per istruzioni sulla configurazione degli esportatori OpenTelemetry per l'invio di span a Cloud Trace o a un raccoglitore OpenTelemetry in produzione, consulta Configura Python con OpenTelemetry e Scegli un approccio di strumentazione.

Abilitazione del tracciamento

Il tracciamento distribuito può essere abilitato a livello globale utilizzando una variabile di ambiente o in modo programmatico per ogni client. La configurazione per client passata utilizzando ClientOptions ha la precedenza sulle impostazioni delle variabile di ambiente.

Opzione 1: configurazione globale (variabili di ambiente)

Per abilitare il tracciamento in tutte le librerie client Python Google Cloud supportate nel tuo ambiente, imposta la seguente variabile di ambiente prima di avviare l'applicazione:

export GOOGLE_SDK_PYTHON_TRACING_ENABLED=true

Se impostato su true, le librerie client rilevano automaticamente l'oggetto OpenTelemetry TracerProvider registrato a livello globale ed emettono intervalli per tutte le chiamate client.

Opzione 2: configurazione per client (codice)

Per un controllo granulare o per applicazioni multi-tenant, configura un'istanza client specifica passando un tracer_provider utilizzando ClientOptions:

from google.api_core.client_options import ClientOptions
from google.cloud import secretmanager

options = ClientOptions(tracer_provider=my_tracer_provider)
client = secretmanager.SecretManagerServiceClient(client_options=options)

Esempi di codice

Le librerie client possono utilizzare Credenziali predefinite dell'applicazione per autenticarsi facilmente con le API di Google e inviare richieste a queste API. Con Credenziali predefinite dell'applicazione, puoi testare l'applicazione localmente ed eseguirne il deployment senza modificare il codice sottostante. Per saperne di più, consulta Autenticati per l'utilizzo delle librerie client.

1. Esempio di guida rapida (SecretManagerServiceClient)

L'esempio autonomo seguente mostra come configurare OpenTelemetry standard, abilitare il tracciamento della libreria client utilizzando una variabile di ambiente e stampare gli span emessi direttamente nel terminale come JSON utilizzando ConsoleSpanExporter.

import os

from google.cloud import secretmanager
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor


def get_secret_version_with_tracing(
    project_id: str,
    secret_id: str,
    version_id: str = "latest",
) -> secretmanager.SecretVersion:
    """Get a secret version in Secret Manager with OpenTelemetry tracing enabled.

    Args:
        project_id: Google Cloud project ID.
        secret_id: ID of the secret.
        version_id: ID of the secret version (defaults to "latest").

    Returns:
        The SecretVersion metadata object.
    """
    # NOTE: In standalone scripts or CLI tools, initialize and shut down the
    # TracerProvider within the script workflow. In long-running production
    # applications (e.g., web servers), configure the TracerProvider once at
    # application startup.
    #
    # Initialize the OpenTelemetry TracerProvider with a Console exporter
    provider = TracerProvider()
    provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
    trace.set_tracer_provider(provider)

    # Enable Google Cloud client library tracing
    os.environ["GOOGLE_SDK_PYTHON_TRACING_ENABLED"] = "true"

    # Instantiate the client (automatically discovers the active TracerProvider)
    client = secretmanager.SecretManagerServiceClient()

    # Construct the resource name and invoke the RPC
    name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"

    try:
        print("--- OpenTelemetry Trace Spans (JSON) ---")
        response = client.get_secret_version(request={"name": name})
        state_name = response.state.name
        print(
            f"\nAPI Result: Retrieved secret version {response.name} (state: {state_name})"
        )
        return response
    finally:
        # Flush buffered spans before program completion
        provider.shutdown()

2. Configurazione programmatica (ClientOptions)

Se preferisci non utilizzare le variabili di ambiente o devi passare istanze TracerProvider diverse a client diversi, configura un client in modo programmatico passando tracer_provider utilizzando ClientOptions:

from google.api_core.client_options import ClientOptions
from google.cloud import secretmanager
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor


def get_secret_version_with_client_options(
    project_id: str,
    secret_id: str,
    version_id: str = "latest",
) -> secretmanager.SecretVersion:
    """Get a secret version configuring tracing programmatically via ClientOptions.

    Args:
        project_id: Google Cloud project ID.
        secret_id: ID of the secret.
        version_id: ID of the secret version (defaults to "latest").

    Returns:
        The SecretVersion metadata object.
    """
    # Initialize an independent TracerProvider (no global registration required)
    provider = TracerProvider()
    provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))

    # Pass the TracerProvider directly via ClientOptions
    # Tracing is activated specifically for this client instance, even without
    # setting the GOOGLE_SDK_PYTHON_TRACING_ENABLED environment variable.
    options = ClientOptions(tracer_provider=provider)
    client = secretmanager.SecretManagerServiceClient(client_options=options)

    # Construct resource name and invoke RPC
    name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"

    try:
        print("--- OpenTelemetry Trace Spans (JSON) ---")
        response = client.get_secret_version(request={"name": name})
        state_name = response.state.name
        print(
            f"\nAPI Result: Retrieved secret version {response.name} (state: {state_name})"
        )
        return response
    finally:
        # Flush buffered spans before program completion
        provider.shutdown()

3. Esempio di client asincrono (SecretManagerServiceAsyncClient)

L'esempio seguente definisce una coroutine asincrona (async def get_secret_version_with_tracing_async) utilizzando SecretManagerServiceAsyncClient. Poiché questo client è asincrono, assicurati di eseguirlo all'interno di un loop di eventi asyncio attivo.

import asyncio
import os

from google.cloud import secretmanager
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor


async def get_secret_version_with_tracing_async(
    project_id: str,
    secret_id: str,
    version_id: str = "latest",
) -> secretmanager.SecretVersion:
    """Get a secret version using SecretManagerServiceAsyncClient with OpenTelemetry tracing.

    Args:
        project_id: Google Cloud project ID.
        secret_id: ID of the secret.
        version_id: ID of the secret version (defaults to "latest").

    Returns:
        The SecretVersion metadata object.
    """
    # NOTE: In standalone scripts or CLI tools, initialize and shut down the
    # TracerProvider within the script workflow. In long-running production
    # applications (e.g., web servers), configure the TracerProvider once at
    # application startup.
    #
    # Initialize the OpenTelemetry TracerProvider with a Console exporter
    provider = TracerProvider()
    provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
    trace.set_tracer_provider(provider)

    # Enable Google Cloud client library tracing
    os.environ["GOOGLE_SDK_PYTHON_TRACING_ENABLED"] = "true"

    # Instantiate the async client
    client = secretmanager.SecretManagerServiceAsyncClient()

    # Construct resource name and invoke the async RPC
    name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"

    try:
        print("--- OpenTelemetry Trace Spans (JSON) ---")
        response = await client.get_secret_version(request={"name": name})
        state_name = response.state.name
        print(
            f"\nAPI Result: Retrieved secret version {response.name} (state: {state_name})"
        )
        return response
    finally:
        # Flush buffered spans before program completion
        provider.shutdown()

Riferimento agli attributi semantici

Gli intervalli emessi dalle librerie client Python Google Cloud rispettano le convenzioni semantiche OpenTelemetry standard per gli intervalli RPC, registrando i metadati standard per il protocollo di trasporto, l'identità del metodo RPC, l'indirizzo del server di destinazione, i codici di stato della risposta e i dettagli degli errori. Puoi utilizzare questi attributi per filtrare, aggregare e creare policy di avviso nella dashboard di osservabilità o di Cloud Trace.

Sicurezza e dati sensibili

Google Cloud La strumentazione della libreria client Python è progettata seguendo rigorosi standard di sicurezza e privacy:

  • Protezione del payload: le librerie client non registrano mai i dati del payload di richiesta o risposta (come i contenuti dei file, i valori dei secret o i risultati delle query del database) negli intervalli di traccia.
  • Visibilità degli identificatori: i nomi delle risorse (come ID progetto, ID set di dati e nomi dei secret) vengono visualizzati nei parametri dei metodi e negli attributi degli endpoint URL. Se gli identificatori delle risorse contengono informazioni aziendali sensibili, assicurati che l'archiviazione delle tracce sia conforme alle tue policy di conformità interne.
  • Esportatori di terze parti: quando esporti le tracce verso servizi di osservabilità di terze parti o fornitori SaaS, esamina gli accordi sulla protezione dei dati della tua organizzazione e configura il filtro degli attributi dell'esportatore, se necessario.