DEV Community

Cover image for [Parte 11] ASP.NET Core: Application Insights y Serilog
Isaac Ojeda
Isaac Ojeda

Posted on

[Parte 11] ASP.NET Core: Application Insights y Serilog

Introducción

Al tener aplicaciones en producción siempre es de suma importancia el poder monitorearlas. Monitorear una Web API tiene sus grandes beneficios y se ha convertido en un MUST al momento de yo manejar aplicaciones en ambientes de producción.

Saber como se comporta tu aplicación, que problemas de rendimiento tiene y hasta saber que errores genera es de vital importancia al operar un sistema. Siempre habrán errores y siempre habrá que arreglarlos. Hagamos que este proceso de debugging sea más sencillo para nosotros.

Como siempre, aquí encontrarás el código que aplica para este post.

Application Insights

Application Insights es una herramienta que forma parte de la suite de Azure Monitor el cual provee de un Application Performance Management y monitoreo para aplicaciones web que están en producción o corriendo en vivo en Azure o en cualquier lado.

Developers o profesionales de DevOps pueden usar Application Insights para:

  • Automáticamente detectar anomalías de performance
  • Ayuda a diagnosticar problemas utilizando las herramientas de analytics
  • Ver el comportamiento de los usuarios al usar la aplicación
  • Ayuda a mejorar continuamente la usabilidad y el performance de la aplicación

Funcionalidades de Application Insights:

  • Soporta una gran variedad de lenguajes de programación, como .NET, node.js, java y python
  • Funciona en aplicaciones hospedadas en servidores on-premises, híbrido o en cualquier nube pública
  • Se puede integrar con procesos de DevOps
  • Se puede conectar con muchas herramientas de desarrollo (Power BI, Alertas, Visual Studio, etc)
  • Puede monitorear y analizar la telemetría de aplicaciones móviles

¿Cómo funciona?

Para usar Application Insights debemos de instalar un pequeño paquete (el SDK) en la aplicación, en visual studio se pude hacer incluso automáticamente, pero lo haremos manualmente más adelante.

Podemos monitorear cualquier servicio web o background service, incluso la parte de frontend con Javascript en una aplicación web. Como mencioné antes, las aplicaciones no están obligadas a estar hosteadas en Azure para que se puedan analizar.

La instrumentación ocurre en distintos Threads y no bloquea cualquier llamada que se hace a la aplicación, por lo que el impacto en la aplicación es pequeño.

El siguiente diagrama muestra un ejemplo de como Application Insights monitorea la aplicación y manda la telemetría a AI.

Image description

¿Qué monitorea?

Application insights ayuda a los equipos de desarrollo a entender el uso y el performance de las aplicaciones, por lo que monitorea:

  • Requests recibidos, tiempos de respuesta y fallas
    • Podríamos saber cuales son los métodos más lentos, más usados y los que más fallan
  • Todas las dependencias (bases de datos, servicios externos, storage accounts, redis, etc)
  • Excepciones
    • Todos los errores que ocurren en la aplicación podemos analizarlos e incluso debuggear el memory dump
  • El frontend: visitas a las páginas, cuanto tardan en cargar y comportamiento de usuarios
    • También llamadas de javascript (requests realizados, tiempo de respuesta y errores)
  • Cantidad de usuarios y sesiones únicas
  • Indicadores de performance, como el CPU, memoria y uso de la red
  • Diagnósticos del host, como docker o azure
  • Trace logs de las apps, podemos hacer tracing de un request y ver como se ejecuto incluso si involucra distintos servicios
  • En general custom events/logs y métricas que sirven para algún tracking que el negocio requiera

Configurando Application Insights en ASP.NET Core

Realmente como mencioné antes, si usamos visual studio, podemos configurar application insights de una forma automática, pero me gusta hacerlo manualmente para entender bien que se configura.

Nota 👀: Este post sigue siendo una continuación de la serie de artículos sobre distintos temas de ASP.NET Core. Si no tienes la solución, no dudes en visitar el repositorio en GitHub por que aquí omitiré mucho código.

Comenzamos instalando los siguientes paquetes:

<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.20.0" />
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="3.1.0" />
Enter fullscreen mode Exit fullscreen mode

Estos dos paquetes son el SDK de Application Insights y un Sink de Serilog. Serilog lo hemos configurado en este post y es bien útil combinarlos con Application Insights.

Para comenzar a recolectar telemetría de nuestra aplicación y empezar a usarla, necesitamos crear un Application Insights en Azure. Es bien sencillo y realmente no pide información que se te pueda dificultar.

Lo importante, es tener los connection strings / instrumentation keys de un application insights previamente creado:

Image description
Y la configuración es extremadamente sencilla, nos vamos a Program.cs y agregamos la siguiente línea:

// ... código omitido
builder.Host.UseSerilog();

// ... código omitido
builder.Services.AddApplicationInsightsTelemetry(); // <------ this one

var app = builder.Build();
// ... código omitido
Enter fullscreen mode Exit fullscreen mode

Y agregamos la cadena de conexión en la configuración (appsettings.json o user secrets)

{
    // Settings omitidos
    "ApplicationInsights": {
    "ConnectionString": "InstrumentationKey=<Instrumentation Key>;IngestionEndpoint=https://eastus-6.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/"
  }
}
Enter fullscreen mode Exit fullscreen mode

Así de fácil, ya podemos empezar a monitorear nuestra aplicación. En este punto se monitorea casi lo más importante pero hay algo que nos falta, los logs y las excepciones.

Si ejecutamos así la aplicación y la empezamos a usar, vamos a poder ver tiempos de respuesta, que solicitudes se hacen, si las solicitudes fallan (mostrando únicamente el HTTP Code) y los indicadores del servidor como el CPU, memoria, etc.

Pero si recuerdan, al implementar CQRS y serilog, incluimos ya logs que nos pueden servir para el diagnostico de la aplicación si algo sale mal (los audit logs, las excepciones y entre otras cosas).

Por lo que, siempre recomendaré, es aprovechar el Sink de Serilog para complementar esta herramienta.

Configurarlo, es igual de fácil. En Program.cs actualizamos:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.ApplicationInsights(app.Services.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces) // <--- this one
    .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();
Enter fullscreen mode Exit fullscreen mode

Anteriormente ya teníamos configurado Serilog, por lo que solamente resta agregar el Sink a Application Insights que incluso ya instalamos al inicio de este post.

Lo que estamos diciendo aquí es, que todos los Logs que son generados por la aplicación, los guarde en Application Insights como del tipo Traces. Ya sean Information, Warning. Los Error / Exceptions serán del tipo Exception en Application Insights. Esto es bien super útil, por que nos permitirá ver traces de esta forma:

Image description
Ya que previamente en nuestra aplicación, hemos configurado que se haga Logs de los errores, esto lo hacemos aquí implementando unos ExceptionFilters.

Si exploramos un request, podemos ver todo bien detallado:

Image description
Esto, es esencial, créanme, necesitan esto en sus aplicaciones en producción

Siempre va a salir algo mal, necesitamos las herramientas para investigar que sucede en nuestra aplicación.

En mi Stack, application insights ha venido para quedarse.

Nota 👀: Existen otras herramientas para hacer esto mismo, pero dado a que yo soy Azure Based, esto me funciona al 100%. Open Telemetry y proyectos como Prometheus o Jeager ayudan bastante en esta misma tarea.

En resumen, con application insights en una Web Api podemos monitorear:

Todas las operaciones realizadas
Image description
Cuanto tardan las dependencias
Image description

Indicadores del servidor
Image description

Métricas en tiempo real
Image description
Este es de los que son más útiles para mi, al intentar reproducir errores, podemos ver los logs en tiempo real.

Gracias a serilog, nos facilita la vida y manda los logs según lo configuremos.

Message Templates

En el post de Serilog, mencioné la importancia de crear Message Templates en los logs y no "concatenar" strings en los logs. La razón de que es mejor usar message templates es por la generación de esta telemetría. Un Message Template se puede visualizar de esta forma:

Image description
El Message es lo que nosotros vemos en consola, pero todos esos Custom Properties nos ayudan incluso a buscar mejor según necesitemos. Aquí podríamos buscar por RequestName, User o algún dato en el Request.

Búsqueda por Custom Properties

El beneficio real de usar los Message Templates y que Serilog los mande como Custom Properties, está al hacer búsqueda en los logs.

Application Insights nos deja hacer Queries con un lenguaje especial de Azure. Saber esto es bien útil, porque podemos automatizar muchas cosas (como generar alertas).

Si consultamos las operaciones realizadas por un usuario, podemos hacerlo:

Image description
Aquí vemos que todo lo que el Message Template incluye, se agrega en el Trace de Application Insights.

Otro ejemplo, si queremos buscar por operación:

Image description
Ya con esto, incluso podríamos tener un sistema auditable (de eso hable en este post utilizando Audit.NET).

Básicamente, lo que Serilog agrega como Custom Properties al mandar los logs a Application Insights son:

{
  "AspNetCoreEnvironment": "Development",
  "RequestId": "0HMH6PLB0IKKE:00000015",
  "RequestPath": "/api/products",
  "ConnectionId": "0HMH6PLB0IKKE",
  "ActionName": "MediatrExample.WebApi.Controllers.ProductsController.CreateProduct (MediatrExample.WebApi)",
  "ActionId": "850584fd-aa63-4f96-a2a3-6fe791b279fe",
  "MessageTemplate": "{RequetsName}: {@User} with request {@Request}",
  "SourceContext": "MediatrExample.ApplicationCore.Common.Behaviours.AuditLogsBehavior",
  "User": "cbb809be-e383-44d0-9435-564017db0602",
  "Request": "{\"Description\":\"string\",\"Price\":0,\"_typeTag\":\"CreateProductCommand\"}",
  "RequetsName": "CreateProductCommand"
}
Enter fullscreen mode Exit fullscreen mode

Más todo lo que incluyamos en el Message Template. En este caso, el message template incluye RequestName, User y Request ( y fíjate que Request, es otro objeto JSON)

Conclusión

Aunque Application Insights no es gratis, no tiene un costo elevado para que no se considere en tu stack.

Uses o no Azure, AI puede usarse y obtener resultados muy similares (si no es que iguales).

Su integración con una aplicación de .NET es muy fácil, pero también lo es con los lenguajes soportados.

Espero te sea de utilidad y le des el uso que yo le doy.

Referencias

Discussion (2)

Collapse
joseduquee profile image
joseduquee

Isaac gracias por todo este gran trabajo!!
Muy útil todo y conciso!

Te quería hacer una pregunta, recomiendas usar el Specification Pattern en proyecto con CQRS y MediaTr? O sería agregarle más complejidad y abstracciones innecesarias?

Un saludo!

Collapse
isaacojeda profile image
Isaac Ojeda Author

¡Gracias!

Sinceramente ese patrón lo encuentro innecesario, ya que estamos usando EF Core como abstracción de la persistencia y los queries.

Reutilizar queries yo suelo hacerlo en alguna especie de Servicio, por lo que prefiero no usarlo ya que como dices, agrega complejidad y tal vez una abstracción innecesaria.

Steve Ardalis en su template de clean architecture sí lo utiliza y tiene varias charlas al respecto en youtube, si quieres verlos te puede orientar más.

Saludos!