scala maven logging apache-spark jar

scala - Separación de los registros de la aplicación en Logback desde Spark Logs en log4j



maven logging (2)

Tuve el mismo problema: estaba tratando de usar un archivo de configuración de logback. Intenté muchas permutaciones, pero no conseguí que funcionara.

Estaba accediendo a logback a través de grizzled-slf4j usando esta dependencia SBT:

"org.clapper" %% "grizzled-slf4j" % "1.3.0",

Una vez que agregué el archivo de configuración log4j:

src/main/resources/log4j.properties/log4j.properties files.

mi registro funcionó bien.

Tengo un proyecto de Scala Maven usando Spark, y estoy intentando implementar el registro usando Logback. Estoy compilando mi aplicación en un contenedor y desplegándola en una instancia EC2 donde está instalada la distribución Spark. Mi pom.xml incluye dependencias para Spark y Logback de la siguiente manera:

<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_${scala.binary.version}</artifactId> <version>${spark.version}</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency>

Cuando envío mi aplicación Spark, imprimo el enlace slf4j en la línea de comando. Si ejecuto el código de los jars usando java, el enlace es a Logback. Si uso Spark (es decir, spark-submit), sin embargo, el enlace es para log4j.

val logger: Logger = LoggerFactory.getLogger(this.getClass) val sc: SparkContext = new SparkContext() val rdd = sc.textFile("myFile.txt") val slb: StaticLoggerBinder = StaticLoggerBinder.getSingleton System.out.println("Logger Instance: " + slb.getLoggerFactory) System.out.println("Logger Class Type: " + slb.getLoggerFactoryClassStr)

rendimientos

Logger Instance: org.slf4j.impl.Log4jLoggerFactory@a64e035 Logger Class Type: org.slf4j.impl.Log4jLoggerFactory

Entiendo que tanto log4j-1.2.17.jar como slf4j-log4j12-1.7.16.jar están en / usr / local / spark / jars, y que Spark probablemente está haciendo referencia a estos jar a pesar de la exclusión en mi pom.xml, porque si los elimino me dan una ClassNotFoundException en el tiempo de ejecución de spark-submit.

Mi pregunta es: ¿hay alguna manera de implementar el registro nativo en mi aplicación usando Logback mientras se conservan las capacidades de registro interno de Spark? Idealmente, me gustaría escribir mis registros de aplicación de Logback en un archivo y permitir que los registros de Spark sigan mostrándose en STDOUT.


Me encontré con un problema muy similar.

Nuestra compilación fue similar a la suya (pero usamos sbt ) y se describe en detalle aquí: https://.com/a/45479379/1549135

Ejecutar esta solución localmente funciona bien , pero luego spark-submit ignoraría todas las exclusiones y el nuevo marco de registro ( logback ) porque el classpath de spark tiene prioridad sobre el jar desplegado. Y dado que contiene log4j 1.2.xx , simplemente lo cargará e ignorará nuestra configuración.

Solución

He usado varias fuentes. Pero citando Spark 1.6.1 documentos (se aplica a Spark latest / 2.2.0 también):

spark.driver.extraClassPath

Entradas de ruta de clases adicionales para anteponer a la ruta de clase del controlador. Nota: En el modo cliente, esta configuración no se debe establecer a través del SparkConf directamente en su aplicación, porque la JVM del controlador ya ha comenzado en ese punto. En su lugar, establezca esto mediante la opción de línea de comando --driver-class-path o en su archivo de propiedades predeterminado.

spark.executor.extraClassPath

Entradas de classpath adicionales para anteponer a classpath de ejecutores. Esto existe principalmente por compatibilidad con versiones anteriores de Spark. Los usuarios generalmente no deberían necesitar establecer esta opción.

Sin embargo, lo que no está escrito aquí es que extraClassPath tiene prioridad antes de la ruta de clases predeterminada de Spark.

Entonces, la solución debería ser bastante obvia.

1. Descarga esos frascos:

- log4j-over-slf4j-1.7.25.jar - logback-classic-1.2.3.jar - logback-core-1.2.3.jar

2. Ejecute el spark-submit :

libs="/absolute/path/to/libs/*" spark-submit / ... --master yarn / --conf "spark.driver.extraClassPath=$libs" / --conf "spark.executor.extraClassPath=$libs" / ... /my/application/application-fat.jar / param1 param2

Todavía no estoy seguro si puedes poner esos frascos en HDFS. Los tenemos localmente junto al tarro de la aplicación.

userClassPathFirst

Por extraño que parezca, con Spark 1.6.1 también he encontrado esta opción en documentos:

spark.driver.userClassPathFirst , spark.executor.userClassPathFirst

(Experimental) Si se debe dar preferencia a los jars agregados por el usuario sobre los propios jar de Spark al cargar las clases en el controlador. Esta característica se puede usar para mitigar conflictos entre las dependencias de Spark y las dependencias de los usuarios. Actualmente es una característica experimental. Esto se usa solo en modo de clúster.

Simplemente configurando

--conf "spark.driver.userClassPathFirst=true" / --conf "spark.executor.userClassPathFirst=true" /

No funcionó para mí ¡Así que estoy extraClassPath usar extraClassPath !

¡Aclamaciones!

Cargando logback.xml

Si tiene algún problema al cargar logback.xml a Spark, mi pregunta aquí podría logback.xml de ayuda: Pase la propiedad del sistema a la chispa-envíe y lea el archivo de classpath o ruta personalizada