Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:Collect Spark job logs with SLS

Última atualização: Jun 27, 2026

A execução de jobs do Spark em um cluster do Container Service for Kubernetes (ACK) gera um grande volume de logs distribuídos por diferentes pods, o que dificulta o gerenciamento. O Simple Log Service (SLS) oferece uma solução completa para coleta, processamento, consulta, análise, visualização e alertas de logs. Este tópico explica como usar o Simple Log Service (SLS) para gerenciar com eficiência os logs de jobs do Spark executados em um cluster ACK.

Pré-requisitos

Visão geral

Este tópico orienta você nas etapas necessárias para configurar o SLS e gerenciar os logs de sistema e de aplicação gerados pelos seus jobs do Spark.

  1. Crie uma imagem de contêiner do Spark que inclua a dependência do layout de modelo JSON do log4j e envie a imagem para o seu registro de imagens de contêiner.

  2. Crie um ConfigMap para configurar o Log4j2, definindo o nível de log como INFO e o formato de saída como JSONL.

  3. Crie um recurso AliyunLogConfig. O Simple Log Service criará automaticamente a configuração do Logtail correspondente no Logstore especificado para coletar logs dos jobs do Spark enviados pelo operador Spark.

  4. Crie e execute um job de exemplo do Spark, verifique se os logs do pod estão no formato JSONL e revise as definições dos campos principais.

  5. Faça login no console do Simple Log Service para consultar e analisar os logs do job do Spark dentro de um intervalo de tempo específico.

  6. (Opcional) Limpeza: após concluir os testes, exclua os jobs do Spark e outros recursos criados para evitar custos adicionais.

Etapa 1: Criar uma imagem de contêiner do Spark

Crie o seguinte Dockerfile (este exemplo usa o Spark 3.5.3) e adicione a dependência necessária ao classpath do Spark. Após concluir a compilação, envie a imagem para o seu registro de imagens de contêiner. Para simplificar a coleta e a análise de logs, utilizaremos o formato JSONL para a saída.

ARG SPARK_IMAGE=<SPARK_IMAGE>  # Replace <SPARK_IMAGE> with your Spark base image.
FROM ${SPARK_IMAGE}
# Add dependency for log4j-layout-template-json
ADD --chown=spark:spark --chmod=644 https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-layout-template-json/2.24.1/log4j-layout-template-json-2.24.1.jar ${SPARK_HOME}/jars

Etapa 2: Configurar logs do Log4j2

Crie um arquivo chamado spark-log-conf.yaml com o conteúdo abaixo. Esta configuração define o nível de log como INFO e o formato de saída como JSONL. Ela utiliza o Elastic Common Schema (ECS), um formato de log padronizado, como modelo. Para mais detalhes sobre a configuração, consulte Coletar logs do Log4j.

apiVersion: v1
kind: ConfigMap
metadata:
  name: spark-log-conf
  namespace: default
data:
  log4j2.properties: |
    # Set everything to be logged to the console and file
    rootLogger.level = info
    rootLogger.appenderRefs = console, file
    rootLogger.appenderRef.console.ref = STDOUT
    rootLogger.appenderRef.file.ref = FileAppender
    appender.console.name = STDOUT
    appender.console.type = Console
    appender.console.layout.type = JsonTemplateLayout
    appender.console.layout.eventTemplateUri = classpath:EcsLayout.json
    appender.file.name = FileAppender
    appender.file.type = File
    appender.file.fileName = /opt/spark/logs/spark.log
    appender.file.layout.type = JsonTemplateLayout
    appender.file.layout.eventTemplateUri = classpath:EcsLayout.json

Execute o comando a seguir para criar o recurso ConfigMap.

kubectl apply -f spark-log-conf.yaml

Saída esperada:

configmap/spark-log-conf created

Etapa 3: Criar uma configuração do Logtail

Crie um arquivo de manifesto AliyunLogConfig chamado aliyun-log-config.yaml com o conteúdo a seguir. Substitua <SLS_PROJECT> pelo nome do seu Project do SLS e <SLS_LOGSTORE> pelo nome do seu Logstore. Para mais informações sobre as opções de configuração, consulte Gerenciar configurações do Logtail usando AliyunLogConfig.

apiVersion: log.alibabacloud.com/v1alpha1
kind: AliyunLogConfig
metadata:
  name: spark
  namespace: default
spec:
  # (Optional) The name of the destination Project. Default value: k8s-log-<Your_Cluster_ID>.
  project: <SLS_PROJECT>
  # The name of the Logstore. If the specified Logstore does not exist, Simple Log Service automatically creates it.
  logstore: <SLS_LOGSTORE>
  # The Logtail configuration.
  logtailConfig:
    # The name of the Logtail configuration.
    configName: spark
    # The type of the data source. `file` indicates text logs.
    inputType: file
    # The configurations for log input.
    inputDetail:
      # The directory where the log files are located.
      logPath: /opt/spark/logs
      # The name of the log file. Wildcard characters are supported.
      filePattern: '*.log'
      # The encoding of the log file.
      fileEncoding: utf8
      # The log type.
      logType: json_log
      localStorage: true
      key:
      - content
      logBeginRegex: .*
      logTimezone: ''
      discardNonUtf8: false
      discardUnmatch: true
      preserve: true
      preserveDepth: 0
      regex: (.*)
      outputType: LogService
      topicFormat: none
      adjustTimezone: false
      enableRawLog: false
      # Collect text logs from containers.
      dockerFile: true
      # Advanced configurations.
      advanced:
        # Preview container metadata.
        collect_containers_flag: true
        # Kubernetes collection configuration.
        k8s:
          # Filter pods by label.
          IncludeK8sLabel:
            sparkoperator.k8s.io/launched-by-spark-operator: "true"
          # Filter containers by name.
          K8sContainerRegex: "^spark-kubernetes-(driver|executor)$"
          # Additional log tag configurations.
          ExternalK8sLabelTag:
            spark-app-name: spark-app-name
            spark-version: spark-version
            spark-role: spark-role
            spark-app-selector: spark-app-selector
            sparkoperator.k8s.io/submission-id: sparkoperator.k8s.io/submission-id
      # Log processing plug-ins.
      plugin:
        processors:
        # Log splitting.
        - type: processor_split_log_string
          detail:
            SplitKey: content
            SplitSep: ''
        # JSON field parsing.
        - type: processor_json
          detail:
            ExpandArray: false
            ExpandConnector: ''
            ExpandDepth: 0
            IgnoreFirstConnector: false
            SourceKey: content
            KeepSource: false
            KeepSourceIfParseError: true
            NoKeyError: false
            UseSourceKeyAsPrefix: false
        # Log timestamp extraction.
        - type: processor_strptime
          detail:
            SourceKey: '@timestamp'
            Format: '%Y-%m-%dT%H:%M:%S.%fZ'
            KeepSource: false
            AdjustUTCOffset: true
            UTCOffset: 0
            AlarmIfFail: false

Execute o comando a seguir para criar a configuração do Logtail.

kubectl apply -f aliyun-log-config.yaml

Siga estas etapas para visualizar o novo Logstore e a configuração do Logtail:

  1. Faça login no console do Simple Log Service.

  2. Na seção Projects, clique em no projeto desejado.

    image

  3. Na aba Log Storage > Logstores, clique em no ícone > à frente do Logstore de destino e escolha Data Collection > Logtail Configuration.

    Na página Logtail configuration, uma lista das configurações existentes é exibida. A lista inclui uma configuração chamada spark, associada a um grupo de máquinas.

  4. Clique em na configuração do Logtail desejada para visualizar seus detalhes.

Etapa 4: Enviar um job de exemplo do Spark

Crie um arquivo de manifesto SparkApplication chamado spark-pi.yaml com o seguinte conteúdo.

apiVersion: sparkoperator.k8s.io/v1beta2
kind: SparkApplication
metadata:
  name: spark-pi
  namespace: default
spec:
  type: Scala
  mode: cluster
  image: <SPARK_IMAGE>
  mainClass: org.apache.spark.examples.SparkPi
  mainApplicationFile: local:///opt/spark/examples/jars/spark-examples_2.12-3.5.3.jar
  arguments: 
  - "5000"
  sparkVersion: 3.5.3
  sparkConfigMap: spark-log-conf
  driver:
    cores: 1
    memory: 512m
    serviceAccount: spark-operator-spark
  executor:
    instances: 1
    cores: 1
    memory: 4g

Execute o comando a seguir para enviar o job.

kubectl apply -f spark-pi.yaml

Após a conclusão do job, visualize as últimas 10 linhas do log do pod driver.

kubectl logs  --tail=10 spark-pi-driver  

Saída esperada:

{"@timestamp":"2024-11-20T11:45:48.487Z","ecs.version":"1.2.0","log.level":"WARN","message":"Kubernetes client has been closed.","process.thread.name":"-937428334-pool-19-thread-1","log.logger":"org.apache.spark.scheduler.cluster.k8s.ExecutorPodsWatchSnapshotSource"}
{"@timestamp":"2024-11-20T11:45:48.585Z","ecs.version":"1.2.0","log.level":"INFO","message":"MapOutputTrackerMasterEndpoint stopped!","process.thread.name":"dispatcher-event-loop-7","log.logger":"org.apache.spark.MapOutputTrackerMasterEndpoint"}
{"@timestamp":"2024-11-20T11:45:48.592Z","ecs.version":"1.2.0","log.level":"INFO","message":"MemoryStore cleared","process.thread.name":"main","log.logger":"org.apache.spark.storage.memory.MemoryStore"}
{"@timestamp":"2024-11-20T11:45:48.592Z","ecs.version":"1.2.0","log.level":"INFO","message":"BlockManager stopped","process.thread.name":"main","log.logger":"org.apache.spark.storage.BlockManager"}
{"@timestamp":"2024-11-20T11:45:48.596Z","ecs.version":"1.2.0","log.level":"INFO","message":"BlockManagerMaster stopped","process.thread.name":"main","log.logger":"org.apache.spark.storage.BlockManagerMaster"}
{"@timestamp":"2024-11-20T11:45:48.598Z","ecs.version":"1.2.0","log.level":"INFO","message":"OutputCommitCoordinator stopped!","process.thread.name":"dispatcher-event-loop-1","log.logger":"org.apache.spark.scheduler.OutputCommitCoordinator$OutputCommitCoordinatorEndpoint"}
{"@timestamp":"2024-11-20T11:45:48.602Z","ecs.version":"1.2.0","log.level":"INFO","message":"Successfully stopped SparkContext","process.thread.name":"main","log.logger":"org.apache.spark.SparkContext"}
{"@timestamp":"2024-11-20T11:45:48.604Z","ecs.version":"1.2.0","log.level":"INFO","message":"Shutdown hook called","process.thread.name":"shutdown-hook-0","log.logger":"org.apache.spark.util.ShutdownHookManager"}
{"@timestamp":"2024-11-20T11:45:48.604Z","ecs.version":"1.2.0","log.level":"INFO","message":"Deleting directory /var/data/spark-f783cf2e-44db-452c-83c9-738f9c894ef9/spark-2caa5814-bd32-431c-a9f9-a32208b34fbb","process.thread.name":"shutdown-hook-0","log.logger":"org.apache.spark.util.ShutdownHookManager"}
{"@timestamp":"2024-11-20T11:45:48.606Z","ecs.version":"1.2.0","log.level":"INFO","message":"Deleting directory /tmp/spark-dacdfd95-f166-4b23-9312-af9052730417","process.thread.name":"shutdown-hook-0","log.logger":"org.apache.spark.util.ShutdownHookManager"}

Os logs são impressos no formato JSONL. Os campos são descritos da seguinte forma:

  • @timestamp: momento em que a entrada de log foi gerada.

  • ecs.version: versão do Elastic Common Schema (ECS). O ECS é um esquema padronizado para dados de log.

  • log.level: nível de severidade do log.

  • message: mensagem registrada no log.

  • process.thread.name: nome da thread que originou a entrada de log.

  • log.logger: nome do logger responsável por registrar a entrada.

Etapa 5: Consultar e analisar logs do Spark

Consulte o guia de início rápido para consulta e análise de logs para especificar o intervalo de execução do job e confirmar se a coleta ocorreu com sucesso.

Na página de consulta do console do Simple Log Service, selecione o Logstore spark, defina um intervalo de tempo e execute a consulta. Na aba Raw Logs, é possível visualizar os logs coletados da aplicação Spark. Entradas como o aviso de nível WARN Unable to load native-hadoop library e registros de nível INFO sobre a versão do Spark (3.5.3), sistema operacional e versão do Java durante a fase de inicialização confirmam que a coleta de logs está funcionando corretamente.

(Opcional) Etapa 6: Limpeza

Caso tenha concluído este tutorial e não precise mais dos recursos, execute os comandos abaixo para excluí-los.

Exclua o job do Spark com o seguinte comando:

kubectl delete -f spark-pi.yaml

Remova a configuração do Logtail executando:

kubectl delete -f aliyun-log-config.yaml

Elimine a configuração de log do Log4j2 através do comando:

kubectl delete -f spark-log-conf.yaml