Scala / JVM noob здесь, который хочет больше узнать о ведении журнала, особенно при использовании Apache Spark.
Я написал библиотеку в Scala, которая зависит от группы библиотек Spark, вот мои зависимости:
import sbt._
object Dependencies {
object Version {
val spark = "2.2.0"
val scalaTest = "3.0.0"
}
val deps = Seq(
"org.apache.spark" %% "spark-core" % Version.spark,
"org.scalatest" %% "scalatest" % Version.scalaTest,
"org.apache.spark" %% "spark-hive" % Version.spark,
"org.apache.spark" %% "spark-sql" % Version.spark,
"com.holdenkarau" %% "spark-testing-base" % "2.2.0_0.8.0" % "test",
"ch.qos.logback" % "logback-core" % "1.2.3",
"ch.qos.logback" % "logback-classic" % "1.2.3",
"com.typesafe.scala-logging" %% "scala-logging" % "3.8.0",
"com.typesafe" % "config" % "1.3.2"
)
val exc = Seq(
ExclusionRule("org.slf4j", "slf4j-log4j12")
)
}
(по общему признанию, я скопировал много этого из другого места).
Я могу упаковать свой код как JAR, используя sbt package
, который я затем могу вызвать из Spark, поместив JAR в ${SPARK_HOME}/jars
. Это отлично работает.
Теперь я хочу реализовать ведение журнала из моего кода, поэтому я делаю это:
import com.typesafe.scalalogging.Logger
/*
* stuff stuff stuff
*/
val logger : Logger = Logger("name")
logger.info("stuff")
однако, когда я пытаюсь вызвать свою библиотеку (что я делаю из Python, я не думаю, что это здесь актуально) Я получаю сообщение об ошибке:
py4j.protocol.Py4JJavaError: произошла ошибка при вызове z: com.company.package.class.function.
E: java .lang.NoClassDefFoundError: com / typesafe / scalalogging / Logger $
Очевидно, это потому, что библиотеки com.typesafe.scala-logging
нет в моем JAR. Я знаю, что могу решить эту проблему, упаковав с помощью sbt assembly
, но я не хочу этого делать, потому что он будет включать все другие зависимости и приведет к тому, что мой JAR будет огромным.
Есть ли способ выборочно включать библиотеки (com.typesafe.scala-logging
в данном случае) в моем JAR? В качестве альтернативы, следует ли мне пытаться войти в систему другим методом, возможно, используя регистратор, который включен в Spark?
Благодаря pasha701 в комментариях я попытался упаковать свои зависимости, используя sbt assembly
, а не sbt package
.
import sbt._
object Dependencies {
object Version {
val spark = "2.2.0"
val scalaTest = "3.0.0"
}
val deps = Seq(
"org.apache.spark" %% "spark-core" % Version.spark % Provided,
"org.scalatest" %% "scalatest" % Version.scalaTest,
"org.apache.spark" %% "spark-hive" % Version.spark % Provided,
"org.apache.spark" %% "spark-sql" % Version.spark % Provided,
"com.holdenkarau" %% "spark-testing-base" % "2.2.0_0.8.0" % "test",
"ch.qos.logback" % "logback-core" % "1.2.3",
"ch.qos.logback" % "logback-classic" % "1.2.3",
"com.typesafe.scala-logging" %% "scala-logging" % "3.8.0",
"com.typesafe" % "config" % "1.3.2"
)
val exc = Seq(
ExclusionRule("org.slf4j", "slf4j-log4j12")
)
}
К сожалению, даже при указании зависимостей искры как Provided
мой JAR изменился с 324 КБ до 12 МБ, поэтому я решил использовать вместо него println()
. Вот мое сообщение о фиксации:
журнал с использованием println
Я выбрал опцию println, потому что она сохраняет размер JAR маленьким.
Я пробовал использовать com.typesafe.scalalogging.Logger, но мои тесты завершились неудачно с ошибкой:
java .lang.NoClassDefFoundError: com / typesafe / scalalogging / Logger
, потому что этого нет в Spark. Я попытался использовать сборку sbt вместо пакета sbt, но это привело к тому, что размер JAR-файла увеличился до go с 324 КБ до 12 МБ, даже если для зависимостей искры установлено значение «Предоставлено». 12M JAR не стоит компромисса только для использования scalaLogging, поэтому вместо этого используется println. . Мы будем очень признательны за любые советы по использованию log4j из Scala при написании библиотеки Spark.