[SimplePBI] Como armar un histórico de Fabric Capacity Metrics App

Cada día me llegan más solicitudes de instalar una herramienta de monitoreo para administrar una capacidad dedicada. Allí es cuando aparece la App de Microsoft. Sin embargo, la herramienta, o debería decir el modelo semántico, cuenta con una limitada historia para monitorear. Resulta que el informe resguarda pocos días hacia atrás y algunas instituciones prefieren contar con valores históricos para poder analizar tendencias o dar explicaciones a sucesos pasados y no solamente a lo que ocurre ahora.

En este artículo veremos como podemos extraer datos del modelo semántico de Fabric Capacity Metrics App para construir un histórico utilizando la librería SimplePBI de Python en un jupyter notebook.

Si tenemos nuestros desarrollos desplegados en una capacidad, seguramente estamos utilizando Fabric Capacity Metrics App. Digo "seguro" porque la aplicación del store de Microsoft provee un informe para monitorear el uso de nuestra capacidad (Unidades de procesamiento/capacity CUs). A diferencia del Admin Monitoring que provee un detalle de lo que esta desplegado en la organización y las operaciones o actividades que se ejecutan, la Capacity metrics nos ayuda a entender cuantos recursos de la capacidad esta utilizando un contenido como un modelo semantico, un dataflow gen2, un Fabric notebook o un pipeline de Fabric Data Factory.

Cuando disponemos de una capacidad la administración cambia completamente. Las acciones diarias y los hitos por proyectos o deploys nuevos deben tenerse en cuenta. Si queremos comparar o analizar cambios en deploys mensuales de proyectos complejos, necesitamos almacenar un histórico. Si necesitamos analizar si una tendencia actual que esta relentizando o consumiendo todos los recursos estaba sucediendo en el pasado y no es excepcional, necesitamos histórico. Por esta y muchas otras razones que me comentaron algunos clientes se me ocurrió escribir este artículo.

Prerequisitos

Lo primero que necesitamos será definir nuestro almacenamiento. Si ya utilizamos Fabric es posible usar lakehouse o warehouse con Fabric notebooks, sin embargo tal vez querramos aislar este desarrollo para que no tenga la más mínima influencia en la capacidad. Una vez definido el almacenamiento debemos asegurarnos que podemos usar la Power Bi Rest API. Este artículo puede ayudarlos. Por último, instalar en el entorno donde correremos código Python la librería SimplePBI.

¿Qué vamos a extraer?

El modelo semántico de la Capacity Metrics esta lleno de tablas y contiene parámetros dinámicos. Sin embargo, hoy nos vamos a concentrar en lo más usados.

  • Timepoints: puntos temporales donde ocurre un movimiento de la capacidad.
  • Items: contenido que ha utilizado la capacidad al menos una vez.
  • Background Operations: operaciones de código que incluyen procesamientos o transformaciones.
  • Interactive Operations: refiere a las interacciones de los usuarios explorando y utilizando los informes.

Vamos a iniciar importando librería, recolectando valores de nuestra Aplicacion Registrada en Azure para usar la API. También podemos buscar el id de la capacidad en el portal de administración de Fabric, administrando capacidades.

Para obtener los datos vamos a ejecutar una consulta/query contra el modelo de datos. Veamos por ejemplo una función para traer los Timepoints de un día específico.

Para comenzar debemos mandar un parámetro dinámico de M PowerQuery. Mandamos el id de capacidad y ejecutamos un SUMMARIZECOLUMNS buscando el listado de timepoints y algunas columnas más de operaciones.

A partir de los timepoints podremos buscar las operaciones puesto que se desencadenan para cada timepoint. Entonces hay muchas operaciones por cada timepoint. El primer desafío es que la API nos limita a 1.000.000 de celdas o registros. Calculando cuantas filas podemos traer para la cantidad de columnas que conllevan ese volumen, hablamos de 66.666 filas aproximadamente. Esta información es clave para iterar operaciones de nuestra capacidad.

NOTA: Esto solo será necesario si tenemos mucha cantidad de contenido o usuarios operando.

Comenzaremos ejecutando un COUNT de filas de las operaciones para partir la cantidad de iteraciones cada 66.666 filas.

La consulta para saber las filas y traer los resultados es similar. Ambas pasarán los parámetros dinámicos de M (id de capacidad y timepoint) y buscaran las columnas esperadas, las renombraremos y al final cambiará si buscamos contar las filas o traer los resultados en "ventanas" de 66.666 filas.

Con las funciones que nos den las filas y la ejecución de cada timepoint, vamos a construir la iteración.

En caso que las operaciones lleguen en "None", lo más probable es que sea porque la librería SimplePBI no hay podido traer los resultados por limitación de cantidad de requests ejecutados con la API. Entonces desencaderá una espera de 1 minuto para reanudar. Pueden observar cada paso con sus comentarios para ir comprendiendo el código o construir uno propio. Aqui iteramos dos veces, por un lado una lista timepoints "tp_looper" y por cada una de ella la limitación de filas de la API. Agregamos tres columnas que nos ayuden a reconocer el resultado, el id de capacidad (por si tenemos más de una capacidad), el timepoint (para conocer la fecha con exactitud) y tipo de operación (si es de back o interactiva). Vamos agregando los resultados en un solo pandas dataframe.

Así formamos un frame de operaciones background. Para las operaciones interactive es realmente muy similar, cambian un par de nombre de columnas y tablas.

Finalmente, traemos los items involucrados para constituir una dimensión de ellos. Sería bueno que al integrarlos comparemos el destino para ver de agregar únicamente las filas nuevas.

Así constituimos las 4 tablas que podrán ejecutarse cada día para ir construyendo un histórico.

Pueden repasar el Notebook completo en mi GitHub.

Espero que les sea de utilidad y puedan almacenar las operaciones historicas ordenadas en este modelo estrella sencillo de dimensiones de timepoints e items con hechos de operaciones background e interactivas.