Monitorizar el rendimiento con trazas del lado del cliente

Para monitorizar y depurar las solicitudes de Firestore de principio a fin, puedes habilitar las trazas en las bibliotecas de cliente. El rastreo del lado del cliente puede proporcionar una señal sobre el rendimiento que experimenta tu aplicación, así como estadísticas que pueden ayudarte a depurar problemas.

Las trazas del lado del cliente, que se recogen ejecutando RPCs desde el cliente, proporcionan la siguiente información:

  • Abarca las marcas de tiempo de cuándo envió el cliente la solicitud de RPC y cuándo recibió la respuesta de RPC, incluida la latencia introducida por la red y el sistema del cliente.
  • Atributos (pares clave-valor) que muestran información sobre el cliente y su configuración.
  • Registros asociados a eventos clave en los intervalos
  • Trazas de pila si se produce un fallo en el cliente

OpenTelemetry

Las trazas de las bibliotecas de cliente se instrumentan mediante las APIs de OpenTelemetry. OpenTelemetry es un framework de observabilidad de código abierto estándar del sector. OpenTelemetry ofrece una amplia gama de herramientas, como APIs y SDKs de instrumentación, colectores, exportadores específicos de backend y opciones de configuración flexibles, como controles de muestreo y límites de intervalos.

Exportar trazas con exportadores y colectores

Como parte de tus configuraciones, puedes exportar tus trazas a un backend de observabilidad. La mayoría de los proveedores de servicios de observabilidad ofrecen exportadores que puedes usar, como Cloud Trace.

Además de un exportador, OpenTelemetry recomienda configurar un Collector. Un recolector permite que tu servicio descargue datos rápidamente y que el recolector se encargue de la gestión adicional, como los reintentos, la creación de lotes y el cifrado. Un recolector se ejecuta junto con tu aplicación. El recolector recibe mensajes OTLP, los procesa y los exporta a tu backend de observabilidad.

Limitaciones

Las trazas del lado del cliente tienen las siguientes limitaciones:

  • Los intervalos de traza están disponibles en las bibliotecas de cliente de Java y Node.js.
  • La biblioteca de cliente no genera intervalos de seguimiento para los listeners en tiempo real.

Facturación

Además del uso de Firestore, el análisis de trazas del lado del cliente puede generar cargos.

No se aplican cargos por recoger trazas ni por usar el framework OpenTelemetry.

La ingesta de intervalos de traza en tu backend de observabilidad puede ser facturable. Por ejemplo, si usas Cloud Trace como backend, se te facturará según los precios de Cloud Trace. Si utilizas otro proveedor de servicios de observabilidad, infórmate sobre su modelo de facturación y los costes asociados.

Para entender mejor la facturación, empieza con una proporción de muestreo de trazas pequeña (traza un pequeño porcentaje de tus RPCs) en función de tu tráfico.

Antes de empezar

Antes de empezar:

  • Asegúrate de configurar la cuenta de servicio con la que tu aplicación escribe las trazas en tu backend de observabilidad con los roles de Gestión de Identidades y Accesos necesarios:

    Operación de rastreo Rol de gestión de identidades y accesos
    Leer trazas roles/cloudtrace.user
    Escribir trazas roles/cloudtrace.agent
    Leer o escribir trazas roles/cloudtrace.admin
  • Verifica que la API Trace esté habilitada en este proyecto.

Configurar trazas del lado del cliente

En esta sección se proporcionan ejemplos de configuraciones de las trazas del lado del cliente. Puedes exportar datos a un Collector o directamente a un backend de observabilidad. También tiene las siguientes opciones para configurar las trazas del lado del cliente:

Exportar trazas a un Collector con las APIs de OpenTelemetry

El siguiente código configura la biblioteca de cliente para exportar intervalos con una proporción de muestreo del 10% a un Collector de OpenTelemetry.

Java (administración)

Resource resource = Resource
  .getDefault().merge(Resource.builder().put(SERVICE_NAME, "My App").build());

OtlpGrpcSpanExporter otlpGrpcSpanExporter =
  OtlpGrpcSpanExporter
  .builder()
  .setEndpoint("http://localhost:4317") // Replace with your OTLP endpoint
  .build();

// Using a batch span processor
// You can also use other `BatchSpanProcessorBuilder` methods
// to further customize.
BatchSpanProcessor otlpGrpcSpanProcessor =
  BatchSpanProcessor.builder(otlpGrpcSpanExporter).build();

// Export to a collector that is expecting OTLP using gRPC.
OpenTelemetrySdk otel = OpenTelemetrySdk.builder()
        .setTracerProvider(
          SdkTracerProvider.builder()
            .setResource(resource)
            .addSpanProcessor(otlpGrpcSpanProcessor)
            .setSampler(Sampler.traceIdRatioBased(0.1))
            .build())
          .build();

Firestore firestore = FirestoreOptions
  .newBuilder()
  .setOpenTelemetryOptions(
    FirestoreOpenTelemetryOptions.newBuilder()
      .setTracingEnabled(true)
      .setOpenTelemetry(otel)
      .build())
  .build().getService();

    
Node.js (administrador)

import { trace } from "@opentelemetry/api";
import {GrpcInstrumentation} from '@opentelemetry/instrumentation-grpc';

import pkg1 from "@opentelemetry/sdk-trace-node";
import pkg2 from "@opentelemetry/instrumentation";
import pkg3 from "@opentelemetry/exporter-trace-otlp-grpc";

const { NodeTracerProvider, BatchSpanProcessor, TraceIdRatioBasedSampler } = pkg1;
const { registerInstrumentations } = pkg2;
const { OTLPTraceExporter } =  pkg3;

const provider = new NodeTracerProvider(
  // Provide your chosen NodeTracerConfig such as sampler and span limit
  {
    sampler: new TraceIdRatioBasedSampler(0.1),
  }
);
provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter()));
provider.register();

// If you'd like to see gRPC spans (recommended), enable GrpcInstrumentation
registerInstrumentations({
  instrumentations: [
    new GrpcInstrumentation(
      // (optional): you can add GrpcInstrumentationConfig here
    ),
  ],
});


const settings: Settings = {
  projectId: 'my-project-id',
  preferRest: false,
  openTelemetry: {
    tracerProvider: trace.getTracerProvider()
  }
};

// Initialize Firestore
const firestore = new Firestore(settings);
// Add app code here

// Make sure to shut down your TracerProvider to flush any traces left in memory.
process.on('SIGINT', async () => {
  await provider
        .shutdown()
        .catch(error => console.error('Error terminating NodeTracerProvider:', error));
});
    

Exportar directamente a un backend de observabilidad con las APIs de OpenTelemetry

Si tu proveedor de servicios de observabilidad admite la ingestión de OTLP, puedes usar su exportador de OpenTelemetry para exportar trazas directamente a su backend. El siguiente código configura la biblioteca de cliente para exportar directamente los intervalos de traza a Cloud Trace con una proporción de muestreo de trazas del 10 %.

Java (administración)

// TraceExporter needed for this use case
import com.google.cloud.opentelemetry.trace.TraceExporter;

Resource resource = Resource
  .getDefault().merge(Resource.builder().put(SERVICE_NAME, "My App").build());
SpanExporter gcpTraceExporter = TraceExporter.createWithDefaultConfiguration();

// Using a batch span processor
// You can also use other `BatchSpanProcessorBuilder` methods
// to further customize.
SpanProcessor gcpBatchSpanProcessor =
  BatchSpanProcessor.builder(gcpTraceExporter).build();

// Export directly to Cloud Trace with 10% trace sampling ratio
OpenTelemetrySdk otel = OpenTelemetrySdk.builder()
        .setTracerProvider(SdkTracerProvider.builder()
            .setResource(resource)
            .addSpanProcessor(gcpBatchSpanProcessor)
            .setSampler(Sampler.traceIdRatioBased(0.1))
            .build())
        .build();

Firestore firestore = FirestoreOptions
  .newBuilder()
  .setOpenTelemetryOptions(
    FirestoreOpenTelemetryOptions.newBuilder()
      .setTracingEnabled(true)
      .setOpenTelemetry(otel)
      .build())
  .build().getService();

    
Node.js (administrador)

import { trace } from "@opentelemetry/api";
import {GrpcInstrumentation} from '@opentelemetry/instrumentation-grpc';
import { TraceExporter } from "@google-cloud/opentelemetry-cloud-trace-exporter";

import pkg1 from "@opentelemetry/sdk-trace-node";
import pkg2 from "@opentelemetry/instrumentation";

const { NodeTracerProvider, BatchSpanProcessor, TraceIdRatioBasedSampler } = pkg1;
const { registerInstrumentations } = pkg2;

const provider = new NodeTracerProvider(
  // Provide your chosen NodeTracerConfig such as sampler and span limits
  {
    sampler: new TraceIdRatioBasedSampler(0.1),
  }
);
provider.addSpanProcessor(new BatchSpanProcessor(new TraceExporter()));
provider.register();

// If you'd like to see gRPC spans (recommended), enable GrpcInstrumentation
registerInstrumentations({
  instrumentations: [
    new GrpcInstrumentation(
      // (optional): you can add GrpcInstrumentationConfig here
    ),
  ],
});


const settings: Settings = {
  projectId: 'my-project-id',
  preferRest: false,
  openTelemetry: {
    tracerProvider: trace.getTracerProvider()
  }
};

// Initialize Firestore
const firestore = new Firestore(settings);
// ...

// Make sure to shut down your TracerProvider to flush any traces left in memory.
process.on('SIGINT', async () => {
  await provider
        .shutdown()
        .catch(error => console.error('Error terminating NodeTracerProvider:', error));
});
    

Instrumentación sin código

Sigue estas instrucciones para configurar los rastreos sin hacer cambios en el código:

Java (administración)
Puedes configurar los rastreos sin cambiar el código mediante agentes automáticos. Debes definir la variable de entorno FIRESTORE_ENABLE_TRACING=ON. También debes definir otros ajustes de configuración, tal como se describe en Configuración del agente. Consulta los ejemplos siguientes.

Exportar a un Collector con agentes automáticos

Ejecuta tu OpenTelemetry Collector con los receptores gRPC de OTLP habilitados. Define el exportador del agente como otlp y especifica el endpoint al que debe exportar los datos. En el siguiente ejemplo se usa una proporción de muestreo del 10% y se envían trazas al Collector que escucha en el puerto 4317 de localhost.


FIRESTORE_ENABLE_TRACING=ON                            \
java                                                   \
-javaagent:path/to/opentelemetry-javaagent.jar         \
-Dotel.traces.exporter=otlp                            \
-Dotel.exporter.otlp.endpoint="http://localhost:4317"  \
-Dotel.traces.sampler=traceidratio                     \
-Dotel.traces.sampler.arg=0.1                          \
-Dotel.service.name="My App"                           \
-jar myapp.jar

Exportar directamente a un backend de observabilidad con agentes automáticos

Además de definir la variable de entorno FIRESTORE_ENABLE_TRACING=ON, debes añadir la extensión del agente de Java de OpenTelemetry para tu backend específico. En el siguiente ejemplo se usa la extensión del exportador de trazas y una proporción de muestreo de trazas del 10 %.


FIRESTORE_ENABLE_TRACING=ON                                                \
java                                                                       \
-javaagent:path/to/opentelemetry-javaagent.jar                             \
-Dotel.javaagent.extensions=/path/to/exporter-auto-0.26.0-alpha-shaded.jar \
-Dotel.traces.exporter=google_cloud_trace                                  \
-Dotel.traces.sampler=traceidratio                                         \
-Dotel.traces.sampler.arg=0.1                                              \

    
Node.js (administrador)

Para configurar la instrumentación sin código, sigue las instrucciones de OpenTelemetry para la instrumentación de JavaScript. El siguiente fragmento de código de ejemplo habilita la instrumentación y envía trazas a un recolector de OpenTelemetry:


npm install @opentelemetry/api
npm install @opentelemetry/auto-instrumentations-node


env \
FIRESTORE_ENABLE_TRACING=ON \
OTEL_TRACES_EXPORTER=otlp \
OTEL_NODE_ENABLED_INSTRUMENTATIONS="http,grpc" \
OTEL_NODE_RESOURCE_DETECTORS="none" \
node --require @opentelemetry/auto-instrumentations-node/register my_app.js

    

Ejemplo de traza

En los siguientes ejemplos se muestra cómo se muestra la información de las trazas en Cloud Trace. Para obtener más información sobre los posibles atributos y valores, consulta Atributos y eventos de intervalos de traza.

Ejemplo de intervalo de traza

Un intervalo de traza visto desde Cloud Trace

Ejemplo de registro de eventos

Registro de eventos de un intervalo de traza visto desde Cloud Trace

Valores de atributo de ejemplo

Valores de los atributos de un intervalo de traza visto desde Cloud Trace

Ejemplo de rastreo de pila y evento de excepción

Un rastreo de pila visto desde Cloud Trace

Evento de excepción visto desde Cloud Trace

Siguientes pasos