PktMon y ETW: por qué –file-size no limita los .etl en multi‑file y cómo generar archivos pequeños

¿Tu captura con pktmon en modo multi-file ignora --file-size y termina con .etl mucho más grandes que lo esperado? Aquí entenderás por qué ocurre y cómo obtener archivos realmente pequeños sin perder eventos: desde relog posprocesado hasta controlar ETW con logman.

Índice

Resumen del problema

Al ejecutar pktmon con rotación por tamaño, por ejemplo --file-size 5, el comportamiento real no coincide con la expectativa de “cerrar el archivo alrededor de cinco megabytes”. Durante la captura suele verse un archivo actual de cero kilobytes en el directorio, y al detener la sesión aparecen varios .etl cuyo tamaño final ronda el centenar de megabytes. Esto no es un fallo de cálculo, sino la consecuencia directa de cómo Etiquetado de Eventos para Windows (ETW) maneja los buffers, la rotación y el vaciado de datos que recibe PktMon.

Causa técnica en profundidad

La clave está en que PktMon no escribe directamente al archivo como lo haría un logger de texto. En su lugar, publica eventos en ETW y es ETW quien los recibe en memoria y decide cuándo y cómo vaciarlos a disco. El resultado final depende de varios factores predeterminados por PktMon y por ETW:

  • Tamaño de buffer elevado: PktMon utiliza buffers grandes en ETW, típicamente del orden de decenas de megabytes por buffer.
  • Buffering por procesador: al no habilitar la opción de no usar buffering por procesador, ETW mantiene un conjunto de buffers por cada CPU que genere eventos.
  • Sin temporizador de vaciado: al no configurar un FlushTimer distinto de cero, ETW no realiza vaciados periódicos; vacía cuando es necesario por llenado o rotación.
  • Rotación orientativa: en ETW, MaximumFileSize —que PktMon expone como --file-size— indica el umbral de rotación, pero no es un límite duro; los buffers completos se escriben y cierran aunque excedan el umbral.
Parámetro o comportamientoValor o efecto típico en PktMonImpacto en el tamaño final
Tamaño de buffer de ETWDecenas de megabytesEl archivo crece en múltiplos del tamaño de buffer
Buffering por procesadorActivoUn grupo de buffers por CPU que emite eventos
Temporizador de vaciadoSin vaciado periódicoLos buffers permanecen en memoria hasta llenarse o rotar
Umbral de rotaciónMaximumFileSize orientativoSe rotará, pero se vuelcan buffers completos y cabezera

En la práctica, cuando uno de los buffers llega al umbral, ETW fuerza el cierre del archivo y vacía los restantes buffers en ese mismo punto, lo que dispara el tamaño final. De ahí que un objetivo de cinco megabytes termine con fragmentos que rondan magnitudes muy superiores.

Regla práctica para estimar tamaños

Como aproximación sencilla, el tamaño de un fragmento suele ser cercano a:

tamaño de archivo ≈ (número de procesadores que generaron eventos + uno para la cabecera) × tamaño de buffer

Ejemplo ilustrativo con un tamaño de buffer grande:

CPU activas en la sesiónTamaño de bufferTamaño final típico por fragmento
CuatroDieciséis megabytesAlrededor de ochenta megabytes
SeisDieciséis megabytesAlrededor de ciento doce megabytes
OchoDieciséis megabytesAlrededor de ciento cuarenta y cuatro megabytes

Estas cifras varían con la actividad de red, la concurrencia y las características del sistema, pero explican por qué ves .etl de orden centenar en lugar de fragmentos cercanos a tu umbral solicitado.

Por qué el parámetro de tamaño no es un límite duro

El parámetro --file-size establece únicamente el punto de rotación a nivel de ETW. ETW, por diseño, preserva la integridad de sus buffers: cuando decide cerrar un archivo, vuelca el contenido de los buffers completos. No existe un corte “byte a byte” al alcanzar el umbral. Además, con buffering por procesador, la descarga simultánea de varios buffers hace inevitable una sobrecarga respecto del valor objetivo.

Soluciones recomendadas

Si tu objetivo es obtener archivos realmente pequeños —por ejemplo, alrededor de cinco megabytes cada uno— tienes varias estrategias, con diferentes niveles de complejidad y riesgo de pérdida de eventos. A continuación se presentan tres caminos probados.

Opción A — Postproceso con relog de ETW

Consiste en capturar con PktMon de la manera habitual y, al finalizar, dividir los .etl en fragmentos pequeños mediante la interfaz de relog de ETW (ITraceRelogger). Es un enfoque limpio y de bajo riesgo: no interfiere con la captura en tiempo real ni modifica el comportamiento de PktMon.

Ventajas: simplicidad operacional, cero impacto en la captura, repetible en lotes.

Inconvenientes: requiere un paso adicional tras la captura y una herramienta propia o un script que consuma la API.

Esquema mínimo en pseudocódigo con la API de relog:

// Pseudocódigo ilustrativo para dividir un ETL en trozos pequeños
CoCreateInstance(TraceRelogger, &relogger);
relogger->SetCompressionMode(TRUE); // opcional
relogger->AddLogfileTrace(L"PktMon.origen.etl", &inputTrace);
relogger->SetOutputFilename(L"PktMon.part.etl");

// Durante OnEvent, reemitir eventos tal cual
// y controlar el tramo actual según bytes escritos
if (bytesSalida > umbralDeseado) {
relogger->Flush();            // cierra el segmento actual
rotarNombreSalida();          // PktMon.part.N.etl
relogger->SetOutputFilename(nuevoNombre);
}

relogger->ProcessTrace(); 

En PowerShell o C#, puedes invocar la interfaz COM correspondiente. El detalle más importante es contabilizar con precisión los bytes reemitidos para disparar una rotación con márgenes adecuados teniendo en cuenta la cabecera de cada fragmento.

Opción B — Buffers pequeños mediante depurador

Con un depurador de usuario y símbolos, es posible interceptar el momento en que PktMon configura la sesión de ETW y forzar un tamaño de buffer más pequeño. Es una técnica avanzada, útil en laboratorios y para personal con experiencia en depuración de Windows.

Ejemplo práctico con el depurador de consola:

cdb -G -c "bu /1 sechost!StartTraceW \"ed @r8+30 40; g\"; g" ^
    pktmon start --capture --comp nics --pkt-size 0 --file-size 5 --log-mode multi-file --file-name C:\Cap\PktMon.etl

Qué hace esa secuencia:

  • Coloca un punto de interrupción temporal en StartTraceW.
  • Antes de que el sistema cree la traza, modifica el campo de tamaño de buffer (BufferSize, expresado en kilobytes) a un valor reducido. En el ejemplo, se escribe un valor hexadecimal que corresponde a sesenta y cuatro kilobytes.
  • Se continúa la ejecución para que la sesión de ETW quede creada con buffers pequeños.

Advertencias:

  • Reducir el tamaño de buffer aumenta el riesgo de pérdida de eventos en escenarios de alta tasa. Para compensar, eleva los mínimos y máximos de buffers si el controlador de la sesión lo permite.
  • La estructura y los offsets pueden variar según la versión; verifica cuidadosamente con símbolos correctos.
  • Recomendable únicamente para entornos controlados.

Guía de referencia de valores típicos para el campo de tamaño de buffer (kilobytes):

Valor hexadecimalTamaño aproximadoUso sugerido
0x40Sesenta y cuatro kilobytesPruebas ligeras, baja tasa
0x80Ciento veintiocho kilobytesCompromiso entre pérdida y fragmentación
0x100Doscientos cincuenta y seis kilobytesTráfico moderado

Opción C — Captura con control directo de ETW usando logman

Este camino separa la configuración del proveedor de PktMon de la sesión que escribe a disco. Dejas que PktMon inicialice el proveedor y los parámetros de captura (como --pkt-size y filtros), pero delegas la escritura y la rotación de archivos a ETW a través de logman, donde sí puedes fijar buffers pequeños y rotación por archivo nuevo. Es el enfoque recomendado para conseguir fragmentos realmente cercanos al objetivo.

Pasos sugeridos:

:: Arranca PktMon en memoria para cargar proveedor y fijar tamaño de snapshot
pktmon start --capture --comp nics --pkt-size 0 --file-size 1 --log-mode memory

\:: Inicia una sesión ETW con buffers pequeños y rotación por archivo nuevo
logman start pktcap -ets -p Microsoft-Windows-PktMon 0x12 -max 5 -bs 64 -mode newfile -o C:\Cap\PktMon%d.etl

\:: ... deja capturar el tiempo necesario ...

\:: Detén la sesión ETW y cierra PktMon
logman stop pktcap -ets
pktmon stop 

Detalles relevantes de los parámetros de logman:

  • -p Microsoft-Windows-PktMon 0x12: habilita el proveedor y el conjunto de banderas de eventos de PktMon necesarios para tráfico y metadatos. Ajusta la máscara si tu caso de uso requiere menos verbosidad.
  • -bs 64: fija buffers de sesenta y cuatro kilobytes. Puedes elevarlo si observas pérdidas, p. ej., a ciento veintiocho o doscientos cincuenta y seis kilobytes.
  • -max 5: solicita rotación a cinco megabytes por fragmento. ETW puede sobrepasar ligeramente este valor por cabecera y sincronización de buffers, pero el resultado es muy cercano.
  • -mode newfile: en lugar de sobrescribir, crea un archivo nuevo cada vez que se alcanza el umbral, con sufijo incremental en el nombre.
  • -o C:\Cap\PktMon%d.etl: patrón de salida con número basado en fecha u ordinal, cómodo para series largas.

Validación rápida del tamaño:

for %f in (C:\Cap\PktMon*.etl) do @echo %~nxf: %~zf bytes

Integración con conversión a pcapng: una vez tengas fragmentos controlados, puedes convertir cada .etl a .pcapng para analizarlos en herramientas de red estándar:

for %f in (C:\Cap\PktMon*.etl) do @pktmon format "%f" -o "%~dpnf.pcapng"

Buenas prácticas para minimizar volumen y pérdidas

  • Reduce el tamaño de snapshot con --pkt-size si no necesitas el payload completo. Menor tamaño de evento implica menor presión sobre buffers y archivos.
  • Aplica filtros de puertos, direcciones o protocolos con PktMon para disminuir la tasa de eventos procesados.
  • Ajusta el número de buffers en la sesión ETW cuando sea posible, para absorber picos sin pérdidas, especialmente si eliges buffers pequeños.
  • Revisa pérdidas de eventos al finalizar. Las herramientas de ETW y mensajes de PktMon suelen indicar si hubo “events lost”. Si detectas pérdidas, incrementa -bs o reduce la tasa de eventos.
  • Separa el volumen total del tamaño de fragmento: obtener fragmentos pequeños no reduce automáticamente el volumen total; eso depende del filtrado y del snapshot.

Respuestas breves a dudas habituales

¿Por qué veo un archivo vacío durante la captura? Porque ETW mantiene los datos en buffers en memoria. El archivo en disco refleja el estado al último vaciado; con vaciado diferido, aparece como vacío hasta que rotas o detienes la sesión.

¿Es posible forzar un cierre exacto al alcanzar el umbral? No con PktMon puro. ETW no recorta buffers a mitad. El resultado siempre incluirá el vuelco de buffers completos y la cabecera del archivo.

¿Puedo lograr fragmentos pequeños sin herramientas adicionales? Con PktMon solamente, no hay un control fino del tamaño de buffers y del vaciado periódico. Por eso el camino con logman es el más directo y estable.

¿Qué sucede en equipos con muchas CPU? Aun con buffers pequeños, puedes observar un ligero sobre‑tamaño por la descarga concurrente de varios buffers al rotar. Es normal y queda dentro de márgenes razonables si los buffers son modestos.

Procedimiento recomendado listo para usar

  1. Elige el directorio de salida con espacio suficiente.
  2. Inicia PktMon en memoria fijando el tamaño de snapshot y los filtros necesarios.
  3. Arranca la sesión con logman usando buffers pequeños, newfile y el umbral de rotación deseado.
  4. Ejecuta la carga o escenario de captura el tiempo necesario.
  5. Detén la sesión con logman stop y luego cierra PktMon.
  6. Verifica tamaños y comprueba pérdidas. Ajusta -bs o filtros si es necesario.
  7. Convierte a pcapng o divide/archiva según tu flujo de trabajo.

Errores comunes y cómo evitarlos

  • Confiar en el valor del parámetro como límite duro: recuerda que es un umbral de rotación y que ETW siempre escribirá buffers completos.
  • Dejar buffers enormes: si buscas fragmentos pequeños, reduce explícitamente el tamaño de buffer en la sesión que escribe a disco.
  • Ignorar la tasa de eventos: incluso con buffers pequeños, una tasa excesiva puede causar pérdidas. Filtra y ajusta --pkt-size.
  • Olvidar la limpieza: con newfile, puedes crear cientos de fragmentos; automatiza la rotación y el borrado según políticas de retención.

Plantillas de comandos

Plantilla con buffers pequeños y rotación a cinco megabytes

:: Preparación del proveedor en memoria
pktmon start --capture --comp nics --pkt-size 0 --file-size 1 --log-mode memory

\:: Sesión ETW gestionada externamente
logman start pktcap -ets -p Microsoft-Windows-PktMon 0x12 -bs 64 -max 5 -mode newfile -o C:\Cap\PktMon%d.etl

\:: Detener y cerrar
logman stop pktcap -ets
pktmon stop 

Conversión masiva a formato compatible con analizadores de red

for %f in (C:\Cap\PktMon*.etl) do @pktmon format "%f" -o "%~dpnf.pcapng"

Glosario esencial

  • ETW: marco de instrumentación de eventos de Windows que gestiona sesiones de traza, buffers, vaciado y archivos.
  • Buffer: región de memoria donde ETW acumula eventos antes de escribir a disco.
  • Rotación: acción de finalizar un archivo de traza y comenzar otro al alcanzar un umbral o condición.
  • Relog: proceso de reemitir eventos a un nuevo archivo, opcionalmente filtrando, fusionando o dividiendo.
  • Snapshot: longitud de datos por paquete que PktMon captura; cuanto mayor, más bytes por evento.

Conclusión

El parámetro de rotación de PktMon no puede garantizar fragmentos diminutos por sí solo, ya que ETW trabaja con buffers grandes, buffering por procesador y sin temporizador de vaciado. Eso provoca cierres de archivo con sobre‑tamaño respecto del umbral. Para lograr fragmentos realmente pequeños y gestionables, existen dos rutas seguras: dividir después con la API de relog, o —preferiblemente— dejar que logman administre la sesión de ETW con buffers pequeños y rotación por archivo nuevo. Quien necesite un control quirúrgico en laboratorio puede optar por ajustar buffers con un depurador, aceptando el mayor riesgo de pérdidas y la complejidad añadida. Con estos enfoques, podrás equilibrar tamaño de archivo, integridad de la captura y rendimiento de manera predecible.

Índice