Las dos lecciones anteriores te dieron la vista de la infraestructura: cuánta CPU consume el VMSS, cuántos errores 5xx devuelve la web, qué registros ha escrito cada recurso. Eso responde a «¿está sano el sistema?», pero no a «¿qué le pasó al pasajero del localizador XR7742?». Entre ambas preguntas hay un salto: la infraestructura puede estar perfecta y el pasajero seguir sin su tarjeta de embarque.

Application Insights cubre ese hueco. Es la parte de Azure Monitor que observa la aplicación desde dentro: cada petición con su duración y su resultado, cada llamada a la base de datos, cada excepción con su pila, y —lo decisivo— el hilo que une todo eso a través de los seis componentes por los que pasa una reserva. Esta lección te enseña a instrumentarlo, a correlacionarlo, a no arruinarte con el volumen y a extraer de él datos de negocio, no solo técnicos.

Contenido

  1. Qué añade sobre las métricas de infraestructura
  2. El modelo de telemetría
  3. Instrumentación: automática, SDK y recurso basado en área de trabajo
  4. Correlación distribuida: el hilo que une la reserva
  5. Mapa de la aplicación, transacciones y búsqueda en vivo
  6. Rendimiento, dependencias y errores
  7. Muestreo: imprescindible y traicionero
  8. Telemetría personalizada, inicializadores y procesadores
  9. Pruebas de disponibilidad
  10. Detección inteligente y alertas de aplicación
  11. Consultar la telemetría con KQL y controlar el coste
  12. Errores Comunes y Consejos
  13. Ejercicios
  14. Conclusión

  1. Qué añade sobre las métricas de infraestructura

Pregunta La responde
¿Está saturada la máquina? Métricas de plataforma (07-01)
¿Qué escribió el servicio en su registro? Registros de recurso y KQL (07-02)
¿Qué operación de mi API es lenta y por qué? Application Insights
¿Qué dependencia externa está frenando la petición? Application Insights
¿Cuántos pasajeros distintos han sufrido este error? Application Insights
¿Por dónde se rompió el flujo de esta reserva concreta? Application Insights

La diferencia de fondo es el sujeto de la medida. Las métricas de plataforma miden recursos; Application Insights mide operaciones de negocio y usuarios. Por eso puede decir «el 3,2 % de los intentos de compra falla en el paso de emisión de tarjeta, afectando a 148 pasajeros distintos en la última hora», una frase que ninguna métrica de CPU puede formular.

  1. El modelo de telemetría

Todo lo que Application Insights recoge encaja en unos pocos tipos. Conocerlos es imprescindible porque cada uno tiene su tabla en log-contoso-pro, su coste y su papel en la investigación.

Tipo Qué representa Tabla Ejemplo en Contoso
Petición (request) Trabajo que la app hace por encargo de alguien AppRequests POST /api/reservas; ejecución de GenerarTarjetaEmbarque
Dependencia Llamada saliente a otro sistema AppDependencies Consulta a sql-contoso-reservas-pro, escritura en cola-emision-tarjetas
Excepción Error no controlado, con pila de llamadas AppExceptions KeyVaultAccessDeniedException
Traza Mensaje de registro del código AppTraces «Tarifa recalculada para XR7742»
Evento personalizado Un hecho de negocio que tú emites AppEvents ReservaConfirmada, CheckInCompletado
Métrica personalizada Un número agregable que tú emites AppMetrics Importe medio, asientos libres
Vista de página Carga de una página en el navegador AppPageViews Portada de Contoso Reservas
Disponibilidad Resultado de una prueba sintética AppAvailabilityResults Sondeo de /salud

La distinción clave, y la que más se confunde: una petición es trabajo entrante, una dependencia es trabajo saliente. La misma llamada HTTP entre la web y la API aparece dos veces: como dependencia en la web y como petición en la API. Correlacionar ambas es lo que permite ver el recorrido completo.

  1. Instrumentación: automática, SDK y recurso basado en área de trabajo

Hay dos formas de instrumentar, y no son excluyentes:

Automática (sin código) SDK en el código
Cómo se activa Un ajuste en el servicio Paquete NuGet y configuración
Qué recoge Peticiones, dependencias, excepciones, rendimiento Todo lo anterior más lo que tú emitas
Reimplantación No hace falta tocar el código Requiere desplegar
Eventos de negocio No Sí
Dónde encaja en Contoso Punto de partida en todos los servicios app-contoso-reservas-pro y func-contoso-tarjetas-pro

La recomendación práctica es empezar por la automática en todo, y añadir el SDK solo donde necesites telemetría de negocio o control fino.

Antes de nada, el recurso. Contoso usa un recurso basado en área de trabajo, que envía toda la telemetría a log-contoso-pro. Es lo que hizo posible el apartado 7 de la lección anterior: las tablas App* conviven con AzureDiagnostics y AzureActivity, y se pueden cruzar en una consulta. Los recursos clásicos, no basados en área, guardaban los datos aparte y están retirados.

az monitor app-insights component create \
  --app ai-insights-contoso-pro \
  --resource-group rg-contoso-seguridad-pro \
  --location westeurope \
  --workspace "/subscriptions/<id>/resourceGroups/rg-contoso-seguridad-pro/providers/Microsoft.OperationalInsights/workspaces/log-contoso-pro" \
  --application-type web \
  --tags entorno=produccion proyecto=contoso-reservas centro-coste=CC-1042 propietario=marta.rios

# Activación sin código en App Service (extensión del entorno de ejecución)
CONN=$(az monitor app-insights component show --app ai-insights-contoso-pro \
  --resource-group rg-contoso-seguridad-pro --query connectionString -o tsv)

az webapp config appsettings set \
  --name app-contoso-reservas-pro --resource-group rg-contoso-reservas-pro \
  --settings APPLICATIONINSIGHTS_CONNECTION_STRING="$CONN" \
             ApplicationInsightsAgent_EXTENSION_VERSION="~3" \
             XDT_MicrosoftApplicationInsights_Mode="recommended"

Sobre la cadena de conexión: sustituye a la antigua clave de instrumentación y no es opcional, porque además del identificador lleva los puntos de conexión regionales de ingesta. Contiene un identificador, no una credencial de acceso a datos, pero sigue siendo un valor de configuración: en Contoso vive en kv-contoso-pro y llega a la aplicación por referencia de Key Vault, como cualquier otro ajuste (módulo 4).

Los otros dos casos de Contoso:

# Función: mismo ajuste, más el muestreo del anfitrión configurado en host.json
az functionapp config appsettings set \
  --name func-contoso-tarjetas-pro --resource-group rg-contoso-reservas-pro \
  --settings APPLICATIONINSIGHTS_CONNECTION_STRING="$CONN"

# Contenedores: se inyecta como variable de entorno de la aplicación
az containerapp update --name ca-motor-disponibilidad \
  --resource-group rg-contoso-reservas-pro \
  --set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING="$CONN"

En cae-contoso-pro conviene distinguir dos cosas que se solapan: el entorno de Container Apps ya envía registros y métricas del sistema a log-contoso-pro, mientras que Application Insights aporta las peticiones, dependencias y correlación de la aplicación. Se complementan y ambos son necesarios para seguir la reserva de punta a punta.

  1. Correlación distribuida: el hilo que une la reserva

Este es el corazón de la lección y la respuesta al problema que abrió el módulo. Cuando un pasajero compra, intervienen seis componentes. Sin correlación, cada uno genera telemetría aislada y no hay forma de saber qué pertenece a qué compra.

La solución es el contexto de traza del W3C, un estándar que Azure implementa: cada llamada saliente lleva una cabecera traceparent con el formato 00-<trace-id>-<span-id>-<flags>. El receptor la lee, la propaga en sus propias llamadas y etiqueta con ella toda su telemetría. En las tablas de Log Analytics esto aparece como tres columnas:

  • OperationId: identifica la operación completa de negocio. Es el mismo valor en los seis componentes.
  • Id: identifica el tramo concreto, único por componente.
  • ParentId: apunta al tramo que lo provocó, y es lo que construye el árbol.
sequenceDiagram
  participant N as Navegador
  participant W as app-contoso-reservas-pro
  participant A as app-contoso-api-disponibilidad-pro
  participant S as sql-contoso-reservas-pro
  participant Q as cola-emision-tarjetas
  participant F as func-contoso-tarjetas-pro
  N->>W: POST /reservas (traceparent nuevo)
  W->>A: GET /api/disponibilidad (mismo OperationId)
  A->>S: SELECT ... (dependencia)
  W->>Q: Encolar mensaje (traceparent en la propiedad del mensaje)
  Q-->>F: Desencadenador
  F->>F: GenerarTarjetaEmbarque (mismo OperationId)

El paso frágil es el de la cola. HTTP propaga traceparent solo; los mensajes no, salvo que el emisor lo escriba como propiedad del mensaje y el consumidor lo lea. Los SDK modernos de Service Bus lo hacen automáticamente, pero una cola de Azure Storage como cola-emision-tarjetas requiere hacerlo a mano. Si el rastro se corta en la cola, el mapa se parte en dos y vuelves a la situación de partida. Comprobarlo es el primer paso de cualquier implantación:

AppRequests
| where TimeGenerated > ago(1h) and AppRoleName == "func-contoso-tarjetas-pro"
| summarize Total = count(), SinPadre = countif(isempty(ParentId))
| extend PorcentajeHuerfanas = round(100.0 * SinPadre / Total, 1)

Un porcentaje alto de ejecuciones sin ParentId significa exactamente eso: correlación rota en el salto asíncrono.

  1. Mapa de la aplicación, transacciones y búsqueda en vivo

Sobre esa correlación se construyen tres herramientas que se usan a diario:

  • Mapa de la aplicación: un grafo generado automáticamente con todos los componentes, sus llamadas, el volumen, la latencia media y el porcentaje de error de cada arista. Revela tres cosas que nadie había dibujado: dependencias que no sabías que existían, la que realmente está lenta, y componentes que ya nadie llama. En Contoso destapó que la web consultaba cosmos-contoso-tarifas-pro dos veces por reserva por un fallo de caché.
  • Transacciones de extremo a extremo: al pinchar una petición concreta, la línea de tiempo en cascada de todo lo que ocurrió, con la duración de cada tramo. Una petición de 4,2 segundos se descompone en 120 ms de la web, 3,8 s esperando a sql-contoso-reservas-pro y 280 ms de serialización: el culpable queda a la vista sin conjeturas.
  • Búsqueda en vivo (Live Metrics): telemetría con latencia de un segundo y sin muestreo, que además no se almacena y por tanto no se factura como ingesta. Es la herramienta del despliegue: Diego publica en la ranura preproduccion, intercambia, y observa en directo peticiones, errores y dependencias durante los dos minutos críticos. Si algo se dispara, revierte antes de que una alerta llegue a evaluarse.

  1. Rendimiento, dependencias y errores

El panel de rendimiento ordena las operaciones por duración y permite ver la distribución completa, no solo la media. La lectura correcta es siempre por percentiles: si la p50 es de 180 ms y la p95 de 3.400 ms, no tienes un problema de rendimiento general, tienes un problema con un subconjunto de peticiones —normalmente, las de un caso de uso concreto o las que topan con un bloqueo.

El desglose de dependencias es donde suele estar la respuesta. La regla empírica: en aplicaciones de negocio, el 80 % de la latencia está fuera de tu código, en la base de datos o en un servicio externo. El panel de errores complementa con los códigos de respuesta fallidos, las excepciones más frecuentes y las dependencias que fallan.

  1. Muestreo: imprescindible y traicionero

Una aplicación con tráfico real genera un volumen de telemetría que no tiene sentido almacenar íntegro. El muestreo conserva una fracción de los elementos y anota cuántos representa cada uno.

Tipo Dónde ocurre Ajuste Coste que ahorra
Adaptativo En el SDK, antes de enviar Automático, por objetivo de elementos/segundo Ingesta y ancho de banda
Fijo En el SDK, porcentaje constante Tú fijas el porcentaje Ingesta y ancho de banda
De ingesta En el servicio, al recibir Porcentaje en el recurso Solo almacenamiento

Dos propiedades que hay que entender bien. Primera: el muestreo es coherente por operación. Si se conserva una petición, se conservan también sus dependencias, trazas y excepciones; nunca verás una traza huérfana. Segunda, y aquí está la trampa: cada elemento conservado lleva un campo ItemCount con el número de elementos que representa. Las vistas del portal lo aplican solas, pero tus consultas KQL no:

// INCORRECTO con muestreo: infravalora el recuento real
AppRequests | where TimeGenerated > ago(1h) | summarize count()

// CORRECTO: pondera por el factor de muestreo
AppRequests | where TimeGenerated > ago(1h) | summarize Estimado = sum(ItemCount)

Con un muestreo del 20 %, la primera consulta devuelve 2.000 y la realidad son 10.000. Esa discrepancia entre el panel y una consulta propia es una de las confusiones más habituales, y se resuelve con sum(ItemCount). En Contoso, el muestreo adaptativo está activo en la web con un objetivo de cinco elementos por segundo, y desactivado en func-contoso-tarjetas-pro, porque su volumen es bajo y cada ejecución importa individualmente. Las excepciones se excluyen siempre del muestreo.

  1. Telemetría personalizada, inicializadores y procesadores

Aquí es donde Application Insights deja de ser una herramienta técnica y empieza a responder preguntas de negocio. El evento ReservaConfirmada que usaste en KQL sale de aquí:

public class ServicioReservas
{
    private readonly TelemetryClient _telemetria;

    public ServicioReservas(TelemetryClient telemetria) => _telemetria = telemetria;

    public async Task<Reserva> ConfirmarAsync(SolicitudReserva solicitud)
    {
        var reserva = await _repositorio.CrearAsync(solicitud);

        // Evento de negocio: propiedades para filtrar y agrupar, métricas para agregar
        _telemetria.TrackEvent("ReservaConfirmada",
            properties: new Dictionary<string, string>
            {
                ["localizador"] = reserva.Localizador,   // permite SeguirLocalizador() de 07-02
                ["canal"]       = solicitud.Canal,       // web, movil, mostrador
                ["ruta"]        = $"{reserva.Origen}-{reserva.Destino}",
                ["clase"]       = reserva.Clase,
                ["entorno"]     = "produccion"
            },
            metrics: new Dictionary<string, double>
            {
                ["importe"]        = (double)reserva.Importe,
                ["pasajeros"]      = reserva.Pasajeros.Count,
                ["diasAntelacion"] = (reserva.Salida - DateTime.UtcNow).TotalDays
            });

        return reserva;
    }
}

Tres decisiones deliberadas en ese código. Las propiedades son cadenas y sirven para filtrar y agrupar (by canal); las métricas son números y sirven para agregar (avg(importe)). El localizador se incluye porque es la clave de la investigación, y no es un dato personal: identifica una reserva, no a una persona. Y no aparece ni el nombre del pasajero, ni su correo, ni su documento de identidad; eso es intencionado y lo refuerza el siguiente bloque.

Los inicializadores de telemetría añaden contexto a todo lo que se envía; los procesadores filtran o modifican antes del envío:

// Inicializador: enriquece cada elemento con contexto común
public class InicializadorContoso : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        telemetry.Context.Cloud.RoleName = "app-contoso-reservas-pro";
        if (telemetry is ISupportProperties props)
        {
            props.Properties["centroCoste"] = "CC-1042";
            props.Properties["version"]     = Environment.GetEnvironmentVariable("BUILD_ID");
        }
    }
}

// Procesador: descarta ruido y elimina datos personales antes de que salgan del proceso
public class ProcesadorContoso : ITelemetryProcessor
{
    private readonly ITelemetryProcessor _siguiente;
    private static readonly Regex Correo = new(@"[\w\.\-]+@[\w\.\-]+\.\w+", RegexOptions.Compiled);

    public ProcesadorContoso(ITelemetryProcessor siguiente) => _siguiente = siguiente;

    public void Process(ITelemetry item)
    {
        // 1. No almacenar los sondeos de estado: son la mitad del volumen y no aportan nada
        if (item is RequestTelemetry r && r.Url?.AbsolutePath == "/salud") return;

        // 2. Enmascarar correos que se hayan colado en mensajes o consultas
        if (item is TraceTelemetry t)
            t.Message = Correo.Replace(t.Message, "[correo-eliminado]");
        if (item is DependencyTelemetry d && d.Data is not null)
            d.Data = Correo.Replace(d.Data, "[correo-eliminado]");

        _siguiente.Process(item);
    }
}

Este procesador hace dos trabajos distintos y ambos importan. El primero es de coste: descartar los sondeos a /salud, que en Contoso eran el 46 % de las peticiones registradas. El segundo es de cumplimiento, y conviene decirlo sin rodeos: la telemetría de aplicación es un destino habitual de fugas de datos personales, porque una consulta SQL registrada o un mensaje de excepción pueden llevar dentro un correo o un documento de identidad. Bajo el RGPD, eso convierte a log-contoso-pro en un almacén de datos personales, con sus obligaciones de base legal, minimización, plazo de conservación y derecho de supresión —y borrar selectivamente en Log Analytics es lento y limitado—. La regla de Contoso es tajante: los datos personales se eliminan antes de salir del proceso, en el procesador, nunca después. Identificadores de negocio como el localizador, sí; identidades de personas, no.

  1. Pruebas de disponibilidad

Las pruebas de disponibilidad son sondeos sintéticos lanzados desde varias regiones. Alimentan la primera alerta de la tabla de 07-01 y detectan lo que ningún registro puede: que la aplicación está bien pero el DNS, el certificado o el enrutamiento de fd-contoso-global no.

Tipo Qué hace Uso en Contoso
Comprobación de URL estándar Una petición HTTP, con validación de código, contenido y certificado /salud de la API, desde 5 ubicaciones
Personalizada con TrackAvailability Cualquier lógica que tú programes y publiques como resultado Comprobar que se puede emitir una tarjeta de prueba de extremo a extremo

Tres reglas de diseño. Usa al menos cinco ubicaciones y exige que fallen tres antes de alertar: con una sola ubicación, un problema de red local genera falsas alarmas. Comprueba el contenido, no solo el código 200 —una página de error personalizada devuelve 200 perfectamente—. Y valida la caducidad del certificado, que es exactamente el caso que causó el incidente de la tarjeta no emitida.

  1. Detección inteligente y alertas de aplicación

La detección inteligente analiza la telemetría automáticamente y avisa de anomalías sin configurar umbrales: aumento anormal de la tasa de errores, degradación de latencia respecto a la línea base, fugas de memoria, o un patrón de excepciones que empieza justo después de un despliegue. Es útil por lo que descubre sin que nadie lo pidiera, pero no sustituye a las alertas explícitas: no conoce tus SLO ni tu criticidad de negocio. Trátala como una segunda opinión y dirígela al grupo ag-equipo-contoso, no al de guardia.

Las alertas explícitas de aplicación de Contoso, sobre las métricas de Application Insights: latencia p95 de la API por encima de 800 ms, tasa de peticiones fallidas superior al 2 %, tiempo de respuesta de la dependencia sql-contoso-reservas-pro por encima de 1 segundo, y la disponibilidad de /salud. Todas construidas con lo aprendido en 07-01 y apuntando a los grupos de acciones ya definidos.

  1. Consultar la telemetría con KQL y controlar el coste

Como el recurso está basado en área de trabajo, todo lo anterior se consulta con KQL en log-contoso-pro. Un ejemplo que combina lo aprendido:

// Impacto real de negocio de los fallos, por canal de venta
let ventana = 24h;
AppEvents
| where TimeGenerated > ago(ventana) and Name == "ReservaConfirmada"
| extend Canal = tostring(Properties["canal"]),
         Importe = todouble(Measurements["importe"])
| summarize Confirmadas = sum(ItemCount), Ingreso = sum(Importe * ItemCount) by Canal
| join kind=leftouter (
    AppRequests
    | where TimeGenerated > ago(ventana) and Name == "POST /api/reservas" and Success == false
    | extend Canal = tostring(Properties["canal"])
    | summarize Fallidas = sum(ItemCount) by Canal
  ) on Canal
| extend TasaFallo = round(100.0 * Fallidas / (Confirmadas + Fallidas), 2)
| project Canal, Confirmadas, Fallidas, TasaFallo, IngresoEuros = round(Ingreso, 0)
| order by Fallidas desc

Fíjate en el uso sistemático de sum(ItemCount) en lugar de count() por el muestreo, en Measurements para las métricas del evento frente a Properties para las cadenas, y en el join kind=leftouter explícito. El resultado es una tabla que Nuria Peña entiende: cuántas reservas y cuántos euros por canal, y qué porcentaje se está perdiendo.

Sobre el coste, la advertencia de 07-02 se aplica íntegra, porque la telemetría se factura como cualquier otra ingesta en Log Analytics. Las palancas específicas de Application Insights, en orden de impacto: muestreo adaptativo activo en los servicios de alto volumen; filtrado de sondeos de estado y peticiones a recursos estáticos en el procesador; desactivar las trazas de nivel de depuración en producción, que es el error más caro y más frecuente; y retención por tabla, con AppTraces a 30 días y AppEvents a más tiempo por su valor de negocio. Con esas cuatro medidas Contoso redujo el volumen un 60 % sin perder capacidad de investigación.

Errores Comunes y Consejos

  • Contar sin ItemCount. Con muestreo activo, count() infravalora sistemáticamente. Usa sum(ItemCount).
  • Correlación rota en la cola. Si el traceparent no viaja en el mensaje, el rastro se parte. Compruébalo con el porcentaje de peticiones sin ParentId.
  • Registrar datos personales. Correos y documentos acaban en las trazas y en las consultas registradas. Fíltralos en el procesador, antes del envío.
  • Dejar el nivel de depuración en producción. La causa número uno de facturas de telemetría desbocadas.
  • Prueba de disponibilidad desde una sola ubicación. Genera falsas alarmas; usa cinco y exige que fallen tres.
  • Confiar solo en la detección inteligente. No conoce tus SLO; complementa, no sustituye.
  • Consejo: fija Cloud.RoleName en un inicializador. Sin él, el mapa de la aplicación muestra nombres genéricos y deja de ser legible.
  • Consejo: emite eventos de negocio desde el primer día. Instrumentar lo técnico se puede añadir después; reconstruir un histórico de negocio que no se capturó, no.
  • Consejo: usa la búsqueda en vivo en cada despliegue. Es gratuita, no se muestrea y da dos minutos de ventaja sobre cualquier alerta.

Ejercicios

Ejercicio 1. La web muestra en el mapa de la aplicación una latencia media de 2,3 s hacia sql-contoso-reservas-pro, pero el panel de métricas de la base de datos indica un uso de DTU del 35 % y ninguna consulta lenta registrada. Explica las causas posibles y cómo distinguirlas con las herramientas de esta lección.

Ejercicio 2. Diego ha instrumentado func-contoso-tarjetas-pro y ve sus ejecuciones, pero al usar SeguirLocalizador("XR7742") de 07-02 la función no aparece en la línea de tiempo. Diagnostica el problema y describe la solución.

Ejercicio 3. El equipo de Contoso Millas (centro-coste=CC-2077) quiere medir cuántos socios canjean puntos, el importe medio del canje y qué porcentaje abandona a mitad del proceso. Diseña la instrumentación completa, incluyendo la consulta KQL y las precauciones de privacidad y coste.

Soluciones

Solución 1: hay tres causas posibles y se distinguen bien. (a) El tiempo no está en la base de datos sino en llegar a ella: agotamiento del grupo de conexiones, resolución DNS o latencia de red. Se identifica porque en las transacciones de extremo a extremo la dependencia dura mucho pero la consulta ejecutada es trivial, y porque AppDependencies muestra duración alta con Success == true. (b) Bloqueos y esperas: la consulta es rápida pero espera a otra transacción; el uso de DTU es bajo precisamente porque nadie está trabajando, todos esperan. Se confirma con los registros de Deadlocks y Timeouts de la configuración de diagnóstico de SQL (07-01). (c) Una media engañosa: unas pocas consultas muy lentas elevan el promedio del mapa. Se descarta consultando AppDependencies con percentile(DurationMs, 50) y percentile(DurationMs, 95) agrupado por Data: si la p50 es baja y la p95 altísima, el problema afecta a una consulta concreta y no al conjunto. El orden de investigación es siempre ese: primero percentiles, después transacciones de extremo a extremo de un caso lento concreto, y solo entonces mirar la base de datos.

Solución 2: la correlación se ha roto en el salto asíncrono. La web escribe en cola-emision-tarjetas, que es una cola de Azure Storage y no propaga automáticamente el contexto de traza del W3C, a diferencia de HTTP o de Service Bus. La función arranca por tanto una operación nueva, con su propio OperationId, y SeguirLocalizador —que filtra por OperationId == op— no la encuentra. Diagnóstico: la consulta de peticiones sin ParentId del apartado 4 devolverá cerca del 100 % para esa función. Solución: incluir el traceparent como propiedad del mensaje al encolar y, en la función, iniciar la actividad con ese contexto como padre antes de emitir telemetría. Comprobación: tras el cambio, el mapa de la aplicación debe mostrar la arista de la cola hacia la función, y la línea de tiempo de extremo a extremo debe llegar hasta GenerarTarjetaEmbarque. Como red de seguridad mientras tanto, añadir el localizador como propiedad en toda la telemetría de la función permite localizarla por ese campo aunque la correlación falle.

Solución 3: instrumentación con tres eventos personalizados —CanjeIniciado, CanjeConfirmado y CanjeAbandonado—, todos con las propiedades idCanje (un identificador propio, no el número de socio), tipoPremio, paso y entorno, y las métricas puntos e importeEquivalente. El embudo se calcula con AppEvents | where Name startswith "Canje" | summarize Total = sum(ItemCount) by Name, y el abandono como 1 - Confirmados/Iniciados; el importe medio, con summarize avg(todouble(Measurements["importeEquivalente"])) sobre los confirmados, siempre ponderando por ItemCount. Privacidad: no se emite el número de socio, ni su nombre, ni su correo; se usa un identificador de canje sin significado externo, y el procesador de telemetría enmascara cualquier correo que se cuele en trazas o dependencias, según el RGPD y la política de la lección. Coste: muestreo adaptativo desactivado si el volumen de canjes es bajo —conviene conservar cada evento—, pero trazas de depuración desactivadas y sondeos de estado filtrados; retención de AppEvents amplia por su valor de negocio y AppTraces a 30 días. Etiquetas del recurso: entorno, proyecto=contoso-millas, centro-coste=CC-2077 y propietario.

Conclusión

Ya sabes qué añade Application Insights sobre las métricas de infraestructura: cambia el sujeto de la medida, de recursos a operaciones de negocio y usuarios. Conoces su modelo de telemetría —petición, dependencia, excepción, traza, evento personalizado, métrica personalizada, vista de página y disponibilidad—, cada uno con su tabla, y la distinción que más se confunde: petición es trabajo entrante, dependencia es trabajo saliente. Sabes instrumentar sin código y con SDK, y por qué Contoso usa un recurso basado en área de trabajo que envía todo a log-contoso-pro, unificando esta lección con la anterior; lo has activado en app-contoso-reservas-pro, en func-contoso-tarjetas-pro y en los contenedores de cae-contoso-pro, con la cadena de conexión guardada en kv-contoso-pro.

El centro de la lección era la correlación distribuida: el contexto de traza del W3C, OperationId, Id y ParentId, y el punto frágil del salto asíncrono por la cola, que es exactamente donde se partía el rastro de la reserva que abrió el módulo. Sobre esa correlación has visto el mapa de la aplicación, las transacciones de extremo a extremo que descomponen una petición lenta tramo a tramo, y la búsqueda en vivo para vigilar un despliegue en directo y sin coste. Dominas el muestreo —adaptativo, fijo y de ingesta—, por qué es imprescindible y la trampa de ItemCount que hace que tus consultas cuenten de menos. Has emitido telemetría personalizada de negocio en C#, y has escrito un inicializador que enriquece y un procesador que filtra sondeos y elimina datos personales antes de que salgan del proceso, con la advertencia del RGPD que eso conlleva. Y cierras con pruebas de disponibilidad desde varias ubicaciones, detección inteligente como segunda opinión, las alertas de aplicación y el control del coste con las cuatro palancas que redujeron el volumen de Contoso un 60 %.

Con esto, la plataforma de Contoso es por fin observable: una queja se convierte en una consulta, y una consulta en una causa raíz. Pero observar no es operar. Cada mañana alguien enciende los entornos de desarrollo y cada noche alguien debería apagarlos; hay instantáneas viejas que nadie limpia, credenciales que rotar, informes que generar y servidores que parchear, y todo eso sigue consumiendo las horas del equipo de Marta Ríos. La lección 07-04, Azure Automation y runbooks, se ocupa de ese trabajo repetitivo: cuentas de Automation con identidad administrada, runbooks en PowerShell con sus programaciones y sus activos, Hybrid Runbook Worker para actuar sobre la oficina de Barcelona, disparar un runbook desde una alerta de Azure Monitor —cerrando el círculo con 07-01— y Azure Update Manager para el parcheo.

Curso de Azure

Módulo 1: Introducción a Azure

Módulo 2: Servicios principales de Azure

Módulo 3: Bases de datos de Azure

Módulo 4: Seguridad en Azure

Módulo 5: Azure DevOps

Módulo 6: Servicios avanzados de Azure

Módulo 7: Monitoreo y gestión

Módulo 8: Gestión y optimización de costos

Módulo 9: Estudios de caso y mejores prácticas

© Copyright 2026. Todos los derechos reservados