Spark

Junior

Como ler um event log do Spark sem abrir a Spark UI?

A Spark UI é só um renderizador desse arquivo. Sabendo quais tipos de evento realmente importam, você consegue os mesmos números mais rápido - ou pode alimentá-los direto na sua automação.

Ler em:
SparkListenerTaskEnd SparkListenerStageCompleted SparkListenerJobEnd
Quais tipos de evento carregam as métricas que você realmente precisa, aproximadamente nessa ordem - não é um levantamento medido.

Um event log do Spark é um arquivo JSON delimitado por linhas - um objeto de evento por linha, escrito em tempo real enquanto o job roda. A UI que você usa lê exatamente esse mesmo arquivo.

Onde o arquivo mora, e o que tem nele

Configure spark.eventLog.enabled=true e spark.eventLog.dir para algo durável (disco local, S3, HDFS) e o Spark vai escrever uma linha de JSON por evento enquanto a aplicação roda - sem ferramentas extras. Cada linha tem um campo "Event" que nomeia seu tipo: SparkListenerApplicationStart, SparkListenerJobStart, SparkListenerStageSubmitted, SparkListenerTaskEnd, SparkListenerStageCompleted, e mais uma dúzia que quase nenhum job precisa.

# as 10 tarefas mais longas, direto do event log cat app-events.log | jq -r 'select(.Event == "SparkListenerTaskEnd") | [."Task Info"."Task ID", ."Task Metrics"."Executor Run Time"] | @tsv' | sort -k2 -n -r | head -10

Os três tipos de evento que carregam quase tudo que você precisa

SparkListenerTaskEnd é o mais importante: seu objeto "Task Metrics" tem o tempo de execução no executor, memoryBytesSpilled, diskBytesSpilled e os bytes de shuffle read/write - por tarefa, que é a granularidade que realmente mostra o skew (desbalanceamento). SparkListenerStageCompleted dá o resumo em nível de stage sem você precisar reagregar cada tarefa manualmente, e SparkListenerJobEnd diz se tudo realmente terminou com sucesso. Quase qualquer pergunta de diagnóstico - esse job está fazendo spill, uma tarefa está muito mais lenta que as outras, esse stage sequer terminou - dá para responder só com esses três.

Onde isso deixa de funcionar, e por que a UI ainda existe

Dois limites honestos: o event log é escrito depois do fato, então não serve para um job que ainda está rodando (a visão ao vivo da UI lê o estado em memória, não o arquivo). E ele fica grande - um job com 50.000 tarefas produz aproximadamente uma linha JSON por tarefa só para eventos TaskEnd, então carregar o arquivo inteiro com json.load() é a abordagem errada depois de algumas centenas de MB; em vez disso, processe linha por linha.

É literalmente isso que o motor de regras do opti-pipe faz com ele: percorre os eventos de fim de tarefa em streaming em vez de carregar o arquivo inteiro, extrai as métricas numéricas acima, e nunca toca em nada que revelasse seu SQL real ou código de DataFrame - o event log nem carrega isso, só as operações que o próprio planejador de DAG do Spark produziu.

Veja como isso fica no seu próprio pipeline.

Envie um event log real do Spark, um run_results.json do dbt, ou uma exportação de métricas do Flink, e receba recomendações concretas que exigem sua aprovação - não mais uma regra geral.