Resumen de alertas de log por servicio y severidad
Requisito
A partir de un flujo de logs de servicio (los datos están en el código),
quédate solo con las líneas WARN y ERROR y
genera un resumen con sangría: los servicios ordenados por número de
alertas, bajo cada servicio la severidad con su recuento y, bajo cada
severidad, los mensajes distintos. La línea de cabecera lleva
los totales generales de ERROR/WARN. Ambas versiones deben imprimir el
resumen que aparece bajo Salida esperada.
Salida esperada
Alert digest — ERROR 4, WARN 5
api (4)
ERROR x2
- timeout calling billing
WARN x2
- slow query 1.2s
- disk 85% full
auth (3)
ERROR x1
- bad signature
WARN x2
- token near expiry
billing (2)
ERROR x1
- invoice 442 failed
WARN x1
- retrying charge
Lado a lado
Dart nativo
FxDart
Por qué difieren
Un resumen con sangría es un árbol aplanado en líneas, y
flatMap es exactamente ese aplanado: el
groupBy + sortBy + flatMap exterior
emite una cabecera más sus hijos por cada servicio, el
flatMap interior hace lo mismo por cada severidad, y
uniq se encarga de los mensajes repetidos allí donde
aparecen. countBy da los totales de la cabecera en una sola
palabra. La versión nativa son tres bucles for anidados que
escriben en una misma lista body compartida, más un mapa de
conteo hecho a mano y un conjunto seen para deduplicar —la
forma de árbol es real en ambas versiones, pero solo una de ellas te deja
leerla en la propia sangría del código.
Benchmark
N = 100
Tiempo Empate
Memoria pico Empate
N = 10,000
Tiempo Empate
Memoria pico Empate
N = 1,000,000
Tiempo Empate
Memoria pico Gana nativo
Las barras son medianas de iteraciones cronometradas repetidas en procesos nuevos por lado (los N pequeños se agrupan por resolución del temporizador). Dos lados a menos del 5% entre sí — o a menos de 0.6 ms, una diferencia que nadie puede percibir — cuentan como empate; las carreras relativas ajustadas se vuelven a medir hasta 5 veces. En una app, cualquier cosa por debajo de unos pocos milisegundos es invisible para el usuario, gane la barra que gane. La memoria es el RSS pico del proceso. La VM de Dart y el dataset son idénticos en ambos lados, así que la diferencia entre las dos barras es lo que retiene el pipeline en sí.