Настройка ведения журнала Apache Spark с помощью Maven и журнала и, наконец, отправка сообщения в Loggly

У меня возникли проблемы с тем, чтобы приложение Spark игнорировало Log4j, чтобы использовать Logback. Одна из причин, по которой я пытаюсь использовать logback, заключается в том, что он поддерживает loggly appender.

У меня есть следующие зависимости и исключения в моем файле pom. (версии находятся в моем диспетчере зависимостей в основной библиотеке pom.)

<dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-core_2.12</artifactId>
        <version>${spark.version}</version>
        <scope>provided</scope>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
            <exclusion>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
            </exclusion>
        </exclusions>            
    </dependency>
    
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>           
    </dependency>
    
    <dependency>
        <groupId>org.logback-extensions</groupId>
        <artifactId>logback-ext-loggly</artifactId>         
    </dependency>
    
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j-over-slf4j</artifactId>           
    </dependency>    

Я сослался на эти две статьи:

Разделение журналов приложений в Logback от журналов Spark в log4j
Настройка ведения журнала Apache Spark с помощью Scala и вернуться

Я пробовал использовать первое использование (при запуске spark-submit):
--conf spark.driver.userClassPathFirst=true
--conf spark.executor.userClassPathFirst=true

но получаю ошибку

    Exception in thread "main" java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.ge
tLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/spark/util/ChildFirstURLClassLoader) of the current cl
ass, org/slf4j/LoggerFactory, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the method's defining class, org/slf4
j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature      

Я хотел бы, чтобы это работало с приведенным выше, но затем я также рассмотрел попытку ниже
--conf spark.driver.extraClassPath=$libs
--conf spark.executor.extraClassPath=$libs

но так как я передаю свой uber jar, чтобы запустить отправку локально И (в кластере Amazon EMR), я действительно не могу указать местоположение файла библиотеки, которое будет локальным для моей машины. Поскольку uber jar содержит файлы, есть ли способ использовать эти файлы? Должен ли я копировать эти библиотеки на мастер-узлы в кластере EMR, когда приложение spark, наконец, запустится оттуда?

Однако первый подход с использованием userClassPathFirst кажется лучшим маршрутом.


person user1161137    schedule 07.10.2020    source источник


Ответы (1)


Итак, я решил проблему, и у меня было несколько проблем.

Таким образом, для того, чтобы заставить Spark разрешить работу журнала, решение, которое сработало для меня, было комбинацией элементов из статей, которые я разместил выше, и, кроме того, проблема с файлом сертификата.

Файл сертификата, который я использовал для передачи в spark-submit, был неполным и переопределял базовые сертификаты хранилища доверенных сертификатов. Это вызывало проблему ОТПРАВКИ сообщений Https в Loggly.

Изменение части 1: обновите maven до оттенка org.slf4j (как указано в ответе @matemaciek)

      </dependencies>
         ...
         <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>                
        </dependency>
                
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.logback-extensions</groupId>
            <artifactId>logback-ext-loggly</artifactId>
            <version>0.1.5</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.30</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <transformers>
                        <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <manifestEntries>
                                <Main-Class>com.TestClass</Main-Class>
                            </manifestEntries>
                        </transformer>
                    </transformers>
                    <relocations>
                        <relocation>
                            <pattern>org.slf4j</pattern>
                            <shadedPattern>com.shaded.slf4j</shadedPattern>
                        </relocation>
                    </relocations>
                </configuration>
            </plugin>
        </plugins>
    </build>

Часть 1а: logback.xml

<configuration debug="true">
    <appender name="logglyAppender" class="ch.qos.logback.ext.loggly.LogglyAppender">
        <endpointUrl>https://logs-01.loggly.com/bulk/TOKEN/tag/TAGS/</endpointUrl>
        <pattern>${hostName} %d{yyyy-MM-dd HH:mm:ss,SSS}{GMT} %p %t %c %M - %m%n</pattern>
    </appender>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>${hostName} %d{yyyy-MM-dd HH:mm:ss,SSS}{GMT} %p %t %c %M - %m%n</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="logglyAppender" />
        <appender-ref ref="STDOUT" />
    </root>
</configuration> 

Изменение части 2: MainClass

import org.slf4j.*;

public class TestClass {

    static final Logger log = LoggerFactory.getLogger(TestClass.class);

    public static void main(String[] args) throws Exception {
        
        log.info("this is a test message");
    }
}

Изменение части 3:
я отправлял искровое приложение как таковое (пример):

sparkspark-submit --deploy-mode client --class com.TestClass --conf "spark.executor.extraJavaOptions=-Djavax.net.ssl.trustStore=c:/src/testproject/rds-truststore.jks -Djavax.net.ssl.trustStorePassword=changeit" --conf "spark.driver.extraJavaOptions=-Djavax.net.ssl.trustStore=c:/src/testproject/rds-truststore.jks -Djavax.net.ssl.trustStorePassword=changeit" com/target/testproject-0.0.1.jar 

Таким образом, вышеуказанная spark-submit не удалась из-за проблемы с сертификацией HTTPS (это было, когда с Loggly связались, чтобы отправить сообщение в службу loggly), потому что rds-truststore.jks перезаписал сертификаты без всех сертификатов. Я изменил это, чтобы использовать хранилище cacerts, и теперь у него были все необходимые сертификаты.

Больше нет ошибок в части Loggly при отправке этого

sparkspark-submit --deploy-mode client --class com.TestClass --conf "spark.executor.extraJavaOptions=-Djavax.net.ssl.trustStore=c:/src/testproject/cacerts -Djavax.net.ssl.trustStorePassword=changeit" --conf "spark.driver.extraJavaOptions=-Djavax.net.ssl.trustStore=c:/src/testproject/cacerts -Djavax.net.ssl.trustStorePassword=changeit" com/target/testproject-0.0.1.jar 
person user1161137    schedule 08.10.2020