Ejemplo de instrumentación de Python

En este documento se describe cómo modificar una aplicación de Python para recoger datos de trazas y métricas mediante el framework de código abierto OpenTelemetry, así como escribir registros JSON estructurados en la salida estándar. Este documento también proporciona información sobre una aplicación de Python de ejemplo que puedes instalar y ejecutar. La aplicación usa el framework web Flask y está configurada para generar métricas, trazas y registros.

Para obtener más información sobre la instrumentación, consulta los siguientes documentos:

Información sobre la instrumentación manual y sin código

En este lenguaje, OpenTelemetry define la instrumentación sin código como la práctica de recoger datos telemétricos de bibliotecas y frameworks sin tener que modificar el código. Sin embargo, sí puedes instalar módulos y definir variables de entorno.

En este documento no se describe la instrumentación sin código. Para obtener información sobre este tema, consulta Instrumentación de Python sin código.

Para obtener información general, consulta Instrumentación de OpenTelemetry para Python.

Antes de empezar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

  4. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs:

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com
  8. Install the Google Cloud CLI.

  9. Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

  10. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs:

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com
  14. Instrumentar tu aplicación para recoger trazas, métricas y registros

    Para instrumentar tu aplicación de forma que recoja datos de trazas y métricas, y escriba JSON estructurado en la salida estándar, sigue los pasos que se describen en las secciones posteriores de este documento:

    1. Configurar OpenTelemetry
    2. Configurar el almacenamiento de registros estructurado

    Configurar OpenTelemetry

    Esta aplicación de ejemplo está configurada para usar el SDK de Python de OpenTelemetry para exportar trazas y métricas mediante el protocolo OTLP. De forma predeterminada, el SDK de Python de OpenTelemetry usa el formato Contexto de seguimiento de W3C para propagar el contexto de seguimiento, lo que asegura que los intervalos tengan la relación de usuarios superiores y secundarios correcta en un seguimiento.

    En el siguiente código de ejemplo se muestra un módulo de Python para configurar OpenTelemetry. Para ver el ejemplo completo, haz clic en Más y, a continuación, selecciona Ver en GitHub.

    def setup_opentelemetry() -> None:
        resource = Resource.create(
            attributes={
                # Use the PID as the service.instance.id to avoid duplicate timeseries
                # from different Gunicorn worker processes.
                SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
            }
        )
    
        # Set up OpenTelemetry Python SDK
        tracer_provider = TracerProvider(resource=resource)
        tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
        trace.set_tracer_provider(tracer_provider)
    
        logger_provider = LoggerProvider(resource=resource)
        logger_provider.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter()))
        logs.set_logger_provider(logger_provider)
    
        event_logger_provider = EventLoggerProvider(logger_provider)
        events.set_event_logger_provider(event_logger_provider)
    
        reader = PeriodicExportingMetricReader(OTLPMetricExporter())
        meter_provider = MeterProvider(metric_readers=[reader], resource=resource)
        metrics.set_meter_provider(meter_provider)
    
    

    La aplicación Flask se basa en Gunicorn para servir solicitudes HTTP siguiendo las recomendaciones de la guía Despliegue en producción de Flask. Gunicorn inicia varias copias de tu aplicación en procesos de trabajo independientes para aumentar el rendimiento. Para asegurarnos de que las métricas de los procesos de trabajador no entren en conflicto entre sí, recomendamos que cada proceso de trabajador defina un valor único para el atributo de recurso service.instance.id. Una forma de hacerlo es incluir el ID de proceso en el service.instance.id. Para obtener más información, consulta Colisiones de series temporales.

    Para obtener más información y opciones de configuración, consulta la instrumentación de OpenTelemetry Python.

    Configurar el almacenamiento de registros estructurado

    Para escribir registros estructurados vinculados a trazas, configura tu aplicación para que genere registros en formato JSON en la salida estándar con claves que contengan información de la traza. En el siguiente ejemplo de código se muestra cómo configurar la biblioteca estándar logging para generar registros estructurados JSON mediante la biblioteca python-json-logger y cómo usar el paquete opentelemetry-instrumentation-logging para incluir información de la traza.

    class JsonFormatter(jsonlogger.JsonFormatter):
        def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None):
            # Format the timestamp as RFC 3339 with microsecond precision
            isoformat = datetime.fromtimestamp(record.created).isoformat()
            return f"{isoformat}Z"
    
    
    def setup_structured_logging() -> None:
        LoggingInstrumentor().instrument()
    
        log_handler = logging.StreamHandler()
        formatter = JsonFormatter(
            "%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
            rename_fields={
                "levelname": "severity",
                "asctime": "timestamp",
                "otelTraceID": "logging.googleapis.com/trace",
                "otelSpanID": "logging.googleapis.com/spanId",
                "otelTraceSampled": "logging.googleapis.com/trace_sampled",
            },
        )
        log_handler.setFormatter(formatter)
        logging.basicConfig(
            level=logging.INFO,
            handlers=[log_handler],
        )
    
    

    La configuración anterior extrae información sobre el intervalo activo del mensaje de registro y, a continuación, añade esa información como atributos al registro estructurado JSON. Estos atributos se pueden usar para correlacionar un registro con un rastreo:

    • logging.googleapis.com/trace: nombre de recurso de la traza asociada a la entrada de registro.
    • logging.googleapis.com/spanId: el ID del intervalo de la traza asociada a la entrada de registro.
    • logging.googleapis.com/trace_sampled: el valor de este campo debe ser true o false.

    Para obtener más información sobre estos campos, consulta la LogEntry estructura.

    Ejecutar una aplicación de ejemplo configurada para recoger telemetría

    La aplicación de ejemplo usa formatos independientes del proveedor, como JSON para los registros y OTLP para las métricas y los rastreos. La telemetría de la aplicación se dirige a Google Cloud mediante Collector de OpenTelemetry configurado con exportadores de Google. Usa Flask para atender solicitudes HTTP y la biblioteca requests para hacer solicitudes HTTP. Para generar métricas y trazas del cliente y el servidor HTTP, la aplicación de ejemplo instala las bibliotecas de instrumentación opentelemetry-instrumentation-flask y opentelemetry-instrumentation-requests:

    logger = logging.getLogger(__name__)
    
    # Initialize OpenTelemetry Python SDK and structured logging
    setup_opentelemetry()
    setup_structured_logging()
    
    app = Flask(__name__)
    
    # Add instrumentation
    FlaskInstrumentor().instrument_app(app)
    RequestsInstrumentor().instrument()

    La aplicación tiene dos endpoints:

    • El endpoint /multi se gestiona con la función multi. El generador de carga de la aplicación envía solicitudes al endpoint /multi. Cuando este endpoint recibe una solicitud, envía entre tres y siete solicitudes al endpoint /single del servidor local.

      @app.route("/multi")
      def multi():
          """Handle an http request by making 3-7 http requests to the /single endpoint."""
          sub_requests = randint(3, 7)
          logger.info("handle /multi request", extra={"subRequests": sub_requests})
          for _ in range(sub_requests):
              requests.get(url_for("single", _external=True))
          return "ok"
      
      
    • El endpoint /single se gestiona con la función single. Cuando este endpoint recibe una solicitud, espera un breve periodo y, a continuación, responde con una cadena.

      @app.route("/single")
      def single():
          """Handle an http request by sleeping for 100-200 ms, and write the number of seconds slept as the response."""
          duration = uniform(0.1, 0.2)
          logger.info("handle /single request", extra={"duration": duration})
          time.sleep(duration)
          return f"slept {duration} seconds"
      
      

    Descargar y desplegar la aplicación

    Para ejecutar la muestra, haz lo siguiente:

    1. In the Google Cloud console, activate Cloud Shell.

      Activate Cloud Shell

      At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

    2. Clona el repositorio:

      git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-python
      
    3. Ve al directorio de ejemplo:

      cd opentelemetry-operations-python/samples/instrumentation-quickstart
      
    4. Compila y ejecuta el ejemplo:

      docker compose up --abort-on-container-exit
      

      Si no estás ejecutando la aplicación en Cloud Shell, hazlo con la variable de entorno GOOGLE_APPLICATION_CREDENTIALS que apunte a un archivo de credenciales. Las credenciales de aplicación predeterminadas proporcionan un archivo de credenciales en $HOME/.config/gcloud/application_default_credentials.json.

      # Set environment variables
      export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
      export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json"
      export USERID="$(id -u)"
      
      # Run
      docker compose -f docker-compose.yaml -f docker-compose.creds.yaml up --abort-on-container-exit
      
    5. Ver tus métricas

      La instrumentación de OpenTelemetry en la aplicación de ejemplo genera métricas de Prometheus que puedes ver con el explorador de métricas:

      • Prometheus/http_server_duration_milliseconds/histogram Registra la duración de las solicitudes del servidor y almacena los resultados en un histograma.

      • Prometheus/http_client_duration_milliseconds/histogram Registra la duración de las solicitudes de cliente y almacena los resultados en un histograma.

      Para ver las métricas generadas por la aplicación de ejemplo, haz lo siguiente:
      1. En la Google Cloud consola, ve a la página  Explorador de métricas:

        Ve al explorador de métricas.

        Si usas la barra de búsqueda para encontrar esta página, selecciona el resultado cuya sección sea Monitorización.

      2. En la barra de herramientas de la Google Cloud consola, selecciona tu Google Cloud proyecto. En las configuraciones de App Hub, selecciona el proyecto host de App Hub o el proyecto de gestión de la carpeta habilitada para aplicaciones.
      3. En el elemento Métrica, despliega el menú Seleccionar una métrica, introduce http_server en la barra de filtros y, a continuación, usa los submenús para seleccionar un tipo de recurso y una métrica específicos:
        1. En el menú Recursos activos, selecciona Destino de Prometheus.
        2. En el menú Categorías de métricas activas, selecciona Http.
        3. En el menú Métricas activas, seleccione una métrica.
        4. Haz clic en Aplicar.
      4. Configure cómo se ven los datos.

        Cuando las mediciones de una métrica son acumulativas, Explorador de métricas normaliza automáticamente los datos medidos por el periodo de alineación, lo que hace que el gráfico muestre una tasa. Para obtener más información, consulta Tipos, clases y conversiones.

        Cuando se miden valores enteros o dobles, como con las dos métricas counter, el explorador de métricas suma automáticamente todas las series temporales. Para ver los datos de las rutas HTTP /multi y /single, defina el primer menú de la entrada Agregación como Ninguna.

        Para obtener más información sobre cómo configurar un gráfico, consulta el artículo Seleccionar métricas al utilizar el explorador de métricas.

      Ver tus trazas

      Los datos de la traza pueden tardar varios minutos en estar disponibles. Por ejemplo, cuando tu proyecto recibe datos de traza, es posible que Google Cloud Observability tenga que crear una base de datos para almacenar esos datos. La creación de la base de datos puede tardar unos minutos. Durante ese periodo, no se podrá ver ningún dato de seguimiento.

      Para ver los datos de la traza, haz lo siguiente:

      1. En la Google Cloud consola, ve a la página Explorador de trazas:

        Ir a Explorador de trazas

        También puedes encontrar esta página mediante la barra de búsqueda.

      2. En la sección de la tabla de la página, seleccione una fila con el nombre del intervalo /multi.
      3. En el gráfico de Gantt del panel Detalles del rastreo, selecciona el intervalo etiquetado como /multi.

        Se abrirá un panel con información sobre la solicitud HTTP. Estos detalles incluyen el método, el código de estado, el número de bytes y el agente de usuario de la persona que llama.

      4. Para ver los registros asociados a este rastreo, selecciona la pestaña Registros y eventos.

        En la pestaña se muestran los registros individuales. Para ver los detalles de la entrada de registro, despliégala. También puede hacer clic en Ver registros y consultar el registro con el Explorador de registros.

      Para obtener más información sobre cómo usar el explorador de Cloud Trace, consulta Buscar y explorar trazas.

      Consultar los registros

      En Explorador de registros, puedes inspeccionar tus registros y ver las trazas asociadas, si las hay.

      1. En la Google Cloud consola, ve a la página Explorador de registros:

        Ve al Explorador de registros.

        Si usas la barra de búsqueda para encontrar esta página, selecciona el resultado cuya sección sea Registro.

      2. Busca un registro con la descripción handle /multi request.

        Para ver los detalles del registro, despliega la entrada.

      3. En una entrada de registro con el mensaje "handle /multi request", haz clic en Trazas y, a continuación, selecciona Ver detalles de la traza.

        Se abre el panel Detalles de la traza, donde se muestra la traza seleccionada.

        Los datos de registro pueden estar disponibles varios minutos antes que los datos de la traza. Si se produce un error al ver los datos de seguimiento, ya sea buscando un seguimiento por ID o siguiendo los pasos de esta tarea, espera uno o dos minutos y vuelve a intentarlo.

      Para obtener más información sobre cómo usar el Explorador de registros, consulta el artículo Ver registros con el Explorador de registros.

      Siguientes pasos