Información general

Esta página describe cómo instrumentar tus aplicaciones Expo para Real User Monitoring (RUM) con el kit de desarrollo de software (SDK) de React Native. RUM incluye capacidades de Error Tracking para informes de fallos y análisis de errores.

Nota: Si has adquirido Error Tracking como producto independiente (sin RUM), consulta en su lugar la documentación de configuración de Error Tracking Expo.

El SDK de React Native de RUM es compatible con Expo y Expo Go. Para utilizarlo, instala expo-datadog y @datadog/mobile-react-native.

expo-datadog es compatible con Expo a partir del SDK 45 y las versiones del complemento siguen las versiones de Expo. Por ejemplo, si utilizas Expo SDK 45, utiliza expo-datadog versión 45.x.x. Datadog recomienda utilizar Expo SDK 45 como versión mínima; las versiones anteriores pueden requerir pasos manuales.

Si tienes algún problema al configurar el kit de desarrollo de software (SDK) de Datadog con una aplicación Expo, puedes consultar nuestra aplicación de ejemplo como referencia.

Configuración

Para instalar con NPM, ejecuta:

npm install expo-datadog @datadog/mobile-react-native

Para instalar con Yarn, ejecuta:

yarn add expo-datadog @datadog/mobile-react-native

Rastrear la navegación de la vista

Para ver cómo las sesiones de RUM se rellenan en Datadog, es necesario implementar el rastreo de la vista, que se puede inicializar de forma manual o automática.

Rastreo manual

Puedes iniciar y detener manualmente una vista utilizando los siguientes métodos startView() y stopView().

import {
    DdRum
} from 'expo-datadog';

// Start a view with a unique view identifier, a custom view name, and an object to attach additional attributes to the view
DdRum.startView(
    '<view-key>', // <view-key> has to be unique, for example it can be ViewName-unique-id
    'View Name',
    { 'custom.foo': 'something' },
    Date.now()
);
// Stops a previously started view with the same unique view identifier, and an object to attach additional attributes to the view
DdRum.stopView('<view-key>', { 'custom.bar': 42 }, Date.now());

Rastreo automático

El rastreo automático de vistas es compatible con los siguientes módulos:

En este proyecto de ejemplo de Datadog, el rastreo de la vista se consigue a través de @datadog/mobile-react-navigation y se configura utilizando el NavigationContainer:

<NavigationContainer
          ref={navigationRef}
          onReady={() => {
            DdRumReactNavigationTracking.startTrackingViews(
              navigationRef.current,
            );
          }}>

Utilización

Inicializar la biblioteca con el contexto de la aplicación

Añade el siguiente fragmento de código a tu archivo de inicialización:

import {
    SdkVerbosity,
    DatadogProvider,
    DatadogProviderConfiguration,
    RumConfiguration,
    LogsConfiguration,
    TraceConfiguration
} from 'expo-datadog';

import { DatadogProviderConfiguration } from '@datadog/mobile-react-native';

const config = new DatadogProviderConfiguration(
    '<CLIENT_TOKEN>', 
    '<ENVIRONMENT_NAME>',
    // Optional: Configure the Datadog Site to target. Default is 'US1'.
    site: 'US1',
    // Optional: Set the reported service name (by default, it uses the package name or bundleIdentifier of your Android or iOS app respectively)
    service: 'com.example.reactnative',
    // Optional: Let the SDK print internal logs above or equal to the provided level. Default is undefined (meaning no logs)
    verbosity: SdkVerbosity.WARN,
    // Enable RUM
    rumConfiguration: {
        // Required: RUM Application ID
        applicationId: '<APPLICATION_ID>',
        // Track user interactions (set to false if using Error Tracking only)
        trackInteractions: true,
        // Track XHR resources (set to false if using Error Tracking only)
        trackResources: true,
        // Track errors
        trackErrors: true,
        // Optional: Sample sessions, for example: 80% of sessions are sent to Datadog. Default is 100%.
        sessionSampleRate: 80,
        // Optional: Enable or disable native crash reports.
        nativeCrashReportEnabled: true,
        // Optional: Sample tracing integrations for network calls between your app and your backend 
        // (in this example, 80% of calls to your instrumented backend are linked from the RUM view to
        // the APM view. Default is 20%).
        // You need to specify the hosts of your backends to enable tracing with these backends
        resourceTraceSampleRate: 80,
        firstPartyHosts: [
            { 
                match: 'example.com', 
                propagatorTypes: [
                    PropagatorType.DATADOG,
                    PropagatorType.TRACECONTEXT
                ]
            }
        ]
    },
    // Enable Logs with default configuration
    logsConfiguration: {},
    // Enable Trace with default configuration
    traceConfiguration: {}
);

// Wrap the content of your App component in a DatadogProvider component, passing it your configuration:
export default function App() {
    return (
        <DatadogProvider configuration={config}>
            <Navigation />
        </DatadogProvider>
    );
}

// Once the Datadog React Native SDK for RUM is initialized, you need to setup view tracking to be able to see data in a dashboard

Ejemplo de tarifas de las sesiones

Para controlar los datos que tu aplicación envía a Datadog RUM, puedes especificar una tasa de muestreo para las sesiones de RUM mientras inicializas el kit de desarrollo de software (SDK) de Expo. Para configurar esta tasa, utiliza el parámetro config.sessionSamplingRate y especifica un porcentaje entre 0 y 100.

Cargar mapas fuente en las compilaciones de EAS

Para activar la notificación de fallos y la simbología de errores, añade expo-datadog a tus complementos en el archivo app.json:

{
    "expo": {
        "plugins": ["expo-datadog"]
    }
}

Este complemento se encarga de cargar los dSYM, los mapas fuente y los archivos de asignación de Proguard en cada compilación de EAS.

Añade @datadog/datadog-ci como dependencia de desarrollo. Este paquete contiene scripts para cargar los mapas fuente. Puedes instalarlo con NPM:

npm install @datadog/datadog-ci --save-dev

o con Yarn:

yarn add -D @datadog/datadog-ci

Ejecuta eas secret:create para configurar DATADOG_API_KEY en tu clave de la API de Datadog y DATADOG_SITE en el host de tu sitio Datadog (por ejemplo, datadoghq.com).

Configura los mapas fuente para una simbología precisa

Opción A: Utilizar el complemento de Datadog Metro (recomendado)

Partiendo de @datadog/mobile-react-native@2.10.0 y @datadog/datadog-ci@v3.13.0, añade el complemento de Datadog Metro a tu metro.config.js:

const { getDatadogExpoConfig } = require("@datadog/mobile-react-native/metro");
const config = getDatadogExpoConfig(__dirname);
module.exports = config;

Opción B: Inyección manual de ID de depuración

Alternativamente, utiliza el comando datadog-ci react-native inject-debug-id para adjuntar manualmente un ID de depuración único a tu paquete de aplicaciones y mapa fuente. Consulta la documentación del comando para obtener instrucciones de uso.

Añadir datos del repositorio git (solo EAS)

Si utilizas EAS para crear tu aplicación Expo, establece cli.requireCommit en true en tu archivo eas.json para añadir los datos del repositorio git a tus archivos de asignación:

{
    "cli": {
        "requireCommit": true
    }
}

Rastrear pantallas de Expo Router

Si utilizas Expo Router, rastrea tus pantallas en tu archivo app/_layout.js:

import { useEffect } from 'react';
import { usePathname, useSearchParams, useSegments, Slot } from 'expo-router';

export default function Layout() {
    const pathname = usePathname();
    const segments = useSegments();
    const viewKey = segments.join('/');

    useEffect(() => {
        DdRum.startView(viewKey, pathname);
    }, [viewKey, pathname]);

    // Export all the children routes in the most basic way.
    return <Slot />;
}

Expo Go

Si estás utilizando Expo Go, cambia a las compilaciones de desarrollo (recomendado) o sigue utilizando Expo Go sin Datadog, mientras lo ejecutas en tu aplicación independiente (no recomendado).

Cambia de Expo Go a las compilaciones de desarrollo

Las compilaciones de desarrollo de tu aplicación son compilaciones de depuración que contienen el paquete expo-dev-client.

  1. Activa el código nativo personalizado para ejecutar con expo run:android y expo run:ios.
  2. Para empezar a utilizar tu aplicación de desarrollo, ejecuta expo install expo-dev-client y expo start --dev-client. Se instala y se inicia el paquete expo-dev-client para ejecutar el código nativo añadido en el modo de desarrollador.

Desarrollar con Expo Go

Cuando tu aplicación se ejecuta dentro de Expo Go, no puedes añadir ningún código nativo personalizado que no forme parte de la aplicación Expo Go. Dado que el kit de desarrollo de software (SDK) de React Native depende de cierto código nativo personalizado para ejecutarse, puedes desarrollar tu aplicación dentro de Expo Go sin Datadog y utilizar Datadog en tus compilaciones independientes.

Tu aplicación se bloquea en Expo Go cuando se llama a algún código nativo (que no está incluido). Para utilizar Datadog con tu aplicación independiente y seguir utilizando Expo Go en el desarrollo, añade el siguiente archivo TypeScript a tu proyecto:

// mockDatadog.ts
// Datadog does not recommend this approach, consider moving to Expo development builds instead.
// This file is not officially maintained and might not be up-to-date with new releases.

import { DdLogs, DdTrace, DdRum, DdSdkReactNative } from 'expo-datadog';

if (__DEV__) {
    const emptyAsyncFunction = () => new Promise<void>(resolve => resolve());

    DdLogs.debug = emptyAsyncFunction;
    DdLogs.info = emptyAsyncFunction;
    DdLogs.warn = emptyAsyncFunction;
    DdLogs.error = emptyAsyncFunction;

    DdTrace.startSpan = () =>
        new Promise<string>(resolve => resolve('fakeSpanId'));
    DdTrace.finishSpan = emptyAsyncFunction;
    DdRum.startView = emptyAsyncFunction;
    DdRum.stopView = emptyAsyncFunction;
    DdRum.startAction = emptyAsyncFunction;
    DdRum.stopAction = emptyAsyncFunction;
    DdRum.addAction = emptyAsyncFunction;
    DdRum.startResource = emptyAsyncFunction;
    DdRum.stopResource = emptyAsyncFunction;
    DdRum.addError = emptyAsyncFunction;
    DdRum.addTiming = emptyAsyncFunction;
    DdRum.getCurrentSessionId = emptyAsyncFunction;

    DdSdkReactNative.initialize = emptyAsyncFunction;
    DdSdkReactNative.setUserInfo = emptyAsyncFunction;
    DdSdkReactNative.addUserExtraInfo = emptyAsyncFunction;
    DdSdkReactNative.clearUserInfo = emptyAsyncFunction;
    DdSdkReactNative.removeUserInfo = emptyAsyncFunction;
    DdSdkReactNative.addAttributes = emptyAsyncFunction;
    DdSdkReactNative.removeAttributes = emptyAsyncFunction;
    DdSdkReactNative.addAttribute = emptyAsyncFunction;
    DdSdkReactNative.removeAttribute = emptyAsyncFunction;
    DdSdkReactNative.setTrackingConsent = emptyAsyncFunction;
}

A continuación, impórtalo antes de inicializar el SDK de React Native de Datadog:

import './mockDatadog';
import { CoreConfiguration } from 'expo-datadog';

const config = new CoreConfiguration(/* your config */);
DdSdkReactNative.initialize(config);

Rastreo de las interacciones de los usuarios

Datadog recomienda configurar el seguimiento de interacciones mediante el complemento Datadog React Native Babel (@datadog/mobile-react-native-babel-plugin). Este complemento enriquece automáticamente los componentes de React con metadatos contextuales, lo que mejora la precisión del seguimiento de interacciones y permite una serie de opciones de configuración.

Instalación

Para instalar con NPM, ejecuta:

npm install @datadog/mobile-react-native-babel-plugin

Para instalar con Yarn, ejecuta:

yarn add @datadog/mobile-react-native-babel-plugin

Configurar Babel

Añade el complemento a tu archivo de configuración de Babel (babel.config.js, .babelrc o similar):

module.exports = {
  presets: ["babel-preset-expo"],
  plugins: ['@datadog/mobile-react-native-babel-plugin']
};

Uso básico

Una vez instalado y configurado, el complemento rastrea automáticamente las interacciones en los componentes estándar de React Native. No se requieren cambios de código adicionales para el uso básico.

Opciones de configuración

Puedes personalizar el comportamiento del complemento para adaptarlo a las necesidades de tu aplicación:

module.exports = {
  presets: ["babel-preset-expo"],
  plugins: [
    [
      '@datadog/mobile-react-native-babel-plugin',
      {
        sessionReplay: {
          // Enable SVG tracking for Session Replay (default: false)
          svgTracking: true
        },
        components: {
          // Use component content as action name (default: true)
          useContent: true,
          // Prefix actions with component name (default: true)
          useNamePrefix: true,
        },
      },
    ],
  ],
};

Seguimiento de componentes personalizados

Para los componentes personalizados, puedes configurar un comportamiento de seguimiento específico:

module.exports = {
  presets: ["babel-preset-expo"],
  plugins: [
    [
      '@datadog/mobile-react-native-babel-plugin',
      {
        components: {
          tracked: [
            {
              name: 'CustomButton',
              // Prop your component uses as content (if available)
              // When not set, the plugin tries to find the most likely match
              contentProp: 'label',
              handlers: [{event: 'onPress', action: 'TAP'}],
            },
            {
              name: 'CustomInput',
              handlers: [{event: 'onFocus', action: 'TAP'}],
            },
          ],
        },
      },
    ],
  ],
};

Nombres de acción personalizados

Puedes especificar nombres de acción personalizados para los componentes utilizando la configuración actionNameAttribute:

module.exports = {
  presets: ["babel-preset-expo"],
  plugins: [
    [
      '@datadog/mobile-react-native-babel-plugin',
      {
        actionNameAttribute: 'data-dd-action-name',
      },
    ],
  ],
};

A continuación, utilízalo en tus componentes:

<Button data-dd-action-name="checkout-button" onPress={handleCheckout}>
  Complete Purchase
</Button>

Envío de datos cuando el dispositivo está desconectado

El SDK de React Native garantiza la disponibilidad de los datos cuando el dispositivo del usuario está desconectado. En casos de zonas con bajo alcance de red o cuando la carga de la batería del dispositivo es demasiado baja, todos los eventos se almacenan primero en el dispositivo local en lotes. Se envían apenas la red vuelve a estar disponible y la carga de la batería es lo suficientemente alta como para garantizar que el SDK de React Native no afecte a la experiencia del usuario final. Si la red no está disponible con tu aplicación ejecutándose en primer plano, o si falla una carga de datos, el lote se guarda hasta que pueda enviarse correctamente.

Esto significa que incluso si los usuarios abren tu aplicación mientras están desconectados, no se pierde ningún dato.

Nota: Los datos del disco se eliminan automáticamente si se vuelven demasiado antiguos, para garantizar que el SDK de React Native no utilice demasiado espacio en disco.

Envío de datos cuando el dispositivo está desconectado

RUM garantiza la disponibilidad de los datos cuando el dispositivo del usuario está desconectado. En el caso de zonas con poca red, o cuando la batería del dispositivo está demasiado baja, todos los eventos se almacenan primero en el dispositivo local por lotes.

Cada lote sigue la especificación de entrada. Se envían tan pronto como la red está disponible y la batería está lo suficientemente cargada como para garantizar que el SDK de Datadog no afecte la experiencia del usuario final. Si la red no está disponible mientras tu aplicación está en primer plano o si falla una carga de datos, el lote se conserva hasta que se lo pueda enviar con éxito.

Esto significa que incluso si los usuarios abren tu aplicación mientras están desconectados, no se pierde ningún dato. Para garantizar que el SDK no utilice demasiado espacio de disco, los datos del disco se descartan automáticamente si son demasiado antiguos.

Solucionar problemas

La aplicación produce muchos recursos de /logs

Cuando el rastreo de recursos está activado y la verbosidad del kit de desarrollo de software (SDK) está configurada en DEBUG, cada recurso activa una llamada de /logs al servidor de desarrollo de Expo para imprimir el log, que a su vez crea un nuevo recurso de RUM y crea así un bucle infinito. Los patrones más comunes de la URL del host del servidor de desarrollo de Expo se filtran con el SDK, por lo tanto, es posible que no te encuentres con este error en la mayoría de las situaciones. Si se produce este error, añade el siguiente asignador de recursos para filtrar las llamadas:

import { CoreConfiguration } from 'expo-datadog';

import Constants from 'expo-constants';

const config = new CoreConfiguration(/* your config */);
config.rumConfiguration.resourceEventMapper = event => {
  if (
    event.resourceContext?.responseURL ===
    `http://${Constants.expoConfig.hostUri}/logs`
  ) {
    return null;
  }
  return event;
};

Referencias adicionales